最近正在学习OpenGL,我认为学习的最快方法就是做一个小项目了。

如果对OpenGL感兴趣的话,这里推荐一个很好的学习网站 https://learnopengl-cn.github.io/

我用的是 vs2013,使用C++语言编写项目。这个小项目叫Simple2D,意味着简易的2D框架。最终的目的是可以渲染几何图形和图片,最后尝试加上一个2D粒子系统和Box2D物理引擎,并编译一个简单的游戏。

第一步,就是创建一个Win32项目。

接下来,生成一个窗口。编写一个RenderWindow类,用于创建窗口。头文件很简单

 #pragma once
#include "Common.h"
#include <Windows.h>
#include <string> namespace Simple2D
{
class DLL_export RenderWindow
{
public:
RenderWindow(int width, int height, const char* title = "Simple2D");
~RenderWindow(); void createWindow(int width, int height, const char* title);
void setClientSize(int width, int height); static LRESULT WINAPI static_window_proc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam); private:
HWND hwnd;
};
}

下面是它的实现

 #include "RenderWindow.h"
#include <exception> #define CLASS_NAME "Simple2DApplication" namespace Simple2D
{
RenderWindow::RenderWindow(int width, int height, const char* title)
{
this->createWindow(width, height, title);
} RenderWindow::~RenderWindow()
{ } void RenderWindow::createWindow(int width, int height, const char* title)
{
WNDCLASS wndclass;
memset(&wndclass, , sizeof(wndclass)); wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wndclass.lpfnWndProc = (WNDPROC)RenderWindow::static_window_proc;
wndclass.cbClsExtra = ;
wndclass.cbWndExtra = ;
wndclass.hInstance = ( HINSTANCE ) GetModuleHandle();
wndclass.hIcon = ;
wndclass.hCursor = ;
wndclass.hbrBackground = CreateSolidBrush(RGB(, , ));
wndclass.lpszMenuName = ;
wndclass.lpszClassName = TEXT(CLASS_NAME);
RegisterClass(&wndclass); /* 创建窗口 */
CreateWindowA(CLASS_NAME, title, WS_OVERLAPPEDWINDOW, , , width, height,
NULL, NULL, ( HINSTANCE ) GetModuleHandle(), this); if ( hwnd == NULL ) throw std::exception("Unable to create window"); /* 显示窗口 */
ShowWindow(hwnd, SW_SHOWNA);
setClientSize(width, height);
} void RenderWindow::setClientSize(int width, int height)
{
/* 设置客户区大小为 width, height */
RECT rectProgram, rectClient;
GetWindowRect(hwnd, &rectProgram);
GetClientRect(hwnd, &rectClient); int borderw = rectProgram.right - rectProgram.left - (rectClient.right - rectClient.left);
int borderh = rectProgram.bottom - rectProgram.top - (rectClient.bottom - rectClient.top); borderw += width;
borderh += height; int showToScreenX = GetSystemMetrics(SM_CXSCREEN) / - borderw / ;
int showToScreenY = GetSystemMetrics(SM_CYSCREEN) / - borderh / ; MoveWindow(hwnd, showToScreenX, showToScreenY, borderw, borderh, false);
} LRESULT WINAPI RenderWindow::static_window_proc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
RenderWindow* self = nullptr;
if ( msg == WM_CREATE ) {
LPCREATESTRUCT create_struct = ( LPCREATESTRUCT ) lParam;
self = ( RenderWindow* ) create_struct->lpCreateParams;
SetWindowLongPtr(wnd, GWLP_USERDATA, ( LONG_PTR ) self);
self->hwnd = wnd;
}
else {
self = ( RenderWindow* ) GetWindowLongPtr(wnd, GWLP_USERDATA);
} switch ( msg ) {
case WM_CLOSE:
PostQuitMessage();
break;
case WM_DESTROY:
PostQuitMessage();
break;
case WM_PAINT:
RECT rect;
if ( GetUpdateRect(wnd, &rect, FALSE) ) {
ValidateRect(wnd, &rect);
}
break;
}
return DefWindowProc(wnd, msg, wParam, lParam);
}
}

主要是注册窗口类,创建窗口和显示窗口。有一点需要注意的是,我这里的窗口大小并不是真正的窗口大小,而是客户区的大小,在 函数 setClientSize 中可以看出,我重新计算了窗口的真正大小。

最后是主函数

#pragma once
#include <Windows.h>
#include "RenderWindow.h" using namespace Simple2D; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
RenderWindow window(DEFAULT_WIN_W, DEFAULT_WIN_H); MSG msg = { };
while ( msg.message != WM_QUIT ) {
if ( PeekMessage(&msg, , , , PM_REMOVE) ) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
// TODO:
}
} return ;
}

只是创建了对象 RenderWindow,和消息循环。

运行后,得到下面的结果

按照我推荐的那个教程,你也可以使用 GLFW 库来创建一个窗口,这种方法更简单。有兴趣的可以尝试一下。

这里是源码地址:http://files.cnblogs.com/files/ForEmail5/Simple2D-01.rar

