OpenGL 编程指南(第八版)学习笔记——3 OpenGL绘制方式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wlk1229/article/details/79433215

OpenGL 编程指南学习资料以及我整理的代码下载地址https://pan.baidu.com/s/1bqrcspD

文中提到的代码为下载文件中的“OpenGL编程指南 VS2015代码.zip”文件

3 OpenGL绘制方式

图元

点的大小可以通过glPointSize()函数和顶点着色器中的变量gl_PointSize变量控制。当通过glEnable(GL_PROGRAM_POINT_SIEZ)开启后,顶点着色器中的gl_PointSize可以决定大小,若顶点着色器没有给gl_PointSize赋值,顶点大小依然由glPointSize()函数决定。

线

线的宽度可以通过glLineWidth()函数设置,不可通过顶点着色器设置。

三角形

三角形正反,这个是通过三个点顺时针和逆时针方向来决定的(具体使用的数学算法是皮克定理,通过面积的正负判读),默认情况下逆时针为正面,但也可以通过glFrontFace()函数设置任一一个方向为正面。

在绘制的时候glEnable(GL_CULL_FACE)开启后,可以裁剪背面,背面就不会被绘制(可以通过函数glCullFace()函数设置裁剪哪个面)。

绘制正方形

OpenGL没有单独的图元类型绘制正方形,正方形可以通过GL_TRIANGLE_STRIP和GL_TRIANGLE_FAN两种模式绘制,绘制的时候点的设置如下。

绘制三角形的时候我们也可以通过glPolygonMode()函数设置绘制的是点、线、面。设置为点时,点大小可以通过glPointSize()函数和顶点着色器中的变量gl_PointSize变量控制。设置为线时,线的宽度可以通过glLineWidth()函数设置。

绘制

设置顶点数据

glVertexAttribpointer()函数可将当前绑定GL_ARRAY_BUFFER与顶点着色器中的输入变量绑定。这个函数只可以与顶点着色器中float类型绑定,int类型需要使用glVertexAttribIPointer()函数, double需要用glVertexAttribLPointer()函数。

绑定函数中的stride参数和pointer参数:stride是数据宽度,pointer是第一个数据的偏移量,例如以下结构体:

Struct Vertex

{

         GLfloat  pos[4];

         GLfloat  color[4];

};

GL_ARRAY_BUFFER缓存中有前面10个GLuint数据之后是10个Vertex数组。

绑定pos 到着色器中是stride设置为sizeof(Vertex),pointer偏移值为sizeof(GLuint)*10

绑定color到着色器中是stride设置为sizeof(Vertex),pointer偏移值为sizeof(GLuint)*10+sizeof(GLfloat )*4

多缓存绑定

绘制图形时可以在一个VAO(glBindVertexArray()绑定的对象)可以绑定多个GL_ARRAY_BUFFER对象,绑定一个GL_ARRAY_BUFFER后立即使用glVertexAttribpointer()函数与着色器中的输入进行绑定。具体可以参加第三章的例子:MultiBuffer。

mat4矩阵输入数据

对于顶点着色器中mat4矩阵输入数据,会占用4个连续的输入位置。使用四次glVertexAttribpointer()函数绑定输入数据,每次绑定矩阵的一列数据例如,以下时绑定着色器中的in mat4 Model;:

    model = glGetAttribLocation(pro, "Model");

    for (inti = 0; i<4; i ++)

    {

       glVertexAttribPointer(i + model, 4, GL_FLOAT, GL_FALSE, sizeof(vmath::mat4),

            BUFFER_OFFSET(sizeof(vmath::Tvec4<float>) * i));

       glEnableVertexAttribArray(i + model);

    }

多实例绘制

书中的多实例绘制对于初学者来说有些复杂,我实现了一个相对简单的多实例绘制,同时绘制4个正方形,工程为:3.5_EasyMultiInstancing,运行结果如下:

多实例绘制时数据绑定与平时绘制时基本相同,只是在设置针对每个实例进行更新的数据不一样。

多实例绘制时有两种数据:1.每个实例都相同的部分;2.实例特有的部分。

      实例相同部分数据与我们平时绘制绑定的数据是完全相同的,使用glVertexAttribpointer()函数绑定就行,是针对每个顶点更新的。

      实例特有的部分需要先使用glVertexAttribpointer()函数绑定数据,然后使用glVertexAttribDivisor()函数设置每隔多少个实例才更新,保证实例的单独特征。

猜你喜欢

转载自blog.csdn.net/wlk1229/article/details/79433215