OpenGL教程翻译 第二课 Hello Dot!

OpenGL教程翻译  第二课 Hello Dot!

原文地址:http://ogldev.atspace.co.uk/(源码请从原文主页下载)

Background

这将是我们第一次遇到GLEW,GLEW是OpenGL的扩展功能库。它能帮助你解决OpenGL不断扩展的问题。一旦你初始化它之后,它在你的系统上将查询所有可用的扩展功能,自动的加载它们并且通过一个单一的头文件提供简单的接口。

在这一节中,我们将第一次看见顶点缓冲区对象(VBOs)的使用。顾名思义,它们是被用来储存顶点数据的。加载顶点进入GPU最有效率的方法VBOs。它们是可以存储在显存中的缓冲区,使得GPU访问数据的速度最快。

这一节和下一节的内容在这本书中是唯一讲诉固定函数管线而不是可编程管线。我们简单的沿着数据的流动通过管线。在接下来的学习中将完整学习渲染管线,现在在涉及到光栅器之前我们使用屏幕坐标系绘制点、线、和三角形,点的坐标用X,Y,Z表示并且他们的值都在[-1.0,1.0]之间。光栅器映射这些坐标到屏幕空间(比如,如果屏幕的宽度是1025,x的坐标为-1.0将映射到0。X坐标为1.0将映射1023).最后,光栅器根据指定绘图命令(可以在下面的源代码解析中看到)的拓扑结构画出图元。因为我们没有绑定任何shader到管线中,所有顶点没有进行矩阵变化。这将意味着为了绘制出这些点我们仅仅需要传递给程序一些在上述范围之内的值就可以了。事实上,选择零点作为x、y两条轴的中心点,换句话说,零点是在屏幕的中间。

Installing GLEW: GLEW从服务器http://glew.sourceforge.net/中可以获得。大部分Linux为了GLEW提供了预编译包。在Ubuntu上,你可以安装通过运行下面的命令行命令 apt-get install libglew1.6 libglew1.6-dev 来安装它。

Sourcewalkthrough

#include<GL/glew.h>

这里我们包含了一个单一的GLEW头文件。如果你包含其他OpenGL头文件,你必须把GLEW头文件放在其他头文件之前。为了用户GLEW链接项目,你需要添加'-lGLEW'到编译脚本。

 

#include"math_3d.h"

在这一节我们开始使用其他的一些辅助工具比如vector。我们以后将会扩展这个头文件。

 

GLenum res =glewInit();
if (res != GLEW_OK)
{
   fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
   return 1;
}

这里我们初始化GLEW和检查是否存在一些错误。这必须要在GLUT被初始化之前完成。

 

Vector3fVertices[1];
Vertices[0] =Vector3f(0.0f, 0.0f, 0.0f);

我们创建了一个类型为Vector3f(这个类型被定义在math_3d.h)的数组,同时初始化XYZ为0.这将会使dot出现在屏幕中间。

 

GLuint VBO;

我们分配一个全局变量GLuint储存顶点缓存区对象的句柄,你稍后将看到大部分OpenGL对象通过一个GLuint类型的变量被访问。

 

glGenBuffers(1,&VBO);

OpenGL为了生成不同类型的对象定义几个glGen*函数。这些函数通常有两个参数,第一个参数指定你想要创建对象的数量,第二个是一个GLuint类型数组的地址,这个数组存储了句柄(确定数组是足够大来处理你的请求)。以后调用这个函数将不会生成相同的句柄,除非你使用glDeleteBuffers函数删除它。在这个地方,你不需要指定用这些buffers来做什么,所以创建的是普通的buffers,指定这个buffer的功能是下面一个函数的任务

 

glBindBuffer(GL_ARRAY_BUFFER,VBO);

OpenGL有一个独一无二的方法使用句柄。在许多的API中,句柄只是简单的通过一些相关的函数来使用。在OpenGL中我们绑定句柄到到一个目标上,然后在目标上执行命令。这些命令的执行只影响到已经绑定的句柄,直到被代替或者上面函数的句柄参数为0。目标GL_ARRAY_BUFFER表示缓冲区存储顶点数组。另一个有用的目标是GL_ELEMENT_ARRAY_BUFFER表示在另一个缓冲区存储数组的索引。别的目标也可以被设置,我们将在下一节看到。

 

glBufferData(GL_ARRAY_BUFFER,sizeof(Vertices),Vertices,GL_STATIC_DRA);

