车床厂家
免费服务热线

Free service

hotline

010-00000000
车床厂家
热门搜索:
技术资讯
当前位置:首页 > 技术资讯

【连载】现代OpenGL介绍(五) 软件编程OS 免费猫

发布时间:2020-02-17 12:29:11 阅读: 来源:车床厂家

【连载】现代OpenGL介绍(五) - 软件编程/OS - 电子工程网

在我们这里,我们的顶点数组只由单个vec2 position属性组成;如果我们有多个属性值,属性值可以是交错的,像是一个结构体数组,或者是分别存储在不同的数组里。灵活的glVertexAttribPointer让我们可以选择这两种情况中每个属性如何选择stride和offset去适应它们的存储布局;改变GLARRAYBUFFER绑定不影响由我们已经设置过的属性数组指针使用的缓冲。

(上面我没有提到的normalized?参数是跟顶点数组中的整型的数组一起使用的。如果为true,元素将从它们的integer类型的范围进行映射,比如0-255用于unsigned byte,0.0-1.0用于符点数,像图片中的颜色组分。如果为false,它们的整型值将被保存。像我们这样使用的已经是符点数的元素,该参数没有任何作用。)

提交渲染作业

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_resources.element_buffer);

glDrawElements(

GL_TRIANGLE_STRIP, /* mode */

4, /* count */

GL_UNSIGNED_SHORT, /* type */

(void*)0 /* element array buffer offset */

);

glDrawElements是设置绘图管线动作为函数。我们告诉它我们使用哪种三种角组装模式,使用多少顶点组装三角形,我们元素数组的组成类型,以及当前绑定的第一个要渲染的元素在GLELEMENTARRAY_BUFFER内部的偏移,这也是一个实际上是integer的指针参数。它将获取指向的元素数组的索引,将它们跟当前绑定的着色器程序,uniform变量,纹理单元,我们刚刚设置的顶点属性指针集合在一起,绑定成为一个渲染作业,并将这个作业放到GPU队列中。

清理工作

glDisableVertexAttribArray(g_resources.attributes.position);

Always leave things the way you found them ,Bill Brasky曾经建议过。OpenGL状态机的缺点就是所有的绑和设置都是全局地持久的,即使调用glDrawElements之后。这意味着我们必须注意整个程序生命期中,我们的OpenGL代码是怎样和其它的OpenGL代码交互的。尽管在这个程序中还没有其它的OpenGL代码与之交互,我们仍然应该养成一个好的习惯。尤其要注意顶点属性:在涉及到多个着色器程序和多个顶点数组的复杂程序中,不正确地使用顶点属性可能会造成glDrawElements去使用无效的GPU数据,导致错误的输出或者段错误。只在需要的时候去使用顶点数组是一个好习惯。这里,我们对position禁用顶点属性。

你也可能会想,每次渲染时,我们重新绑定了所有相同的对象,设置了所有的相同的uniform值(除了fade_factor),并且重新激活了所有的同样的顶点属性。如果状态设置在glDrawElements调用之间是持久的,从技术上讲在进入glutMainLoop之后,我们可以几乎完全没必要要每帧都进行设置,并且每次渲染只更新混色因子并调用glDrawElements。但是,在你每次期望的时候都设置好状态,这是个好主意。

显示我们完成的场景

glutSwapBuffers();

}

我们只有一个渲染作业需要等待,因此当我们提交作业并清理之后,我们可以立即执行同步。GLUT函数glutSwapBuffers等待所有的运行中的作业完成,然后用我们的双缓冲的framebuffer交换颜色缓冲,在下一帧时将当前可见的缓冲移到要渲染的 后面 ,然后将我们刚刚渲染好的图象推到前面,在我们的窗口中显示新渲染好的场景。我们的渲染流程完成了!

让场景动起来

static void update_fade_factor(void)

{

int milliseconds = glutGet(GLUT_ELAPSED_TIME);

g_resources.fade_factor = sinf((float)milliseconds * 0.001f) * 0.5f + 0.5f;

glutPostRedisplay();

}

为了让图片动起来,我们的glutIdleFunc回调函数不停地更新我们给fadefactor赋值的uniform。GLUT维护一个毫秒级的计时器,我们可以使用glutGet(GLUTELAPSED_TIME)访问到;我们使用标准C语言的sinf函数来得到一个平滑的,周期性的0到1之前的数。每次我们更新混色因子,我们调用glutPostRedisplay,这会强制我们的渲染回调函数去执行,更新窗口。

再次编译运行程序

这是我们最后一次编译和运行整个程序,使用所有我们的新的代码。构建和执行的命令看起来很像上次我们构建的空函数版本,但是这次,你将编译真正的hello-gl.c和util.c源文件。如果你使用Makefiles,你可以这样编译默认的目标:

make -f Makefile.MacOSX # or Makefile.Unix or Makefile.Mingw

nmake /f Nmakefile.Windows

一旦编译后,程序假定它的图片和着色器资源是在当前目录的,因此最好从包含可执行文件,图片,着色器代码的目录用命令行运行它。最后我们终于可以晒一下我们的成果了:

夕雾花的种植技术

河田鸡的养殖方法

武侠小说全集免费阅读

创富故事会