2
votes

I have a simple OpenGL program and trying to draw an instanced array that stored in a vertex shader. I'm using two follow shaders for rendering:

Vertex Shader:

#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.
}

After I've compiled and validated these shader I create a vertex array object and draw it like triangle strips:

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

The viewport of drawing is set to the window size like glViewport(0, 0, 800, 600). I pass to MVP a simple orthographic matrix with fallow code:

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

where the matrix was initialized:

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;
}

The problem is I got no triangle strips on my screen. I tried to draw vertex without MVP matrix (gl_Position = vec4(Position[gl_VertexID], 0.0, 1.0)) but also got nothing. How to detect where the problem is?

1
If it still doesn't work with glDrawArrays (since you're only rendering one instance), then it isn't an instancing problem.Nicol Bolas

1 Answers

4
votes
glBindVertexArray(vao);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 1);

And what exactly is stored in that VAO? I'm guessing your answer will be "nothing."

If so, then you have run afoul of several problems. If this is a compatibility context (or GL 2.1 or before), then OpenGL does not allow you to render with a VAO that has nothing in it. That is, you can't render with all attributes disabled. You will get a GL_INVALID_OPERATION error.

However, if you are in a core context 3.2 or above, then you can render with a disabled VAO.

Of course, that's just what the OpenGL specification says. What NVIDIA's drivers say is that you can render with a disabled VAO in both core and compatibility. What ATI's drivers say is that you can't render with a disabled VAO in both core and compatibility.

In short, if you want your code to work, bind something. Enable an array and put a buffer object there. It doesn't matter what is in it, since your shader simply won't care. But if you want it to work on different implementations, bind something.