小菜学Chromium之OpenGL学习之二

在这个教程里,我们一起来玩第一个OpenGL程序.它将显示一个空的OpenGL窗口,可以在窗口和全屏模式下切换,按ESC退出.它是我们以后应用程序的框架.

在CodeBlock里创建一个新的GLUT Win32程序(不是console控制台程序)后,我们还需要链接OpenGL库文件。

代码的前4行包括了我们使用的每个库文件的头文件。如下所示:

#include <windows.h> // Windows的头文件

#include <glew.h> // 包含最新的gl.h,glu.h库

#include <glut.h> // 包含OpenGL实用库

接下来需要设置使用的所有变量。本节中的例程将创建一个空的OpenGL窗口,因此我们暂时还无需设置大堆的变量。余下需要设置的变量不多,但十分重要。几乎所写的每一个OpenGL程序中都会用到它们。

第一行设置的变量是Rendering Context(着色描述表)。每一个OpenGL都被连接到一个着色描述表上。着色描述表将所有的OpenGL调用命令连接到Device Context(设备描述表)上。我将OpenGL的着色描述表定义为 hRC 。要让程序能够绘制窗口的话,还需要创建一个设备描述表,也就是第二行的内容。Windows的设备描述表被定义为 hDC 。DC将窗口连接到GDI(Graphics Device Interface图形设备接口)。而RC将OpenGL连接到DC。第三行的变量 hWnd 将保存由Windows给我们的窗口指派的句柄。最后,第四行为我们的程序创建了一个Instance(实例)。

HGLRC hRC=NULL;// 窗口着色描述表句柄

HDC hDC=NULL;// OpenGL渲染描述表句柄

HWND hWnd=NULL;// 保存我们的窗口句柄

HINSTANCE hInstance;// 保存程序的实例

bool keys[256];// 保存键盘按键的数组

bool active=TRUE;// 窗口的活动标志,缺省为TRUE

bool fullscreen=TRUE;// 全屏标志缺省,缺省设定成全屏模式

下面的代码的作用是重新设置OpenGL场景的大小,而不管窗口的大小是否已经改变(假定您没有使用全屏模式)。OpenGL场景的尺寸将被设置成它显示时所在窗口的大小。

GLvoid ReSizeGLScene(GLsizei width, GLsizei height){

if (height==0) // 防止被零除

{

height=1;// 将Height设为1

}

glViewport(0, 0, width, height);// 重置当前的视口

glMatrixMode(GL_PROJECTION);// 选择投影矩阵

glLoadIdentity();// 重置投影矩阵

// 设置视口的大小

gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

glMatrixMode(GL_MODELVIEW);// 选择模型观察矩阵

glLoadIdentity();// 重置模型观察矩阵}

接下的代码段中,我们将对OpenGL进行所有的设置。我们将设置清除屏幕所用的颜色,打开深度缓存,启用smooth shading(阴影平滑),等等。

int InitGL(GLvoid)// 此处开始对OpenGL进行所有设置{

glShadeModel(GL_SMOOTH);// 启用阴影平滑

glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 黑色背景

glClearDepth(1.0f); // 设置深度缓存

glEnable(GL_DEPTH_TEST); // 启用深度测试

glDepthFunc(GL_LEQUAL); // 所作深度测试的类型

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 告诉系统对透视进行修正

return TRUE; // 初始化 OK

}

下一段包括了所有的绘图代码。任何所想在屏幕上显示的东东都将在此段代码中出现。

int DrawGLScene(GLvoid)// 从这里开始进行所有的绘制

{ // 清除屏幕和深度缓存

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity(); // 重置当前的模型观察矩阵

return TRUE; // 一切 OK

}

下面是我们的Windows程序的入口。将会调用窗口创建例程,处理窗口消息,并监视人机交互。

int WINAPI WinMain(HINSTANCE hInstance,// 当前窗口实例

HINSTANCE hPrevInstance,// 前一个窗口实例

LPSTR lpCmdLine,// 命令行参数

int nCmdShow) // 窗口显示状态

{

创建OpenGL窗口

if (!CreateGLWindow("OpenGL程序框架",640,480,16,fullscreen))

{

return 0; // 失败退出

}

下面是循环的开始。只要done保持FALSE,循环一直进行。

保持循环直到 done=TRUE

while(!done)

{

我们要做的第一件事是检查是否有消息在等待。使用PeekMessage()可以在不锁住我们的程序的前提下对消息进行检查。许多程序使用GetMessage(),也可以很好的工作。但使用GetMessage(),程序在收到paint消息或其他别的什么窗口消息之前不会做任何事。

//有消息在等待吗?

if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))

