OpenGL实例化数组绘图

Posted

技术标签:

【中文标题】OpenGL实例化数组绘图【英文标题】:OpenGL instanced array drawing 【发布时间】:2011-10-22 03:56:03 【问题描述】:

我有一个简单的 OpenGL 程序并试图绘制一个存储在顶点着色器中的实例化数组。我正在使用两个跟随着色器进行渲染:

顶点着色器:

#version 330 core

uniform mat4 MVP;

const int VertexCount = 4;
const vec2 Position[VertexCount] = vec2[](
vec2(-100.0f, -100.0f),
vec2( -100.0f, 100.0f),
vec2( 100.0f, -100.0f),
vec2(100.0f, 100.0f));

void main()
   
    gl_Position = MVP * vec4(Position[gl_VertexID], 0.0, 1.0);

片段着色器:

#version 330 core
#define FRAG_COLOR      0

layout(location = FRAG_COLOR, index = 0) out vec4 Color;

void main()

    Color = vec4(0, 1, 0, 1); //let it will be green.

编译并验证这些着色器后,我创建了一个顶点数组对象并将其绘制成三角形条带:

glUseProgram(programHandle); //handle is checked and valid.
glBindVertexArray(vao);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 1);

绘图的视口设置为像glViewport(0, 0, 800, 600)这样的窗口大小。我向 MVP 传递了一个带有休闲代码的简单正交矩阵:

glUniformMatrix4fv(handle, 1, GL_FALSE, (GLfloat*)&matrix); //handle is checked and valid

矩阵的初始化位置:

Matrix::CreateOrthographicOffCenter(-200, 200, -200, 200, 1.0f, -1.0f, &matrix);

...
void Matrix::CreateOrthographicOffCenter(float left, float right, float bottom, float top, float zNearPlane, float zFarPlane, Matrix* matrix)

memset(matrix, 0, sizeof(Matrix));
    matrix->M11 = 2.0f / (right - left);
    matrix->M14 = (-right - left) / (right - left);
    matrix->M22 = 2.0f / (top - bottom);
    matrix->M24 = (-top - bottom) / (top - bottom);
    matrix->M33 = 1.0f / (zFarPlane - zNearPlane);
    matrix->M34 = (-zNearPlane) / (zFarPlane - zNearPlane);
    matrix->M44 = 1.0f;

问题是我的屏幕上没有三角条。我试图在没有 MVP 矩阵的情况下绘制顶点 (gl_Position = vec4(Position[gl_VertexID], 0.0, 1.0)) 但也一无所获。如何检测问题出在哪里?

【问题讨论】:

如果它仍然不能与glDrawArrays 一起工作(因为你只渲染一个实例),那么这不是一个实例化问题。 【参考方案1】:
glBindVertexArray(vao);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 1);

那个 VAO 中究竟存储了什么?我猜你的答案是“什么都没有”。

如果是这样,那么您遇到了几个问题。如果这是一个兼容性上下文(或 GL 2.1 或更早版本),那么 OpenGL 不允许您使用其中没有任何内容的 VAO 进行渲染。也就是说,您不能在禁用所有属性的情况下进行渲染。您将收到 GL_INVALID_OPERATION 错误。

但是,如果您使用的是 3.2 或更高版本的核心上下文,那么您可以使用禁用的 VAO 进行渲染。

当然,这正是 OpenGL 规范所说的。 NVIDIA 的驱动程序说的是,您可以在核心和兼容性方面使用禁用的 VAO 进行渲染。 ATI 的驱动程序说,您无法核心和兼容性方面使用禁用的 VAO 进行渲染。

简而言之,如果你想让你的代码工作,绑定一些东西。启用一个数组并在那里放置一个缓冲区对象。里面有什么并不重要,因为你的着色器根本不在乎。但是如果你想让它在不同的实现上工作,绑定一些东西。

【讨论】:

我用 glGetError() 检查,但在渲染过程中没有错误代码。我正在尝试渲染顶点着色器中的顶点。

以上是关于OpenGL实例化数组绘图的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL实例化数组奇怪的顶点位置

OpenGL实例化绘图如何处理顶点输入限制

如何让实例化在我的 OpenGL 程序中工作?

如何在 Qt 5 中使用带有实例化的 VAO

在 OpenGL 中实例化数百万个对象

OpenGL ES之实例化渲染(Instancing)