5

I have a problem validating my shader program in LWJGL/OpenGL 3.
I read the documentation, but I can't seem to find a reason why a VAO is needed when calling glValidateProgram.

int program = glCreateProgram();
int vertexShader = glCreateShader(...);
int fragmentShader = glCreateShader(...);
// ... vertex and fragment shader loading, compiling, errorchecking ...
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glBindAttribLocation(program, 0, "position");
glBindAttribLocation(program, 1, "color");
glLinkProgram(program);
glDetachShader(program, shader);
glDetachShader(program, shader);
glValidateProgram(program);
if (glGetProgrami(program, GL_VALIDATE_STATUS) != GL_TRUE)
    System.exit(-1);

This exits the program without any error message.
GL_LINK_STATUS is OK and GL.getErrors() also has nothing to report.
But when creating a VAO around glValidateProgram it works just fine.
I can also just ignore the fact that glGetProgrami returns GL_FALSE and just run the shader program.

What i mean with creating a VAO around glValidateProgram():

int vao = glGenVertexArrays();
glBindVertexArray(vao);
glValidateProgram(program);
if (glGetProgrami(program, GL_VALIDATE_STATUS) != GL_TRUE)
    System.exit(-1);
glDeleteVertexArrays(vao);

When I do this, GL_VALIDATE_STATUS is true and I can draw my stuff.

The used shaders are simple passthrough shaders.
The vertex shader returns the position and the fragment shader returns the color.

So, why do I have to bind an VAO even though I can immediately delete it after the validation?

boraseoksoon
  • 1,792
  • 1
  • 16
  • 23

1 Answers1

7

This behavior matches the OpenGL spec. I'm using the OpenGL 3.3 spec as reference.

In appendix E.2.2 "Removed Features" on page 344, it says:

The default vertex array object (the name zero) is also deprecated. Calling VertexAttribPointer when no buffer object or no vertex array object is bound will generate an INVALID_OPERATION error, as will calling any array drawing command when no vertex array object is bound.

The spec for glValidateProgram() on page 82 says:

ValidateProgram will check for all the conditions that could lead to an INVALID_OPERATION error when rendering commands are issued, and may check for other conditions as well.

So because issuing a draw command without a VAO bound will given a GL_INVALID_OPERATION error, and glValidateProgram() checks if a draw command would give a GL_INVALID_OPERATION error, what you're seeing is exactly as expected.

Reto Koradi
  • 49,246
  • 7
  • 76
  • 116
  • Thanks. Since the objects the program draws are unknown during the creation of the shader, that means, I do not have any vaos to bind, I have to ask, if creating a vao only for the shader program's validation process is a valid way to prevent this error, or do I misunderstand anything about the connection between vaos and shaders and creating a temporary vao is a hint, that the structure of my rendering code is flawed? – iHaveNoIdeaWhatImDoing Sep 29 '16 at 06:22
  • 3
    @iHaveNoIdeaWhatImDoing: to my understanding you don't need to use `glValidateProgram` for anything but a debug aid. Checking the `GL_LINK_STATUS` is enough to check the failure at compilation time. – Yakov Galka Sep 29 '16 at 09:41
  • 1
    @iHaveNoIdeaWhatImDoing: The purpose of `glValidateProgram` is to check that everything is in place that's required to use a given program. The name is a bit unlucky, because it does not really validate the program, but that the execution environment (i.e. the state of the OpenGL context) matches the requirements of the program. – datenwolf Sep 29 '16 at 11:24