现代OpenGL教程 01 - 入门指南 秒速五厘米 2022-06-13 01:38 178阅读 0赞 ## 文章转载自:[http://huangwei.pro/2015-05/modern-opengl1/][http_huangwei.pro_2015-05_modern-opengl1] ## ## 以下是我学习opengl得到的启示最多的一篇文章,我强烈地建议大家去读一下这位大神的相关系列的文章!还有[https://github.com/tomdalling/opengl-series][https_github.com_tomdalling_opengl-series]。这里面的代码包含全面,真正想学习opengl的可以去看看!而且比我写的代码精致得多! ## ## 译序 ## 早前学OpenGL的时候还是1.x版本,用的都是`glVertex`,`glNormal`等固定管线API。后来工作需要接触DirectX9,shader也只是可选项而已,跟固定管线一起混用着。现在工作内容是手机游戏,又转到OpenGL ES,发现OpenGL的世界已经完全不同了,OpenGL ES 2.0版本开始就不再支持固定管线,只支持可编程管线。 ![pipe2.0.png][] 国内很多资料教程参差不齐,旧式接口满天飞。在[知乎][Link 1]看到这一系列教程,觉着挺好,就想着一边学顺便翻译下。毕竟手游市场的机遇和竞争压力都在同比猛涨,多了解OpenGL ES肯定没有坏处。浮躁功利的环境下更需要怀着一颗宁静致远的心去提高自身功底,长路漫漫,与君共勉。 欢迎大家,这是现代OpenGL教程系列的第一篇。所有代码都是开源的,你可以在GitHub上下载:[https://github.com/tomdalling/opengl-series][https_github.com_tomdalling_opengl-series] 通过这篇教程,你将会学到如何在Windows下用Visual Studio 2013或Mac下用Xcode搭建OpenGL 3.2工程。该应用包含一个顶点着色器(vertex shader),一个片段着色器(fragment shader)和使用VAO和VBO来绘制的三角形。该工程使用[GLEW][]来访问OpenGL API,用[GLFW][]来处理窗口创建和输入,还有使用[GLM][]进行矩阵/矢量相关的数学运算。 这听上去有点无聊,但搭建这样的工程确实挺麻烦的,尤其对于初学者。只要解决完这问题,我们就可以开始玩些有趣的东西了。 \[TOC\] ## 获取代码 ## 所有例子代码的zip打包可以从这里获取:[https://github.com/tomdalling/opengl-series/archive/master.zip][https_github.com_tomdalling_opengl-series_archive_master.zip]。 这一系列文章中所使用的代码都存放在:[https://github.com/tomdalling/opengl-series][https_github.com_tomdalling_opengl-series]。你可以在页面中下载zip,加入你会git的话,也可以复制该仓库。 本文代码你可以在`source/01_project_skeleton`目录里找到。使用OS X系统的,可以打开根目录里的`opengl-series.xcodeproj`,选择本文工程。使用Windows系统的,可以在Visual Studio 2013里打开`opengl-series.sln`,选择相应工程。 工程里已包含所有依赖,所以你不需要再安装或者配置额外的东西。如果有任何编译或运行上的问题,请联系我。 ## 关于兼容性的提醒 ## 本文使用OpenGL 3.2,但我会尝试保持如下兼容: * 向后兼容OpenGL 2.1 * 向前兼容OpenGL 3.X和4.X * 兼容Android和iOS的OpenGL ES 2.0 因为OpenGL和GLSL存在许多不同版本,本文代码不一定能做到100%上述兼容。我希望能兼容99%,并且不同版本之间只要轻微修改即可。 想要了解OpenGL和GLSL不同版本间的区别,这里很好得罗列了[兼容列表][Link 2]。 ## Visual Studio下安装 ## 代码在Windows 7 32位系统,[Visual Studio Express 2013][](免费)下创建和测试。你应该可以打开解决方案并成功编译所有工程。如果有问题请联系我,或者将补丁发我,我会更新工程。 ## Xcode下安装 ## Xcode工程实在OSX 10.10系统,Xcode 6.1下创建并测试的。打开Xcode工程应该可以成功编译所有目标。加入你无法成功编译请联系我。 ## Linux下安装 ## Linux是基于[SpartanJ][]。我在Ubuntu 12.04下简单测试通过。 * 安装GLM,GLFW和GLEW: `sudo aptitude install libglm-dev libglew-dev libglfw-dev` * 进入工程目录:`cd platforms/linux/01_project_skeleto` * 运行makefile:`make` * 运行可执行文件:`bin/01_project_skeleton-debug` ## GLEW, GLFW和GLM介绍 ## 现在你有了工程,就让我们开始介绍下工程所用到的开源库和为啥需要这些。 [The OpenGL Extension Wrangler (GLEW)][GLEW]是用来访问OpenGL 3.2 API函数的。不幸的是你不能简单的使用`#include <GL/gl.h>`来访问OpenGL接口,除非你想用旧版本的OpenGL。在现代OpenGL中,API函数是在运行时(run time)确定的,而非编译期(compile time)。GLEW可以在运行时加载OpenGL API。 [GLFW][]允许我们跨平台创建窗口,接受鼠标键盘消息。OpenGL不处理这些窗口创建和输入,所以就需要我们自己动手。我选择GLFW是因为它很小,并且容易理解。 [OpenGL Mathematics (GLM)][GLM]是一个数学库,用来处理矢量和矩阵等几乎其它所有东西。旧版本OpenGL提供了类似`glRotate`, `glTranslate`和`glScale`等函数,在现代OpenGL中,这些函数已经不存在了,我们需要自己处理所有的数学运算。GLM能在后续教程里提供很多矢量和矩阵运算上帮助。 在这系列的所有教程中,我们还编写了一个小型库`tdogl`用来重用C++代码。这篇教程会包含`tdogl::Shader`和`tdogl::Program`用来加载,编译和链接shaders。 ## 什么是Shaders? ## Shaders在现代OpenGL中是个很重要的概念。应用程序离不开它,除非你理解了,否则这些代码也没有任何意义。 Shaders是一段GLSL小程序,运行在GPU上而非CPU。它们使用[OpenGL Shading Language (GLSL)][OpenGL Shading Language _GLSL]语言编写,看上去像C或C++,但却是另外一种不同的语言。使用shader就像你写个普通程序一样:写代码,编译,最后链接在一起才生成最终的程序。 Shaders并不是个很好的名字,因为它不仅仅只做着色。只要记得它们是个用不同的语言写的,运行在显卡上的小程序就行。 在旧版本的OpenGL中,shaders是可选的。在现代OpenGL中,为了能在屏幕上显示出物体,shaders是必须的。 为可能近距离了解shaders和图形渲染管线,我推荐Durian Software的相关文章[The Graphics Pipeline chapter][]。 <table style="margin:15px 0px; padding:0px; border:1px solid rgb(222,222,222); outline:0px; font-family:Lato,"PingFang SC","Microsoft YaHei",sans-serife,HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",Helvetica,Arial,sans-serif; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:1275px"> <thead style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px; background:rgb(248,248,248)"> <th style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-weight:normal; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; text-align:left"> </th> <th style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-weight:normal; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; text-align:left"> 主程序</th> <th style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-weight:normal; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; text-align:left"> Shader程序</th> </tr> </thead> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> 语言</td> <td style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> C++</td> <td style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> GLSL</td> </tr> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> 主函数</td> <td style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> int main(int, char**);</td> <td style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> void main();</td> </tr> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> 运行于</td> <td style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> CPU</td> <td style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> GPU</td> </tr> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> 需要编译?</td> <td style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> 是</td> <td style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> 是</td> </tr> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> 需要链接?</td> <td style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> 是</td> <td style="margin:0px; padding:0px 10px; border:1px solid rgb(222,222,222); outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> 是</td> </tr> </tbody> </table> 那shaders实际上干了啥?这取决于是哪种shader。 ## Vertex Shaders ## Vertex shader主要用来将点(x,y,z坐标)变换成不同的点。顶点只是几何形状中的一个点,一个点叫vectex,多个点叫vertices(发音为[ver-tuh-seez][])。在本教程中,我们的三角形需要三个顶点(vertices)组成。 Vertex Shader的GLSL代码如下: <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">2</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">3</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">4</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">5</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">6</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">7</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">8</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(117,113,94)">#version 150</span></span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"></span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(102,217,239)">in</span> vec3 vert;</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"></span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">void main() { </span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"> // does <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(102,217,239)">not</span> alter the vertices at all</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"> gl_Position = vec4(vert, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">1</span>);</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">}</span> </pre> </td> </tr> </tbody> </table> 第一行`#version 150`告诉OpenGL这个shader使用GLSL版本1.50. 第二行`in vec3 vert;`告诉shader需要那一个顶点作为输入,放入变量`vert`。 第三行定义函数`main`,这是shader运行入口。这看上去像C,但GLSL中`main`不需要带任何参数,并且不用返回void。 第四行`gl_Position = vec4(vert, 1);`将输入的顶点直接输出,变量`gl_Position`是OpenGL定义的全局变量,用来存储vertex shader的输出。所有vertex shaders都需要对`gl_Position`进行赋值。 `gl_Position`是4D坐标(vec4),但`vert`是3D坐标(vec3),所以我们需要将`vert`转换为4D坐标`vec4(vert, 1)`。第二个的参数`1`是赋值给第四维坐标。我们会在后续教程中学到更多关于4D坐标的东西。但现在,我们只要知道第四维坐标是`1`即可,i可以忽略它就把它当做3D坐标来对待。 Vertex Shader在本文中没有做任何事,后续我们会修改它来处理动画,摄像机和其它东西。 ## Fragment Shaders ## Fragment shader的主要功能是计算每个需要绘制的像素点的颜色。 一个”fragment”基本上就是一个像素,所以你可以认为片段着色器(fragment shader)就是像素着色器(pixel shader)。在本文中每个片段都是一像素,但这并不总是这样的。你可以更改某个OpenGL设置,以便得到比像素更小的片段,之后的文章我们会讲到这个。 本文所使用的fragment shader代码如下: <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">2</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">3</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">4</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">5</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">6</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">7</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">8</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(117,113,94)">#version 150</span></span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"></span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">out vec4 finalColor;</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"></span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">void main() { </span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"> //set every drawn pixel to white</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"> finalColor = vec4(<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">1.0</span>, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">1.0</span>, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">1.0</span>, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">1.0</span>);</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">}</span> </pre> </td> </tr> </tbody> </table> 再次,第一行`#version 150`告诉OpenGL这个shader使用的是GLSL 1.50。 第二行`finalColor = vec4(1.0, 1.0, 1.0, 1.0);`将输出变量设为白色。`vec4(1.0, 1.0, 1.0, 1.0)`是创建一个RGBA颜色,并且红绿蓝和alpha都设为最大值,即白色。 现在,就能用shader在OpenGL中绘制出了纯白色。在之后的文章中,我们还会加入不同颜色和贴图。贴图就是你3D模型上的图像。 ## 编译和链接Shaders ## 在C++中,你需要对你的`.cpp`文件进行编译,然后链接到一起组成最终的程序。OpenGL的shaders也是这么回事。 在这篇文章中用到了两个可复用的类,是用来处理shaders的编译和链接:`tdogl::Shader`和`tdogl::Program`。这两个类代码不多,并且有详细的注释,我建议你阅读源码并且去链接OpenGL是如何工作的。 ## 什么是VBO和VAO? ## 当shaders运行在GPU,其它代码运行在CPU时,你需要有种方式将数据从CPU传给GPU。在本文中,我们传送了一个三角的三个顶点数据,但在更大的工程中3D模型会有成千上万个顶点,颜色,贴图坐标和其它东西。 这就是我们为什么需要Vertex Buffer Objects (VBOs)和Vertex Array Objects (VAOs)。VBO和VAO用来将C++程序的数据传给shaders来渲染。 在旧版本的OpenGL中,是通过`glVertex`,`glTexCoord`和`glNormal`函数把每帧数据发送给GPU的。在现代OpenGL中,所有数据必须通过VBO在渲染之前发送给显卡。当你需要渲染某些数据时,通过设置VAO来描述该获取哪些VBO数据推送给shader变量。 ## Vertex Buffer Objects (VBOs) ## 第一步我们需要从内存里上传三角形的三个顶点到显存中。这就是VBO该干的事。VBO其实就是显存的“缓冲区(buffers)” - 一串包含各种二进制数据的字节区域。你能上传3D坐标,颜色,甚至是你喜欢的音乐和诗歌。VBO不关心这些数据是啥,因为它只是对内存进行复制。 ## Vertex Array Objects (VAOs) ## 第二步我们要用VBO的数据在shaders中渲染三角形。请记住VBO只是一块数据,它不清楚这些数据的类型。而告诉OpenGL这缓冲区里是啥类型数据,这事就归VAO管。 VAO对VBO和shader变量进行了连接。它描述了VBO所包含的数据类型,还有该传递数据给哪个shader变量。在OpenGL所有不准确的技术名词中,“Vertex Array Object”是最烂的一个,因为它根本没有解释VAO该干的事。 你回头看下本文的vertex shader(在文章的前面),你就能发现我们只有一个输入变量`vert`。在本文中,我们用VAO来说明“hi,OpenGL,这里的VBO有3D顶点,我想要你在vertex shader时,发三个顶点数据给vert变量。” 在后续的文章中,我们会用VAO来说“hi,OpenGL,这里的VBO有3D顶点,颜色,贴图坐标,我想要你在shader时,发顶点数据给vert变量,发颜色数据给vertColor变量,发贴图坐标给vertTexCoord变量。” 给使用上个OpenGL版本的用户的提醒 假如你在旧版本的OpenGL中使用了VBO但没有用到VAO,你可能会不认同VAO的描述。你会争论说“顶点属性”可以用`glVertexAttribPointer`将VBO和shaders连接起来,而不是用VAO。这取决于你是否认为顶点属性应该是VAO“内置(inside)”的(我是这么认为的),或者说它们是否是VAO外置的一个全局状态。3.2内核和我用的AIT驱动中,VAO不是可选项 - 没有VAO的封装`glEnableVertexAttribArray`, `glVertexAttribPointer`和`glDrawArrays`都会导致`GL_INVALID_OPERATION`错误。这就是为啥我认为顶点属性应该内置于VAO,而非全局状态的原因。[3.2内核手册][3.2]也说VAO是必须的,但我只听说ATI驱动会抛错误。下面描述引用自[OpenGL 3.2内核手册][3.2] > 所有与顶点处理有关的数据定义都应该封装在VAO里。 > 一般VAO边界包含所有更改vertex array状态的命令,比如VertexAttribPointer和EnableVertexAttribArray;所有使用vertex array进行绘制的命令,比如DrawArrays和DrawElements;所有对vertex array状态进行查询的命令(见第6章)。 不管怎样,我也知道为啥会有人认为顶点属性应该放在VAO外部。`glVertexAttribPointer`出现早于VAO,在这段时间里顶点属性一直被认为是全局状态。你应该能看得出VAO是一种改变全局状态的有效方法。我更倾向于认为是这样:假如你没有创建VAO,那OpenGL通过了一个默认的全局VAO。所以当你使用`glVertexAttribPointer`时,你仍然是在VAO内修改顶点属性,只不过现在从默认的VAO变成你自己创建的VAO。 这里有更多的讨论:[http://www.opengl.org/discussion\_boards/showthread.php/174577-Questions-on-VAOs][http_www.opengl.org_discussion_boards_showthread.php_174577-Questions-on-VAOs] ## 代码解释 ## 终于!理论已经说完了,我们开始编码。OpenGL对于初学者而言不是特别友好,但如果你理解了之前所介绍的概念(shaders,VBO,VAO)那你就没啥问题。 打开`main.cpp`,我们从`main()`函数开始。 首先,我们初始化GLFW: <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">2</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">3</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glfwSetErrorCallback(OnError);</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(102,217,239)">if</span>(!glfwInit())</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"> throw <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(166,226,46)">std</span>::runtime_error(<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(230,219,116)">"glfwInit failed"</span>);</span> </pre> </td> </tr> </tbody> </table> `glfwSetErrorCallback(OnError)`这一行告诉GLFW当错误发生时调用`OnError`函数。`OnError`函数会抛一个包含错误信息的异常,我们能从中发现哪里出错了。 然后我们用GLFW创建一个窗口。 <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">2</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">3</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">4</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">5</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">6</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">7</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">8</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">3</span>);</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">2</span>);</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">gWindow = glfwCreateWindow((int)SCREEN_SIZE.x, (int)SCREEN_SIZE.y, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(230,219,116)">"OpenGL Tutorial"</span>, NULL, NULL);</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(102,217,239)">if</span>(!gWindow)</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"> throw <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(166,226,46)">std</span>::runtime_error(<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(230,219,116)">"glfwCreateWindow failed. Can your hardware handle OpenGL 3.2?"</span>);</span> </pre> </td> </tr> </tbody> </table> 该窗口包含一个向前兼容的OpenGL 3.2内核上下文。假如`glfwCreateWindow`失败了,你应该降低OpenGL版本。 创建窗口最后一步,我们应该设置一个“当前”OpenGL上下文给刚创建的窗口: <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glfwMakeContextCurrent(gWindow);</span> </pre> </td> </tr> </tbody> </table> 无论我们调用哪个OpenGL函数,都会影响到“当前上下文”。我们只会用到一个上下文,所以设置完后,就别管它了。理论上来说,我们可以有多个窗口,且每个窗口都可以有自己的上下文。 现在我们窗口有了OpenGL上下文变量,我们需要初始化GLEW以便访问OpenGL接口。 <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">2</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">3</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glewExperimental = GL_TRUE; <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(117,113,94)">//stops glew crashing on OSX :-/</span></span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(102,217,239)">if</span>(glewInit() != GLEW_OK)</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"> throw <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(166,226,46)">std</span>::runtime_error(<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(230,219,116)">"glewInit failed"</span>);</span> </pre> </td> </tr> </tbody> </table> 这里的GLEW与OpenGL内核有点小问题,设置`glewExperimental`就可以修复,但希望再未来永远不要发生。 我们也可以用GLEW再次确认3.2版本是否存在: <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">2</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(102,217,239)">if</span>(!GLEW_VERSION_3_2)</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"> throw <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(166,226,46)">std</span>::runtime_error(<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(230,219,116)">"OpenGL 3.2 API is not available."</span>);</span> </pre> </td> </tr> </tbody> </table> 在`LoadShaders`函数中,我们使用本教程提供的`tdogl::Shader`和`tdogl::Program`两个类编译和链接了vertex shader和fragment shader。 <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">2</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">3</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">4</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(166,226,46)">std</span>::<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(166,226,46)">vector</span><tdogl::Shader> shaders;</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">shaders.push_back(tdogl::Shader::shaderFromFile(ResourcePath(<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(230,219,116)">"vertex-shader.txt"</span>), GL_VERTEX_SHADER));</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">shaders.push_back(tdogl::Shader::shaderFromFile(ResourcePath(<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(230,219,116)">"fragment-shader.txt"</span>), GL_FRAGMENT_SHADER));</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">gProgram = new tdogl::Program(shaders);</span> </pre> </td> </tr> </tbody> </table> 在`LoadTriangle`函数中,我们创建了一个VAO和VBO。这是第一步,创建和绑定新的VAO: <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">2</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glGenVertexArrays(<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">1</span>, &gVAO);</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glBindVertexArray(gVAO);</span> </pre> </td> </tr> </tbody> </table> 然后我们创建和绑定新的VBO: <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">2</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glGenBuffers(<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">1</span>, &gVBO);</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glBindBuffer(GL_ARRAY_BUFFER, gVBO);</span> </pre> </td> </tr> </tbody> </table> 接着,我们上传一些数据到VBO中。这些数据就是三个顶点,每个顶点包含三个`GLfloat`。 <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">2</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">3</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">4</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">5</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">6</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">7</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">GLfloat vertexData[] = { </span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(117,113,94)">// X Y Z</span></span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">0.0f</span>, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">0.8f</span>, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">0.0f</span>,</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">-0.8</span>f,<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">-0.8</span>f, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">0.0f</span>,</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px"> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">0.8f</span>,<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">-0.8</span>f, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">0.0f</span>,</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">};</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glBufferData(GL_ARRAY_BUFFER, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(102,217,239)">sizeof</span>(vertexData), vertexData, GL_STATIC_DRAW);</span> </pre> </td> </tr> </tbody> </table> 现在缓冲区包含了三角形的三个顶点,是时候开始设置VAO了。首先,我们应该启用shader程序中的`vert`变量。这些变量能被开启或关闭,默认情况下是关闭的,所以我们需要开启它。`vert`变量是一个“属性变量(attribute variable)”,这也是为何OpenGL函数名称中有带“Attrib”。我们可以在后续的文章中看到更多类型。 <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glEnableVertexAttribArray(gProgram->attrib(<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(230,219,116)">"vert"</span>));</span> </pre> </td> </tr> </tbody> </table> VAO设置最复杂的部分就是下个函数:`glVertexAttribPointer`。让我们先调用该函数,等会解释。 <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glVertexAttribPointer(gProgram->attrib(<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(230,219,116)">"vert"</span>), <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">3</span>, GL_FLOAT, GL_FALSE, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">0</span>, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline">NULL</span>);</span> </pre> </td> </tr> </tbody> </table> 第一个参数,`gProgram->attrib("vert")`,这就是那个需要上传数据的shder变量。在这个例子中,我们需要发数据给`vert`shader变量。 第二个参数,`3`表明每个顶点需要三个数字。 第三个参数,`GL_FLOAT`说明三个数字是`GLfloat`类型。这非常重要,因为`GLdouble`类型的数据大小跟它是不同的。 第四个参数,`GL_FALSE`说明我们不需要对浮点数进行“归一化”,假如我们使用了归一化,那这个值会被限定为最小0,最大1。我们不需要对我们的顶点进行限制,所以这个参数为false。 第五个参数,`0`,该参数可以在顶点之间有间隔时使用,设置参数为0,表示数据之间没有间隔。 第六个参数,`NULL`,假如我们的数据不是从缓冲区头部开始的话,可以设置这个参数来指定。设置该参数为NULL,表示我们的数据从VBO的第一个字节开始。 现在VBO和VAO都设置完成,我们需要对它们进行解绑定,防止一不小心被哪里给更改了。 <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">2</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glBindBuffer(GL_ARRAY_BUFFER, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">0</span>);</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glBindVertexArray(<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">0</span>);</span> </pre> </td> </tr> </tbody> </table> 到此,shader,VBO和VAO都准备好了。我们可以开始在`Render`函数里绘制了。 首先,我们先清空下屏幕,让它变成纯黑色: <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">2</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glClearColor(<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">0</span>, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">0</span>, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">0</span>, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">1</span>); <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(117,113,94)">// black</span></span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);</span> </pre> </td> </tr> </tbody> </table> 然后告诉OpenGL我们要开始使用VAO和shader了: <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">2</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glUseProgram(gProgram->object());</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glBindVertexArray(gVAO);</span> </pre> </td> </tr> </tbody> </table> 最后,我们绘制出三角形: <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glDrawArrays(GL_TRIANGLES, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">0</span>, <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">3</span>);</span> </pre> </td> </tr> </tbody> </table> 调用`glDrawArrays`函数说明我们需要绘制三角形,从第0个顶点开始,有3个顶点被发送到shader。OpenGL会在当前VAO范围内确定该从哪里获取顶点。 顶点将会从VBO中取出并发送到vertex shader。然后三角形内的每个像素会发送给fragment shader。接着fragment shader将每个像素变成白色。欢呼! 现在绘制结束了,为了安全起见,我们需要将shader和VAO进行解绑定: <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">2</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glBindVertexArray(<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">0</span>);</span> <span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glUseProgram(<span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; color:rgb(113,99,215)">0</span>);</span> </pre> </td> </tr> </tbody> </table> 最后一件事,在我们看到三角形之前需要切换帧缓冲: <table style="margin:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; border-collapse:collapse; border-spacing:0px; width:auto"> <tbody style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline"> <tr style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; vertical-align:baseline; height:35px"> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px 20px 0px 0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(102,102,102); background:rgb(39,40,34); text-align:right"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">1</span> </pre> </td> <td style="margin:0px; padding:0px; border:none; outline:0px; font-style:inherit; font-family:inherit; font-size:16px; vertical-align:middle; height:35px"> <pre style="margin-top:0px; margin-bottom:0px; padding:0px; border:none; outline:0px; font-weight:inherit; font-style:inherit; font-family:"Source Code Pro",Consolas,Monaco,Menlo,Consolas,monospace; font-size:10px; vertical-align:baseline; line-height:22.4px; overflow:auto; color:rgb(255,255,255); background:rgb(39,40,34)"><span style="margin:0px; padding:0px; border:0px; outline:0px; font-weight:inherit; font-style:inherit; font-family:inherit; font-size:15px; vertical-align:baseline; height:15px">glfwSwapBuffers(gWindow);</span> </pre> </td> </tr> </tbody> </table> 在帧缓冲被交换前,我们会绘制到一个不可见的离屏(off-screen)帧缓冲区。当我们调用`glfwSwapBuffers`时,离屏缓冲会变成屏幕缓冲,所以我们就能在窗口上看见内容了。 ## 进一步阅读 ## 在后续文章中,我们会对三角形进行贴图。之后,你会学到一点矩阵变换知识,就可以使用vertex shader来实现3D立方体旋转。 在这之后,我们开始创建3D场景并提交多个物体。 ## 更多现代OpenGL资料 ## 不幸的是,我不得不跳过很多内容,防止本教程的篇幅过长。后面还有很多好的现代OpenGL资料能满足你的求知欲: * [An intro to modern OpenGL][] by Joe Groff of Durian Software * [Learning Modern 3D Graphics Programming][] by Jason L. McKesson * [A collection of simple single file OpenGL examples][] by Jakob Progsch * [OpenGL Step by Step][] by Etay Meiri * [All about OpenGL ES 2.x][] by Diney Bomfim * [The OpenGL Progamming book on Wikibooks][] * [Tutorials on the OpenGL wiki][] * [OpenGL 4 tutorials][] by Donald Urquhart (Swiftless) * [open.gl][] by Alexander Overvoorde * [OpenGLBook.com][] by Eddy Luten * [The official OpenGL SDK documentation][] * [Compatibility tables for OpenGL, OpenGL ES, GLSL, and GLSL ES][Link 2] by Sugih Jamin [http_huangwei.pro_2015-05_modern-opengl1]: http://huangwei.pro/2015-05/modern-opengl1/ [https_github.com_tomdalling_opengl-series]: https://github.com/tomdalling/opengl-series [pipe2.0.png]: http://dn-huangweipro.qbox.me/static/img/opengl-tutorials/pipe2.0.png [Link 1]: http://www.zhihu.com/question/22005157 [GLEW]: http://glew.sourceforge.net/ [GLFW]: http://www.glfw.org/ [GLM]: http://glm.g-truc.net/ [https_github.com_tomdalling_opengl-series_archive_master.zip]: https://github.com/tomdalling/opengl-series/archive/master.zip [Link 2]: http://web.eecs.umich.edu/~sugih/courses/eecs487/common/notes/APITables.xml [Visual Studio Express 2013]: http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs#DownloadFamilies_2 [SpartanJ]: http://www.reddit.com/user/SpartanJ [OpenGL Shading Language _GLSL]: http://en.wikipedia.org/wiki/GLSL [The Graphics Pipeline chapter]: http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Chapter-1:-The-Graphics-Pipeline.html [ver-tuh-seez]: http://static.sfdict.com/dictstatic/dictionary/audio/luna/V00/V0096700.mp3 [3.2]: http://www.opengl.org/registry/doc/glspec32.core.20091207.pdf [http_www.opengl.org_discussion_boards_showthread.php_174577-Questions-on-VAOs]: http://www.opengl.org/discussion_boards/showthread.php/174577-Questions-on-VAOs [An intro to modern OpenGL]: http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Table-of-Contents.html [Learning Modern 3D Graphics Programming]: http://www.arcsynthesis.org/gltut/ [A collection of simple single file OpenGL examples]: https://github.com/progschj/OpenGL-Examples [OpenGL Step by Step]: http://ogldev.atspace.co.uk/ [All about OpenGL ES 2.x]: http://db-in.com/blog/2011/01/all-about-opengl-es-2-x-part-13/ [The OpenGL Progamming book on Wikibooks]: http://en.wikibooks.org/wiki/OpenGL_Programming [Tutorials on the OpenGL wiki]: http://www.opengl.org/wiki/Tutorials [OpenGL 4 tutorials]: http://www.swiftless.com/tutorials/opengl4/1-opengl-window.html [open.gl]: http://open.gl/ [OpenGLBook.com]: http://openglbook.com/ [The official OpenGL SDK documentation]: http://www.opengl.org/sdk/docs/
还没有评论,来说两句吧...