第01课 OpenGL窗口(2)
下一段包括了所有的绘图代码。任何您所想在屏幕上显示的东东都将在此段代码中出现。以后的每个教程中我都会在例程的此处增加新的代码。如果您对OpenGL已经有所了解的话,您可以在 glLoadIdentity()调用之后,返回TRUE值之前,试着添加一些OpenGL代码来创建基本的形。如果您是OpenGL新手,等着我的下个教程。目前我们所作的全部就是将屏幕清除成我们前面所决定的颜色,清除深度缓存并且重置场景。我们仍没有绘制任何东东。
返回TRUE值告知我们的程序没有出现问题。如果您希望程序因为某些原因而中止运行,在返回TRUE值之前增加返回FALSE的代码告知我们的程序绘图代码出错。程序即将退出。
int DrawGLScene(GLvoid) // 从这里开始进行所有的绘制
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存 glLoadIdentity(); // 重置当前的模型观察矩阵 return TRUE; // 一切 OK
}
下一段代码只在程序退出之前调用。KillGLWindow() 的作用是依次释放着色描述表,设备描述表和窗口句柄。我已经加入了许多错误检查。如果程序无法销毁窗口的任意部分,都会弹出带相应错误消息的讯息窗口,告诉您什么出错了。使您在您的代码中查错变得更容易些。
GLvoid KillGLWindow(GLvoid) // 正常销毁窗口
{
我们在KillGLWindow()中所作的第一件事是检查我们是否处于全屏模式。如果是,我们要切换回桌面。我们本应在禁用全屏模式前先销毁窗口,但在某些显卡上这么做可能会使得桌面崩溃。所以我们还是先禁用全屏模式。这将防止桌面出现崩溃,并在Nvidia和3dfx显卡上都工作的很好!
if (fullscreen) // 我们处于全屏模式吗?
{
我们使用ChangeDisplaySettings(NULL,0)回到原始桌面。将NULL作为第一个参数,0作为第二个参数传递强制Windows使用当前存放在注册表中的值(缺省的分辨率、色彩深度、刷新频率,等等)来有效的恢复我们的原始桌面。切换回桌面后,我们还要使得鼠标指针重新可见。
ChangeDisplaySettings(NULL,0); // 是的话,切换回桌面
ShowCursor(TRUE); // 显示鼠标指针
}
接下来的代码查看我们是否拥有着色描述表(hRC)。如果没有,程序将跳转至后面的代码查看是否拥有设备描述表。
if (hRC) // 我们拥有OpenGL渲染描述表吗?
{
如果存在着色描述表的话,下面的代码将查看我们能否释放它(将 hRC从hDC分开)。这里请注意我使用的的查错方法。基本上我只是让程序尝试释放着色描述表(通过调用wglMakeCurrent(NULL,NULL),然后我再查看释放是否成功。巧妙的将数行代码结合到了一行。
if (!wglMakeCurrent(NULL,NULL)) // 我们能否释放DC和RC描述表?
{
如果不能释放DC和RC描述表的话,MessageBox()将弹出错误消息,告知我们DC和RC无法被释放。NULL意味着消息窗口没有父窗口。其右的文字将在消息窗口上出现。"SHUTDOWN ERROR"出现在窗口的标题栏上。MB_OK的意思消息窗口上带有一个写着OK字样的按钮。
MB_ICONINFORMATION将在消息窗口中显示一个带圈的小写的i(看上去更正式一些)。
MessageBox(NULL,"释放DC或RC失败。","关闭错误",MB_OK | MB_ICONINFORMATION);
}
下一步我们试着删除着色描述表。如果不成功的话弹出错误消息。
如果无法删除着色描述表的话,将弹出错误消息告知我们RC未能成功删除。然后hRC被设为NULL。
if (!wglDeleteContext(hRC)) // 我们能否删除RC?
{
MessageBox(NULL,"释放RC失败。","关闭错误",MB_OK | MB_ICONINFORMATION);
} hRC=NULL; // 将RC设为 NULL
}
现在我们查看是否存在设备描述表,如果有尝试释放它。如果不能释放设备描述表将弹出错误消息,然后hDC设为NULL。
if (hDC && !ReleaseDC(hWnd,hDC)) // 我们能否释放 DC?
{
MessageBox(NULL,"释放DC失败。","关闭错误",MB_OK | MB_ICONINFORMATION); hDC=NULL; // 将 DC 设为 NULL
}
现在我们来查看是否存在窗口句柄,我们调用 DestroyWindow( hWnd )来尝试销毁窗口。如果不能的话弹出错误窗口,然后hWnd被设为NULL。
if (hWnd && !DestroyWindow(hWnd)) // 能否销毁窗口?
{ MessageBox(NULL,"释放窗口句柄失败。","关闭错误",MB_OK | MB_ICONINFORMATION); hWnd=NULL; // 将 hWnd 设为 NULL }
最后要做的事是注销我们的窗口类。这允许我们正常销毁窗口,接着在打开其他窗口时,不会收到诸如"Windows Class already registered"(窗口类已注册)的错误消息。
if (!UnregisterClass("OpenG",hInstance)) // 能否注销类?
{
MessageBox(NULL,"不能注销窗口类。","关闭错误",MB_OK | MB_ICONINFORMATION);
hInstance=NULL; // 将 hInstance 设为 NULL
}
}
第01课 OpenGL窗口(2)的更多相关文章
- 第01课 OpenGL窗口(4)
下面的代码处理所有的窗口消息.当我们注册好窗口类之后,程序跳转到这部分代码处理窗口消息. LRESULT CALLBACK WndProc( HWND hWnd, // 窗口的句柄 UINT uMsg ...
- 第01课 OpenGL窗口(3)
接下来的代码段创建我们的OpenGL窗口.我花了很多时间来做决定是否创建固定的全屏模式这样不需要许多额外的代码,还是创建一个容易定制的友好的窗口但需要更多的代码.当然最后我选择了后者.我经常在EMai ...
- 第01课 OpenGL窗口(1)
教程的这一节在2000年一月彻底重写了一遍.将会教您如何设置一个 OpenGL窗口.它可以只是一个窗口或是全屏幕的.可以任意 大小.任意色彩深度.此处的代码很稳定且很强大,您可以在您所有的OpenGL ...
- NeHe OpenGL教程 第一课:OpenGL窗口
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- (7)nehe教程1 创建一个OpenGL窗口:
不要用那个nehe ndk了 误人子弟! 转自: 一个窗口,代码可真多啊 http://www.yakergong.net/nehe/ 在这个教程里,我将教你在Windows环境中创建OpenGL程序 ...
- 第09课 OpenGL 移动图像
3D空间中移动图像: 你想知道如何在3D空间中移动物体,你想知道如何在屏幕上绘制一个图像,而让图像的背景色变为透明,你希望有一个简单的动画.这一课将教会你所有的一切.前面的课程涵盖了基础的OpenGL ...
- 第04课 OpenGL 旋转
旋转: 在这一课里,我将教会你如何旋转三角形和四边形.左图中的三角形沿Y轴旋转,四边形沿着X轴旋转. 上一课中我教给您三角形和四边形的着色.这一课我将教您如何将这些彩色对象绕着坐标轴旋转.其实只需在上 ...
- 第03课 OpenGL 添加颜色
添加颜色: 作为第二课的扩展,我将叫你如何使用颜色.你将理解两种着色模式,在下图中,三角形用的是光滑着色,四边形用的是平面着色 上一课中我教给您三角形和四边形的绘制方法.这一课我将教您给三角形和四边形 ...
- 第02课 OpenGL 多边形
你的第一个多边形: 在第一个教程的基础上,我们添加了一个三角形和一个四边形.也许你认为这很简单,但你已经迈出了一大步,要知道任何在OpenGL中绘制的模型都会被分解为这两种简单的图形.读完了这一课,你 ...
随机推荐
- CodeForce-807C Success Rate(二分数学)
Success Rate CodeForces - 807C 给你4个数字 x y p q ,要求让你求最小的非负整数b,使得 (x+a)/(y+b)==p/q,同时a为一个整数且0<=a< ...
- P7597 「EZEC-8」猜树 加强版
#include<bits/stdc++.h>using namespace std;#define rg register#define inf 0x3f3f3f3f#define ll ...
- php无限分类 构建树形结构
<?php class Classification { const PARENT_ID = 'parentid'; const ID = 'id'; const CHILDREN = 'chi ...
- Java线程类
基础知识 线程状态 根据Thread.State类中的描述,Java中线程有六种状态:NEW,RUNNABLE,WAITING,TERMINATED,BLOCKED. 就绪状态(NEW):当线程对象调 ...
- [原创]配置php+nginx 时遇到的”file not found","access denied"奇怪问题的解决过程
在centos 7中按照我的随笔转载文章"[转载]CentOS 下安装LEMP服务(Nginx.MariaDB/MySQL和PHP)"安装好后,结果无法显示phpinfo()信息, ...
- Windows下nginx报错解决:CreateFile() "xxx/logs/nginx.pid" failed
写在前面 本文给出Windows下nginx报错:CreateFile() "xxx/logs/nginx.pid" failed 的解决方法并分析了出错原因,其中 xxx 表示n ...
- P4756-Added Sequence【斜率优化】
正题 题目链接:https://www.luogu.com.cn/problem/P4756 题目大意 给出序列\(a\),设\(f(l,r)=|\sum_{i=l}^ra_i|\). \(m\)次询 ...
- 熬夜整理小白入门与提升分布式版本管理软件:Git,图文并茂(建议收藏)
@ 目录 什么是Git SVN VS Git 什么是版本控制 安装Git 谁在操作? Git本地仓库 本地仓库构造 重点 Git常用基本操作 git add git commit git diff g ...
- Python3入门系列之-----算术运算符|比较运算符|赋值运算符|逻辑运算符|成员运算符|身份运算符
什么是运算符? 本章节主要说明Python的运算符.举个简单的例子 1 +2 = 3 . 例子中,1 和 1.2 被称为操作数,"+" 称为运算符. Python语言支持以下类型的 ...
- unittest基本原理及介绍
unittest基本原理: unittest是python自带的测试框架,还有一个框架是:pytest,这里简单介绍下unittest模块的简单应用 unittest是python的标准测试库,相比于 ...