基于OpenGL编写一个简易的2D渲染框架-01 创建窗口的更多相关文章

  1. 基于OpenGL编写一个简易的2D渲染框架-05 渲染文本

    阅读文章前需要了解的知识:文本渲染 https://learnopengl-cn.github.io/06%20In%20Practice/02%20Text%20Rendering/ 简要步骤: 获 ...

  2. 基于OpenGL编写一个简易的2D渲染框架-06 编写一个粒子系统

    在这篇文章中,我将详细说明如何编写一个简易的粒子系统. 粒子系统可以模拟许多效果,下图便是这次的粒子系统的显示效果.为了方便演示,就弄成了一个动图. 图中,同时显示了 7 种不同粒子效果,看上去效果挺 ...

  3. 基于OpenGL编写一个简易的2D渲染框架-04 绘制图片

    阅读文章前需要了解的知识,纹理:https://learnopengl-cn.github.io/01%20Getting%20started/06%20Textures/ 过程简述:利用 FreeI ...

  4. 基于OpenGL编写一个简易的2D渲染框架-03 渲染基本几何图形

    阅读文章前需要了解的知识,你好,三角形:https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/ 要 ...

  5. 基于OpenGL编写一个简易的2D渲染框架-02 搭建OpenGL环境

    由于没有使用GLFW库,接下来得费一番功夫. 阅读这篇文章前请看一下这个网页:https://learnopengl-cn.github.io/01%20Getting%20started/02%20 ...

  6. 基于OpenGL编写一个简易的2D渲染框架-08 重构渲染器-整体架构

    事实上,前面编写的渲染器 Renderer 非常简陋,虽然能够进行一些简单的渲染,但是它并不能满足我们的要求. 当渲染粒子系统时,需要开启混合模式,但渲染其他顶点时却不需要开启混合模式.所以同时渲染粒 ...

  7. 基于OpenGL编写一个简易的2D渲染框架-09 重构渲染器-Shader

    Shader 只是进行一些简单的封装,主要功能: 1.编译着色程序 2.绑定 Uniform 数据 3.根据着色程序的顶点属性传递顶点数据到 GPU 着色程序的编译 GLuint Shader::cr ...

  8. 基于OpenGL编写一个简易的2D渲染框架-11 重构渲染器-Renderer

    假如要渲染一个纯色矩形在窗口上,应该怎么做? 先确定顶点的格式,一个顶点应该包含位置信息 vec3 以及颜色信息 vec4,所以顶点的结构体定义可以这样: struct Vertex { Vec3 p ...

  9. 基于OpenGL编写一个简易的2D渲染框架-10 重构渲染器-Pass

    Pass,渲染通路,一个渲染通路指的是一次像素处理和一次顶点处理,也就是指的是一次绘制.简单来说就是顶点数据在渲染管线中走一遍最后绘制. 渲染粒子系统的粒子时,需要开启 OpenGL 的混合模式,并使 ...

随机推荐

  1. PipelineDB 1.0.0 发布——使用标准的pg 扩展开发模型

    PipelineDB 1.0.0 发布已经发布了,现在的已经成为一个标准的pg 扩展了,语法也有变动 create continous view 修改为了view,create streaem 修改为 ...

  2. WebService的web客户端同步、异步、多线程向服务端传入参数的数据交互方式

    接着上一章的内容,在上一章中我们知道了如何.net平台下去建立一个WebService,以及同步调用.异步调用.开线程异步调用三种客户端从服务端获取数据的方式,在本章了所要讲的,是如何将客户端的数据, ...

  3. MongoDB初试备份及恢复

    MongoDB作为文档数据库,有 1.登录MongoDB官网,地址:https://www.mongodb.com/download-center#community  , 根据自己操作系统下载相应版 ...

  4. 【转】每天一个linux命令(45):free 命令

    原文网址:http://www.cnblogs.com/peida/archive/2012/12/25/2831814.html free命令可以显示Linux系统中空闲的.已用的物理内存及swap ...

  5. 谈windows中的句柄

    谈windows中的句柄   每当一个进程打开一个对象,系统就返回一个句柄作为凭证,由此可以想到,句柄是依赖于具体的进程的,换句话说,句柄一定属于某个进程,以后在访问这个对象时就要使用这个凭证!   ...

  6. HttpClient连接池

    HttpClient连接池,发现对于高并发的请求,效率提升很大.虽然知道是因为建立了长连接,导致请求效率提升,但是对于内部的原理还是不太清楚.后来在网上看到了HTTP协议的发展史,里面提到了一个属性C ...

  7. fiddler工具能干啥

    1.通过模拟弱网进行测试(试了木有效果) http://www.cnblogs.com/LanTianYou/p/7095174.html (试了貌似没反应) http://caibaojian.co ...

  8. HSSF NPOI 颜色

    using System; using System.IO; using System.Windows.Forms; using NPOI.HSSF.UserModel; using NPOI.SS. ...

  9. Callable接口和Future

    本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果.        Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结 ...

  10. 第15章 高并发服务器编程(1)_非阻塞I/O模型

    1. 高性能I/O (1)通常,recv函数没有数据可用时会阻塞等待.同样,当socket发送缓冲区没有足够多空间来发送消息时,函数send会阻塞. (2)当socket在非阻塞模式下,这些函数不会阻 ...