以前都是用Cg的,现在改用GLSL,又要重新学,不过两种语言很多都是相通的。
下面的例子是实现绘制一个三角形的简单程序。采用了VBO(veretx buffer object)、VAO(vertex array object)等OpenGL的一些新特性。越往后发展,可编程管线肯定是大势所趋,OpenGL里原来的一些固定管线的内容肯定会被废弃掉。所以从现在开始写程序就要养成使用新特性、采用可编程管线技术的好习惯。
一、VAO、VBO介绍
随着OpenGL状态和固定管线模式的移除,我们不在用任何glEnable函数调用,而且也不会有glVertex、glColor等函数调用。这就意味着我们需要一种新的方式来将数据传输到图形卡以渲染图形。我们可以采用VBO,或者是在OpenGL3以上版本引入的新的特性,叫做VAO。通过它,我们可以把顶点数据和颜色存储在不同的VBO中,但是在同一个VAO中。对于法线数据或者其他的顶点信息也是一样。
VAO,是这样一种方式:把对象信息直接存储在图形卡中,而不是在当我们需要的时候传输到图形卡。这就是Direct3D所采用得方式,而在OpenGL中只有OpenGL3.X以上的版本中采用。这就意味着我们的应用程序不用将数据传输到图形卡或者是从图形卡输出,这样也就获得了额外的性能提升。
使用VAO并不难。我们不需要大量的glVertex调用,而是把顶点数据存储在数组中,然后放进VBO,最后放入VAO。OpenGL会在后台为我们完成其他的功能。
使用VAO的步骤:
1、产生VAO
void glGenVertexArrays(
GLsizei n,
GLuint *arrays);
n:要产生的VAO对象的数量。
arrays:存放产生的VAO对象的名称。
2、绑定VAO
void glBindVertexArray(GLuint array);
array:要绑定的顶点数组的名字。
3、产生VBOs
void glGenBuffers(
GLsizei n,
GLuint *
buffers);
产生缓冲区对象的名称。
参数含义和glGenVertexArrays类似。
4、绑定VBOs
void glBindBuffer(
GLenum target,
GLuint
buffer);
绑定一个缓冲区对象。
target可能取值是:GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, GL_PIXEL_PACK_BUFFER, or GL_PIXEL_UNPACK_BUFFER.
当进行绑定之后,以前的绑定就失效了。
5、给VBO分配数据:
void glBufferData( GLenum target,
GLsizeiptr size,
const GLvoid * data,
GLenum usage);
target可能取值为:GL_ARRAY_BUFFER(表示顶点数据), GL_ELEMENT_ARRAY_BUFFER(表示索引数据),GL_PIXEL_PACK_BUFFER(表示从OpenGL获取的的像素数据), or GL_PIXEL_UNPACK_BUFFER(表示传递给OpenGL的像素数据).
参数含义:
size:缓冲区对象字节数
data:指针:指向用于拷贝到缓冲区对象的数据。或者是NULL,表示暂时不分配数据。
6、定义存放顶点属性数据的数组:
首先需要启用VAO中对应的顶点属性数组:
void glEnableVertexAttribArray( GLuint index);
index:指定了需要启用的顶点属性数组的索引
注意:它只在OpenGL2.0及其以上版本才有。
7、给对应的顶点属性数组指定数据:
void glVertexAttribPointer( GLuint index,
GLint size,
GLenum type,
GLboolean normalized,
GLsizei stride,
const GLvoid * pointer);
index:要指定数据的顶点属性数组的索引。
size:每个顶点属性的数据个数。可能的取值是1、2、3或者4.初始值是4.
type:数组中每个数据的类型。可能的取值是:GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT, GL_FLOAT, or GL_DOUBLE。初始值是GL_FLOAT。
normalized:指定顶点数在被访问的时候是否需要被归一化。
注意:如果有个非零的缓冲对象绑定到GL_ARRAY_BUFFER,那么pointer就是对应的缓冲区对象的偏移量。
stride:两个连续顶点的属性之间的偏移量。
pointer:指向数组中的第一个顶点属性的第一个数据。
8、然后在进行渲染的时候,只需要绑定对应的VAO即可,操作起来十分方便。
glBindVertexArray(vaoHandle);
9、使用完毕之后需要清除绑定。
glBindVertexArray(0);
VAO参考资料:
VAO wiki
关于VAO的一篇博客
VAO
事实上,在这个简单的程序中,不用VAO,只用VBO也一样可以实现。只是采用VAO可以进一步提升性能,而且在较新版本的OpenGL中不用VAO的方式会被逐渐废弃。
二、GLSL入门
关于GLSL,可以参考红宝书的附录,上面介绍了GLSL的入门知识。
这里也有一个很好的入门教程,英文的:
GLSL入门tutorial
三、程序实例
下面贴出源代码(OpenGL,GLSL实现):
basic.vert:
basic.frag:
主文件:
main.cpp:
读取shader文件的程序:
textfile.h:
textfile.cpp:
运行结果:
分享到:
相关推荐
内容包含了glm glut 等库,用vs2008 基于OpenGL 4.0 ,可以直接运行,包含所有源码,里面含有很多使用性技巧
本教程将介绍如何使用GLSL在OpenGL 4.0中渲染3D模型。本教程中的代码基于漫反射教程中的代码https://blog.csdn.net/weixin_44210987/article/details/109300986。 在之前的教程中,我们已经渲染过3D模型,但是它们...
非常不好找的 opengl 4.0 shading language cookbook 源码 GLSL COOKBOOK 源码 opengl 4.0 shading language cookbook 源码 GLSL COOKBOOK 源码 opengl 4.0 shading language cookbook 源码 GLSL COOKBOOK 源码 ...
If you are an OpenGL programmer looking to use the modern features of GLSL 4.0 to create real-time, three-dimensional graphics, then this book is for you. Familiarity with OpenGL programming, along ...
C# opengl vao vbo ebo 结合GLSL 语言 渲染器实例 有备注有说明,看蓝宝书一头雾水的可以看下,代码为OPENGL 加VS2015
opengl编程入门,glsl语言的hello world,你好三角形,绘制一个三角形
这源码是OpenGL4.6着色语言精通_第三版的全部源代码,利用GLSL 4.6和C++ 17构建高质量实时三维图形。主要重点是OpenGL着色语言(GLSL)。因此,我们不花时间讨论用OpenGL编程的基础。在这个我认为读者对在OpenGL中...
opengl编程入门,glsl语言的hello world,着色器,glsl语言简介
opengl glsl 延迟渲染 shader 放大镜效果
这本书是关于OpenGL4.0中怎么使用着色语言的。从基本算法讲起,很使用,带领读者入门。
将鱼眼全景图显示在一个球体上,从而肉眼能够感受到鱼眼视觉效果。
使用编译链接自定义的着色器...用GLSL语言来实现自定义顶点/片元着色器,并将图形进行简单的渲染显示。包含创建图层,创建上下文,清空缓存区设置RenderBuffer,设置FrameBuffer,开始绘制等步骤的详情代码和注释
用VB.net OpenTK写的一个GLSL版本330 + VAO的使用方法DEMO。可以简单了解着色模型ShaderModel的DEMO。并且shader实现了一个模糊效果。
OpenGL_ES之GLSL索引绘制并实现纹理颜色混合:详细介绍了使用索引绘制“金字塔”的全部步骤和逻辑处理,并处理渲染了纹理以及和颜色的混合。
在Qt框架下,用现代OpenGL实现的双面渲染,渲染对象是常见的茶壶模型,详见CSDN博客现代OpenGL+Qt学习笔记之八:GLSL双面渲染。
自己试写的在opengl中使用GLSL的例子
OpenGL Course GLSL 教程