{

下面的代码查看是否出现退出消息。如果当前的消息是由PostQuitMessage(0)引起的WM_QUIT,done变量被设为TRUE,程序将退出。

// 收到退出消息?

if (msg.message==WM_QUIT)

{

done=TRUE; // 是,则done=TRUE

}

else

{

// 不是,处理窗口消息

如果不是退出消息,我们翻译消息,然后发送消息,使得WndProc() 或 Windows能够处理他们。

TranslateMessage(&msg); // 翻译消息

DispatchMessage(&msg); // 发送消息

}

}

else // 如果没有消息

{

如果没有消息,绘制我们的OpenGL场景。代码的第一行查看窗口是否激活。如果按下ESC键,done变量被设为TRUE,程序将会退出。

// 绘制场景。监视ESC键和来自DrawGLScene()的退出消息

if (active) // 程序激活的么?

{

if (keys[VK_ESCAPE]) // ESC 按下了么?

{

done=TRUE; // ESC 发出退出信号

}

else // 不是退出的时候,刷新屏幕

{

如果程序是激活的且ESC没有按下,我们绘制场景并交换缓存(使用双缓存可以实现无闪烁的动画)。我们实际上在另一个看不见的"屏幕"上绘图。当我们交换缓存后,我们当前的屏幕被隐藏,现在看到的是刚才看不到的屏幕。这也是我们看不到场景绘制过程的原因。场景只是即时显示。

DrawGLScene(); // 绘制场景

SwapBuffers(hDC); // 交换缓存 (双缓存)

}

}

}

如果done变量不再是FALSE,程序退出。正常销毁OpenGL窗口,将所有的内存释放,退出程序。

// 关闭程序

KillGLWindow(); // 销毁窗口

return (msg.wParam); // 退出程序

}

在这一课中,详细解释了所有的基本步骤。每一步都与设置有关,并创建了一个全屏OpenGL程序。这是框架,几乎每个OpenGL程序都会用到这些步骤。

欢迎大家继续关注更多内容

参考资料:nehe的OpenGL教程http://www.yakergong.net/nehe/

原文发布于微信公众号 - 程序员互动联盟(coder_online)

原文发表时间:2015-04-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

用python爬虫抓站的一些技巧总结

这些脚本有一个共性,都是和web相关的,总要用到获取链接的一些方法,再加上simplecd这 个半爬虫半网站的项目,累积不少爬虫抓站的经验,在此总结一下,那么以...

2675
来自专栏CSDN技术头条

Java 10新特性解密

随着Java开发工具包(JDK)9的发布,大量的注意力都集中在Java的最新特性上,包括引入模块(通过集成项目Jigsaw)。尽管最近的很多关注都集中在这些强大...

3348
来自专栏开源FPGA

SDRAM读写状态解析

(1)在IDLE状态需要先给ACT命令激活某一行,此时处于Row Active状态。

670
来自专栏华章科技

Java 10新特性解密

请注意,本文中所包含的信息在写本文时是准确的。但是到发布时,JDK 10特性组预计将会增加。

542
来自专栏Vamei实验室

安卓第三夜 概念漫游(上)

拿起一个手机,总是满屏的应用图标。点击图标,选择应用,玩一把游戏,刷一下微博,写一篇日记。“叮咚”一声,邮件应用提醒有一封新来的邮件。在安卓里,眼花缭乱的应用承...

1798
来自专栏腾讯Bugly的专栏

全系统栈崩溃是什么鬼?手机管家高级工程师 jaylin,教你如何抓鬼!

Jaylin 腾讯手机管家团队,高级研发工程师,5年以上Android开发经验,擅长终端架构设计、性能和稳定性优化。 前言 Android的严重碎片化,通常会给...

3274
来自专栏何俊林

爱奇艺Android移动客户端app瘦身经验

今天分享是来自兄弟部门移动客户端的瘦身经验。欢迎大家关注爱奇艺技术产品团队公众号,更多来自爱奇艺公司技术分享和总结。 作者|Jully ? 作者介绍 Jully...

2336
来自专栏向治洪

Android App瘦身实战

随着业务的快速迭代增长,不断引入新的业务逻辑代码、图片资源和第三方SDK等,很多app都面临一个一个结果,app越来越大,甚至很多无用的代码,包体积的增大带来了...

2538
来自专栏腾讯Bugly的专栏

Redex 初探与 Interdex:Andorid 冷启动优化

导语 早在去年10月份,facebook就发布了介绍redex的文章,这个据说可以直接对apk做处理,既提高启动性能,又可减少安装包的利器让安卓开发者们都心动不...

3575
来自专栏程序员宝库

Java 10 新特性解密

随着Java开发工具包(JDK)9的发布,大量的注意力都集中在Java的最新特性上,包括引入模块(通过集成项目Jigsaw)。尽管最近的很多关注都集中在这些强大...

3535

扫描关注云+社区