1、QtOpenGL教程Qt OpenGL 教程最近一段时间除了学习Qt,翻译Qt文档之外,由于工作和兴趣的原因,开 始着手看Qt OpenGL编程。在网上搜索了有关OpenGL的教程,发现?eHe的 OpenGL教程的还很不错,作者是NeHe。上面有很多种语言的实现,但是没有Qt和 Gtk的,所以我就想着手写这个Qt OpenGL教程,每课的内容和NeHe是一样的。 另外,介绍eHe的一个中文翻译站点CSDN-CKer翻译的eHe的OpenGL教程,翻 译人是CKer,在我学习这个教程的过程中,给了我很大的帮助。下面就是Qt OpenGL教程的内容:Qt OpenGL的准备工作第一课:创建一个O
2、penGL窗口第二课:你的第一个多边形第三课:上色第四课:旋转第五课:向三维进军第六课:纹理映射第七课:纹理滤波、光源和键盘控制第八课:融合第九课:在三维空间中移动位图第十课:载入一个三维世界并在其中移动第十一课:旗的效果(波动纹理)第十二课:显示列表第十三课:位图字体第十四课:轮廓字体第十五课:使用纹理映射的轮廓字体第十六课:看起来很棒的雾因为本教程是从NeHe的OpenGL教程迁移过来的,代码变为Qt实现的。所以 有的课程一时还没有实现成功,所以可能有些教程是跳跃的。因本人时间有限,所以难免有错误出现,如果您发现了这些错误,或者有什 么建议,请来信指教,谢谢。Qt OpenGL的准备工作因
3、为Qt存在很多版本,另外它支持的平台也很多,到目前为止我只实验了儿 个组合,所以就先把这些列出来吧,欢迎大家补充。Unix/XULinuxQt:自山版或者企业版都支持OpenGL模块,而专业版则不能。我现在使用的 是3. 1.0自由版和企业版。gcc:编译器。我现在使用的是3. 2。X: Linux下的图形环境。我现在使用的是4.2.0。Mesa:自山的OpenGLo我现在使用的是5.0。WindowsQt:企业版支持OpenGL模块,而专业版则不能。我现在使用的是3. 1. 0企业版。Microsoft Visual Studio:编译器。我现在使用的是6.0。创建一个OpenGL窗口我假设
4、您对Qt编程已经有了一定的了解,如果您还没有熟悉Qt编程,建议 您先学习一下Qt编程的基础知识。Qt中已经包含了 OpenGL模块,具体情况您可以参考Qt OpenGL模块的相关内容。NeHeWidget 类这就是我们继承QGLWidget类得到的OpenGL窗口部件类。(ill nehewidget. h 展开。)#include class NeHeWidget : public QGLWidgetQ_OBJECT因为QGLWidget类被包含在qgl. h头文件中,所以我们的类就需要包含这个 头文件。Q_OBJECT是Qt中的一个专用的宏,具体说明请参见Qt的文档。public:NeHe
5、Widget( QWidget* parent 二 0, const char* name = 0, bool fs = false );XeHeWidget();protected:void initializeGL();void paintGLO ;void resizeGL( int width, int height );因为QGLWidget类已经内置了对OpenGL的处理,就是通过对 initializeGL () paintGL ()和resizeGL ()这个三个函数实现的,具体情况可以参 考QGLWidget类的文档。因为我们的这个Qt OpenGL教程取材于NeHe Ope
6、nGL教程,所以这里就用这 个NeHeWidget类来继承QGLWidget类来使用相关OpenGL的功能。initializeGLO是用来初始化这个OpenGL窗口部件的,可以在里面设定一些 有关选项。paintGLO就是用来绘制OpenGL的窗口了,只要有更新发生,这个函数 就会被调用。resizeGL ()就是用来处理窗口大小变化这一事件的width和height 就是新的大小状态下的宽和高了,另外resizeGL()在处理完后会自动刷新屏幕。void keyPressEvent( QKeyEvent *e );这是Qt里面的鼠标按下事件处理函数。protected:bool fulls
7、creen;用来保存窗口是否处于全屏状态的变量。(ill nehewidget cpp 展开。)nclude nehewidget hNeHeWidget:eHeWidget( QWidget* parent, const char* name, bool fs ):QGLWidget( parent, name )fullscreen = fs;保存窗口是否为全屏的状态。setGeometry( 0, 0, 640, 480 );设置窗口的位置,即左上角为(0,0)点,大小为640*480。setCaption( /,NeHe,s OpenGL Framework );设置窗口的标题为NeH
8、es OpenGL Frameworkv。if ( fullscreen )showFulIScreen();如果fullscreen为真,那么就全屏显示这个窗口。这个是构造函数,parent就是父窗口部件的指针,name就是这个窗口部件的 名称,fs就是窗口是否最大化。NeHeWidget:NeHeWidget()这个是析构函数。void NeHeWidget:initializeGL()glShadeModel( GL.SMOOTH );这一行启用smooth shading(阴影平滑)。阴影平滑通过多边形精细的混合色 彩,并对外部光进行平滑。我将在另一个教程中更详细的解释阴影平滑。glC
9、learColor ( 0. 0, 0. 0, 0. 0, 0. 0 );这一行设置清除屏幕时所用的颜色。如果您对色彩的工作原理不清楚的话, 我快速解释一下。色彩值的范围从0.0到1.0。0.0代表最黑的情况,1.0就是最 亮的情况。glClearColor后的第一个参数是红色,第二个是绿色,第三个是蓝色。 最大值也是1.0,代表特定颜色分量的最亮悄况。最后一个参数是Alpha值。当它 用来清除屏幕的时候,我们不用关心第四个数字。现在让它为0.0。我会用另一个 教程来解释这个参数。通过混合三种原色(红、绿、蓝),您可以得到不同的色彩。希望您在学校 里学过这些。因此,当您使用glClearCol
10、or(0. 0, 0. 0, 1.0, 0.0),您将用亮蓝 色来清除屏幕。如果您用glClearColor(0. 5, 0.0, 0. 0, 0.0)的话,您将使用中 红色来清除屏幕。不是最亮(1.0),也不是最暗(0.0)。要得到白色背景,您应该 将所有的颜色设成最亮(1.0)。要黑色背景的话,您该将所有的颜色设为最暗 (0. 0)。glClearDepth( 1. 0 );设置深度缓存。glEnable( GL_DEPTH_TEST );启用深度测试。glDepthFunc( GL.LEQUAL );所作深度测试的类型。上面这三行必须做的是关于depth buffer (深度缓存)的。将
11、深度缓存设想 为屏幕后面的层。深度缓存不断的对物体进入屏幕内部有多深进行跟踪。我们本节 的程序其实没有真正使用深度缓存,但儿乎所有在屏幕上显示3D场景OpenGL程序 都使用深度缓存。它的排序决定那个物体先画。这样您就不会将一个圆形后面的正 方形画到圆形上来。深度缓存是OpenGL十分重要的部分。glHint( GL_PERSPECTIVE.CORRECTION_HINT, GL.NICEST );真正精细的透视修正。这一行告诉OpenGL我们希望进行最好的透视修正。这 会十分轻微的影响性能。但使得透视图看起来好一点。这个函数中,我们对OpenGL进行所有的设置。我们设置清除屏幕所用的颜 色,
12、打开深度缓存,启用smooth shading (阴影平滑),等等。这个例程直到 OpenGL窗口创建之后才会被调用。void NeHeWidget::paintGL()glClear( GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT );清楚屏幕和深度缓存。glLoadldentity();至置当前的模型观察矩阵。这个函数中包括了所有的绘图代码。任何您所想在屏幕上显示的东东都将在 此段代码中出现。以后的每个教程中我都会在例程的此处增加新的代码。如果您对 OpenGL已经有所了解的话,您可以在glLoadldentity()调用之后,函数返回之 前,试着添加一些
13、OpenGL代码来创建基本的形。如果您是OpenGL新手,等着我的 下个教程。訂前我们所作的全部就是将屏幕清除成我们前面所决定的颜色,清除深 度缓存并且重置场景。我们仍没有绘制任何东东。void NeHeWidget::resizeGL( int width, int height )if ( height = 0 )height 二 1;防止height为OoglViewport( 0, 0, (GLint)width, (GLint)height );重置当前的视口 (Viewport)。glMatrixMode( GL.PROJECTION );选择投影矩阵。glLoadldentity
14、();重置投影矩阵。gluPerspective( 45.0, (GLf loat) width/ (GLf loat) height, 0. 1, 100. 0 );建立透视投影矩阵。glMatrixMode( GL.MODELVIEW );选择模型观察矩阵。至置模型观察矩阵。上面儿行为透视图设置屏幕。意味着越远的东西看起来越小。这么做创建了 一个现实外观的场景。此处透视按照基于窗口宽度和高度的45度视角来计算。 0. 1, 100. 0是我们在场景中所能绘制深度的起点和终点。glMatrixMode(GL_PR0JECTI0N)指明接下来的两行代码将影响projection matrix (投影矩阵)。投影矩阵负责为我们的场景增加透视。glLoadldentity() 近似于重置。它将所选的矩阵状态恢复成其原始状态。调用glLoadldentity()之 后我们为场景设置透视图。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1