OpenGL实例化数组绘图

时间:2011-08-08 06:55:16

标签: opengl rendering shader vertex-array

我有一个简单的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);
}

Fragment Shader:

#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))但也没有得到任何东西。如何检测出问题所在?

1 个答案:

答案 0 :(得分:4)

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进行渲染。

简而言之,如果您希望代码工作,请绑定一些东西。启用数组并在其中放置缓冲区对象。它的内容并不重要,因为你的着色器根本就不在乎。但是如果你想让它在不同的实现上工作,请绑定一些东西。