OpenGL图形学之窗口创建

2021-04-16 10:10发布

图形学就是研究如何在计算机中表示图形、以及利用计算机进行图形的计算、处理和显示的相关原理与算法。是游戏引擎如UnityUE4渲染模块的底层技术。可以这么说,我们熟悉的所有平台所有类型的游戏中炫酷的画面都是使用图形学渲染出来的。因此图形学是基础建设,游戏引擎是框架结构,而游戏本身就是高质量的成品。

使用OpenGL制作的游戏

那么今天就带领大家一起学习如何创建一个基于OpenGL图形学技术的基本游戏窗口,如下图所示:

准备工作

在正式编程前我们需要一些准备工作下载两个OpenGL工具库:

1.freeGLUT

这是一个OpenGL的窗口工具库,可以辅助我们创建OpenGL窗口,还集成了很多其他好用的和OpenGL程序框架相关的功能,下载地址为:

http://nchc.dl.sourceforge.net/project/freeglut/freeglut/2.8.0/freeglut-2.8.0.tar.gz

2.GLEW

这是一个跨平台的C++扩展库,基于OpenGL图形接口。GLEW能自动识别你的平台所支持的全部OpenGL高级扩展涵数,下载地址为:

http://glew.sourceforge.net/

 

创建一个C++空工程

双击打开VS2017,选择文件->新建,选择C++模板,选择空项目,在下面填好工程名称和保存路径后点击右下角确定按钮创建一个新的空C++工程。

 

添加一个C++源文件

在源文件上右键->新建,在弹出的对话框中选择C++文件并在下面修改名称为Main.cpp(.cpp.ccC++源代码文件的后缀),点击添加。

编写一个基本C++程序

接下来我们在代码区首先编写一个C++基本程序以用来生成我们的.sln工程结构。

双击打开Main.cpp,键入如下代码后按Ctrl+F5编译并运行:

编译运行基本C++程序结构

我们会看到一个程序运行的C++控制台程序窗口并打印“C++程序”字样,恭喜大家,我们第1步顺利完成了,接下来我们在此基础上将其改造成一个OpenGL窗口。

在工程文件目录加入两个工具库

在工程目录下创建Includes并放入如下头文件:

 

在工程目录下创建Libs并放入如下静态库文件:

在与工程文件.sln同一级的Debug目录下放入如下动态库文件:

VS工程属性界面配置两个工具库

接下来我们回到VS,在工程上右键->属性,在弹出的面板中选择VC++目录,然后我们点开包含目录,加入刚才创建的Includes目录位置:

然后我们继续点开库目录,加入刚才创建的Libs目录位置:

然后我们选择链接器->输入,在附加依赖项选项中加入如下静态库的链接:

改写Main.cpp

OK,至此所有OpenGL程序的编码前准备配置工作都已经完成,接下来我们正式对Main.cpp中的主函数进行改造,给其加入OpenGL窗口功能。

首先我们引入需要使用到的头文件并链接库:

#include <glew.h>//引入glew

#include <freeglut.h>//引入freeglut

#include <iostream>//引入C++标准输入输出流文件

using namespace std; //使用标准命名空间

引入他们的目的是接下来我们会使用到这些.h头文件中所包含的库函数或工具。

我们现在不太想要这个控制台窗口,因此我们使用#pragma命令取消这个窗口:

#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")//取消控制台工程的控制台窗口

接下来我们还需要定义一下窗口的大小,注意这里是以像素(pixel)为单位:

GLint WIN_WIDTH = 1000;//窗口宽

GLint WIN_HEIGHT = 625;//窗口高

大家都知道游戏的流程是一个循环,而在这个循环中为了渲染游戏画面,我们需要使用一个渲染函数来负责游戏中画面的渲染工作,我们来定义一下这个函数:

static void RenderSceneCB() 

{

glClear(GL_COLOR_BUFFER_BIT);// 清空颜色缓存

glutSwapBuffers();// 交换前后缓存

}

在这个函数中我们首先使用glClear来在每一帧开始前清除上一帧的内容,紧接着使用glutSwapBuffers交换前台缓冲区和后台缓冲区。

接下来我们重写主函数main,首先对glut的环境进行初始化:

glutInit(&argc, argv);// 初始化GLUT

这个函数可以直接对glut库进行初始化的参数设置,我们要想在接下来的程序中使用glut就必须做这一步。

紧接着我们配置一些GLUT的选项设置:

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);

其中GLUT_DOUBLE表明开启双缓冲机制,而GLUT_RGBA为使用颜色缓冲。

当然我们还要获取当前屏幕的分辨率大小以用来设置窗口的大小和位置:

//获取客户区屏幕大小

GLint ScreenWidth = glutGet(GLUT_SCREEN_WIDTH);

GLint ScreenHeight = glutGet(GLUT_SCREEN_HEIGHT);

// 窗口设置

glutInitWindowSize(WIN_WIDTH, WIN_HEIGHT);      // 窗口尺寸

glutInitWindowPosition((ScreenWidth - WIN_WIDTH) / 2, (ScreenHeight - WIN_HEIGHT) / 2 - 50);  // 窗口位置

glutCreateWindow("1OpenGL窗口");   // 窗口标题

还记得刚才写的渲染回调函数吗?我们现在就来指定它:

glutDisplayFunc(RenderSceneCB);//指定OpenGL程序的渲染函数

来指定一下擦除屏幕所用的颜色值吧,这个颜色值会当窗口什么都不绘制时填满整个窗口:

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);// 缓存清空后的颜色值

接下来初始化另外一个库,就是glew:

GLenum res = glewInit();

if (res != GLEW_OK) {

fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));

return 1;

}

最后一步!!!!!!

我们通知这个C++窗口程序可以开始OpenGL主循环了:

glutMainLoop();// 通知开始GLUT的内部循环

这个函数调用传递指令给GLUT现在开始它的内部循环。在这个循环中它监听窗口系统中的事件并通过我们配置的回调传递出去。在我们这个例子中,GLUT将只会调用我们注册的那个display回调(RenderScenceCB),在这个回调函数中(RenderScenceCB)我们可以自定义代码来渲染这一帧的图像。

好了,一切都告一段落了,我们现在可以按下Ctrl+F5键来运行我们的第1OpenGL窗口程序了。