在绑定对象之后,用数据填充它。上面函数的调用使用了目标(和上面绑定的一样),数据的字节数,顶点数组的地址和数据使用样式的枚举量。因为指定了GL_STATIC_DRAW,所有我们没有改变缓冲区的内容,与之相反的将是GL_DYNAMIC_DRAW。可以通过它来产生最佳化的探索(比如在内存中哪个地方是最好的存储缓冲区)。

 

glEnableVertexAttribArray(0);

shaders章节中,你将看见shader中用到的顶点属性(位置,法线等)有一个映射到它们的索引,使我们在c/c++项目中创建的数据能与shader内的属性名之间进行绑定。此外你必须使每个顶点属性能够索引。在这一节中我们还没使用任何shader,但是我们加载到缓冲器的顶点位置在固定函数管线(在没有绑定着色器的时候就自动启用固定管线)中被看做顶点属性索引为0。你必须提供每个顶点属性,否则管线将接收不成数据。

 

glBindBuffer(GL_ARRAY_BUFFER,VBO);

由于将要调用绘图函数,所以这里我们再一次绑定了缓冲区。在这个小的项目中我们只有一个顶点缓冲区,所以在每一帧都调用函数是多余的。但是在更复杂的项目中存在很多个缓冲区来存储不同类型的变量,同时你必须用你打算使用的缓冲区来更新管线状态。

 

glVertexAttribPointer(0,3, GL_FLOAT, GL_FALSE, 0, 0);

这个函数调用告诉管线如何在缓冲区内部解释数据。第一个参数指定了属性的索引。我们都知道0是默认的,但是当我们开始使用shaders的时候,我们在shader中需要明确的设置索引。第二个参数是构成变量成分的个数(X,Y,Z共三个成分)。三个参数是每个成分的数据类型。第四个参数表明属性在管线中使用之前是否需要被标准化。第五个参数是在缓冲区中两个相同属性值之间的间隔的字节数。当只有一个属性时(比如缓冲区只包含顶点位置)并且数据是紧挨着的,那么我们设置这个值为0。如果我们有一个包含位置和法线的数组,我们将设置这个值为6*4=24。最后一个参数在上一个例子中是有用的。我们需要指定在缓冲区中存储数据的偏移值,这样管线才会找到数据。当顶点的位置和法线相邻存储时时,我们设置顶点位置的偏移值为0而顶点法线的偏移值为12。

 

glDrawArrays(GL_POINTS,0, 1);

最后,调用这个函数来画几何体。这里就是GPU真正开始工作的地方。它现在将结合绘图命令的参数,然后创建一个点并将结果渲染到屏幕。

OpenGL提供几个类型的渲染命令,每一个都适合于不同的情况。通常你可以把它们分成两个个类别——有序渲染和索引渲染。有序渲染是更简单的。GPU遍历你的顶点缓冲区,一个接着一个的访问顶点,然后根据在函数中指定的参数类别解释数据,例如,如果你指定GL_TRIANGLES,那么顶点0-2成为第一个三角形,3-5是第二个三角形等。如果你想让相同的顶点出现在不同的三角形中,你将需要在顶点缓冲区指定它两次,这是将会浪费空间。

使用索引渲染是更复杂的,并且涉及到了一个额外的缓冲区索引缓冲区。索引缓冲区包含在顶点缓冲区顶点的索引。GPU扫描索引缓冲区,与顺序渲染类似,他会将索引为0-2描述为第一个三角形。如果你想要相同的顶点在两个三角形中,那么只需要在索引缓冲区中简单的指点该顶点的索引两次。顶点缓冲区仅仅只需要包含一份拷贝。索引缓冲区在游戏中是更普遍的,因为大部分模型的表面(人的皮肤,城堡的墙等等)是由三角形组成的。

在这一节中,我们使用最简单的绘图命令-glDrawArrays。这是一个已经设计好的命令,所以这里没有保存索引编号缓冲区。我们指定点的拓扑结构意味着每个顶点就一个点。下一个参数是将要绘图的第一个顶点的索引。因为我们想要从缓冲区的开始来绘图,所以我们指定参数为0。但是这使我们可以在相同的缓冲区储存多个模型,只需要基于顶点在缓冲区的偏移量就可以选择一个图形去绘制。最后一个参数是要绘制图形顶点的数目。

 

glDisableVertexAttribArray(0);

当顶点不是立即被使用的时候,这是一个好的方法使得每一个顶点属性不被激活。当着色器不使用顶点的时候,如果此时的顶点时激活的将会遇到麻烦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值