OpenGL中的绘制命令

本文详细介绍了OpenGL中的绘制命令,包括直接绘制、间接绘制和多重绘制。直接绘制分为利用GL_ELEMENT_ARRAY_BUFFER和不利用的两种情况,间接绘制涉及从GL_DRAW_INDIRECT_BUFFER读取数据,多重绘制使用数组表示多个绘制指令参数。文章还提到了相关的函数原型和使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

OpenGL中的绘制命令

1.直接绘制命令

OpenGL中以Draw开头的绘制命令主要分成两大类,一类是从GL_ELEMENT_ARRAY_BUFFER缓存中获取绘制信息的函数,一类是不从其获得绘制信息的函数。注意GL_ELEMENT_ARRAY_BUFFER是用于存放顶点索引数组的缓存,可以见OpenGL4.3如何管理buffer中的数据的这篇文章。当从GL_ELEMENT_ARRAY_BUFFER得到绘制信息时,OpenGL将会利用此缓存内存储的索引序号来读取当前顶点数组的顶点。而非此类绘制则是按照指定的顺序来读取顶点。
不利用GL_ELEMENT_ARRAY_BUFFER的绘制函数:

函数原形:
void glDrawArrays(GLenum mode, GLint first, GLsizei count);
函数说明:从顶点数组中first个开头的顶点,绘制count个顶点,绘制原语由mode指出,通常有GL_TRIANGLES, GL_LINE_LOOP,
GL_LINES, GL_POINTS等等

利用GL_ELEMENT_ARRAY_BUFFER的绘制函数:

函数原形: void glDrawElements(GLenum mode, GLsizei count,GLenum type, const GLvoid *indices);
函数说明:mode指定绘制原语,与上函数类似,*indices应为一个数组,指出每个偏移地址,指出从GL_ELEMENT_ARRAY_BUFFER当前元素数组的哪个读取数组索引(这个才是顶点的编号),count表示读取多少个顶点,而type表示数组中的值用何种数据类型存储的,只可以为GL_UNSIGNED_BYTE,GL_UNSIGNED_SHORT, GL_UNSIGNED_INT。

2.间接绘制命令

间接命令绘制的缓存对象需要被存储于GL_DRAW_INDIRECT_BUFFER中。

函数原形:
void glDrawArraysIndirect(GLenum mode,const GLvoid *indirect);
函数说明:从 GL_DRAW_INDIRECT_BUFFER 中读取数据,indirect指出一个命令结构体地址的偏移量,OpenGL将会从间接绘制缓存中此偏移地址获取绘制指令的其余部分,并调用glDrawArraysInstanced()。

下面是偏移地址中绘制指令的结构体:

typedef struct DrawArraysIndirectCommand_t
{
GLuint count;
GLuint primCount;
GLuint first;
GLuint baseInstance;
} DrawArraysIndirectCommand;

DrawArraysIndirectCommand中的成员将会被解释为调用glDrawArraysInstanced()函数的参数,first及count将会被直接传递给函数,primCount是实例的数量,baseInstance是顶点实例的偏移地址。(后面还会说明)

函数原形:
void glDrawElementsIndirect(GLenum mode, GLenum type, const GLvoid * indirect);
函数说明:与glDrawElements基本相同,不同是从 GL_DRAW_INDIRECT_BUFFER 中读取数据,indirect指出一个命令结构体地址的偏移量,OpenGL将会从间接绘制缓存中此偏移地址获取绘制指令的剩余部分。

下面是偏移地址中绘制指令的结构体:

typedef struct DrawElementsIndirectCommand_t
{
GLuint count;
GLuint primCount;
GLuint firstIndex;
GLuint baseVertex;
GLuint baseInstance;
} DrawElementsIndirectCommand;

3.多重绘制命令

多重绘制指令与此前的绘制指令类似,仅不同的是用数组来表示多个绘制指令的参数,下面仅说明一个多重绘制指令,其余的没有特殊的部分则不再多提:

函数原形:
void glMultiDrawArrays(GLenum mode, const GLint * first, const GLint * count, GLsizei primcount);
函数说明:*first,*count都是数组,primcount指出了所需执行的操作数量

下面给出了函数c语言的模拟代码:

void glMultiDrawArrays(GLenum mode,
const GLint * first,
const GLint * count,
GLsizei primcount)
{
    GLsizei i;
    for (i = 0; i < primcount; i++)
    {
        glDrawArrays(mode, first[i], count[i]);
    }
}

红宝书给出了一个说明的例子,但不能完整运行,用于说明绘制指令:
例3.5 - 3.6:

//顶点数组
static const GLfloat vertex_positions[] =
{
    -1.0f, -1.0f, 0.0f, 1.0f,
    1.0f, -1.0f, 0.0f, 1.0f,
    -1.0f, 1.0f, 0
OpenGL绘制矩形通常涉及以下几个步骤[^1]: 1. **设置颜色和线宽**: 使用`glColor3f()`和`glLineWidth()`设定画笔的颜色和线条宽度。 2. **启用元素数组模式**: `glEnableClientState(GL_VERTEX_ARRAY)` 和 `glEnableClientState(GL_COLOR_ARRAY)`,以使用预定义的顶点和颜色数据。 3. **创建顶点数据**: 创建包含矩形四个角顶点的数组,每个顶点包括位置(x, y)和颜色信息。 4. **设置顶点数据**: 使用`glVertexPointer()`设置顶点坐标数据,使用`glColorPointer()`设置颜色数据。 5. **定义矩形的两个三角形**: 因为OpenGL默认只能绘制三角形,所以矩形由两个重叠三角形构成。定义两个三角形的顶点顺序,通常是左下->右上->左上和右下->中心->左下。 6. **绘制**: 调用`glDrawArrays(GL_TRIANGLES, 0, 6)`,其中第一个参数是绘制模式(这里是GL_TRIANGLES),第二个参数是顶点数组的起始索引,第三个参数是绘制的顶点数量。 7. **调用glFlush()**[^2]以确保所有绘制操作都被立即执行并显示在屏幕上。 如果需要具体代码示例,这里有一个简化版的伪代码展示: ```c++ // 假设我们已经有了顶点数组vdata和颜色数组cdata glBegin(GL_TRIANGLES); // 开始绘制 glVertexPointer(2, GL_FLOAT, 0, &vdata[0]); // 设置顶点位置 glColorPointer(3, GL_FLOAT, 0, &cdata[0]); // 设置颜色 glDrawArrays(GL_TRIANGLES, 0, 6); // 绘制两个三角形 glEnd(); // 结束绘制 // 强制执行命令 glFlush(); ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值