基于OpenGL编写一个简易的2D渲染框架-01 创建窗口
最近正在学习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 创建窗口的更多相关文章
- 基于OpenGL编写一个简易的2D渲染框架-05 渲染文本
阅读文章前需要了解的知识:文本渲染 https://learnopengl-cn.github.io/06%20In%20Practice/02%20Text%20Rendering/ 简要步骤: 获 ...
- 基于OpenGL编写一个简易的2D渲染框架-06 编写一个粒子系统
在这篇文章中,我将详细说明如何编写一个简易的粒子系统. 粒子系统可以模拟许多效果,下图便是这次的粒子系统的显示效果.为了方便演示,就弄成了一个动图. 图中,同时显示了 7 种不同粒子效果,看上去效果挺 ...
- 基于OpenGL编写一个简易的2D渲染框架-04 绘制图片
阅读文章前需要了解的知识,纹理:https://learnopengl-cn.github.io/01%20Getting%20started/06%20Textures/ 过程简述:利用 FreeI ...
- 基于OpenGL编写一个简易的2D渲染框架-03 渲染基本几何图形
阅读文章前需要了解的知识,你好,三角形:https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/ 要 ...
- 基于OpenGL编写一个简易的2D渲染框架-02 搭建OpenGL环境
由于没有使用GLFW库,接下来得费一番功夫. 阅读这篇文章前请看一下这个网页:https://learnopengl-cn.github.io/01%20Getting%20started/02%20 ...
- 基于OpenGL编写一个简易的2D渲染框架-08 重构渲染器-整体架构
事实上,前面编写的渲染器 Renderer 非常简陋,虽然能够进行一些简单的渲染,但是它并不能满足我们的要求. 当渲染粒子系统时,需要开启混合模式,但渲染其他顶点时却不需要开启混合模式.所以同时渲染粒 ...
- 基于OpenGL编写一个简易的2D渲染框架-09 重构渲染器-Shader
Shader 只是进行一些简单的封装,主要功能: 1.编译着色程序 2.绑定 Uniform 数据 3.根据着色程序的顶点属性传递顶点数据到 GPU 着色程序的编译 GLuint Shader::cr ...
- 基于OpenGL编写一个简易的2D渲染框架-11 重构渲染器-Renderer
假如要渲染一个纯色矩形在窗口上,应该怎么做? 先确定顶点的格式,一个顶点应该包含位置信息 vec3 以及颜色信息 vec4,所以顶点的结构体定义可以这样: struct Vertex { Vec3 p ...
- 基于OpenGL编写一个简易的2D渲染框架-10 重构渲染器-Pass
Pass,渲染通路,一个渲染通路指的是一次像素处理和一次顶点处理,也就是指的是一次绘制.简单来说就是顶点数据在渲染管线中走一遍最后绘制. 渲染粒子系统的粒子时,需要开启 OpenGL 的混合模式,并使 ...
随机推荐
- ballerina 学习 三十 扩展开发(一)
ballerina 主要是分为两大类 基于ballerina 语言开发的,一般是客户端的connector 使用java语言开发的(类似的基于jvm的都可以),一般是注解以及进行构件生成 baller ...
- hasura graphql-engine v1.0.0-alpha26 版本新功能试用
hasura graphql-engine v1.0.0-alpha26 已经发布了,有好多新的变动,测试使用docker 环境,同时pg 数据库使用了citus citus 是一个方便扩展的pg ...
- C语言面试题4
第二部分:程序代码评价或者找错 1.下面的代码输出是什么,为什么?void foo(void){ unsigned int a = 6; int b = -20; (a+b > ...
- Windows nginx php cgi-fcgi 配置 xdebug
之前使用的是 Apache + PHP,不用怎么配置就可以. 由于服务器用的是 nginx,为了和服务器一致,所以本地开发也改为 nginx. 开始只是简单的开启 xdebug, 发现并不行. 找了一 ...
- MQ的不足
调用方实时依赖执行结果的业务场景,请使用调用,而不是MQ.MQ是互联网分层架构中的解耦利器,那所有通讯都使用MQ岂不是很好?这是一个严重的误区,调用与被调用的关系,是无法被MQ取代的.比如用户登录场景 ...
- Visual Event :快速查看 DOM 上绑定的 JS 事件
http://web.jobbole.com/82503/ Javascript中的事件经常被认为如谜一般不可解.Javascript是一个事件驱动的语言,在这样的前提下前面的看法是很奇怪,但是说到它 ...
- 栈的一个实例——Dijkstra的双栈算术表达式求值法
Dijkstra的双栈算术表达式求值法,即是计算算术表达式的值,如表达式(1 + ( (2+3) * (4*5) ) ). 该方法是 使用两个栈分别存储算术表达式的运算符与操作数 忽略左括号 遇到右括 ...
- Microsoft Dynamics CRM 2013 相关安装包下载
90-day trial keys:Microsoft Dynamics CRM Workgroup Server 2013 (5 CAL limit):NX77Y-BTBCV-JP3T3-8W7JH ...
- github 改位置
在设置里改位置后,先在本地库上右键"stop track this repo". 然后在在线库重新CLONE.
- utmp
How to monitor user login history on CentOS with utmpdump Last updated on September 22, 2014 Authore ...