iammilind
iammilind

Reputation: 70088

OpenGL (in Ubuntu): glGetError() returns GL_INVALID_OPERATION

For OpenGL learning, I am referring to openglbook. Currently in chapter 2, I am trying to run its code which is pasted here for reference.

The problem I am facing is with below function:

void CreateShaders(void)
{
    GLenum ErrorCheckValue = glGetError();

    VertexShaderId = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(VertexShaderId, 1, &VertexShader, NULL);
    glCompileShader(VertexShaderId);

    FragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(FragmentShaderId, 1, &FragmentShader, NULL);
    glCompileShader(FragmentShaderId);

    ProgramId = glCreateProgram();
        glAttachShader(ProgramId, VertexShaderId);
        glAttachShader(ProgramId, FragmentShaderId);
    glLinkProgram(ProgramId);
    glUseProgram(ProgramId);

    ErrorCheckValue = glGetError(); // =====> returns GL_INVALID_OPERATION
    if (ErrorCheckValue != GL_NO_ERROR)
    {
        fprintf(
            stderr,
            "ERROR: Could not create the shaders: %s \n",
            gluErrorString(ErrorCheckValue)
        );

        exit(-1);
    }
}

As shown in above function(glew.h), why does it return "GL_INVALID_OPERATION" ?
If I comment those line, then it works but just prints a blank window.

Here is my glxinfo. Since my version is 2.2 and this code is meant for 3.3+, I have removed below code to avoid failure:

  glutInitContextVersion(4, 0); 
  glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
  glutInitContextProfile(GLUT_CORE_PROFILE);

Update: After following suggestions from @Tim's answer, I was able to run the program successfully; it seems that these lines were creation problem:

"#version 400\n" (replaced with "#version 130")

and

layout(location=0) (removed). layout(location=1) (removed).

However due to this the expected triangle is not printed exactly same. Probably the tutorial teaches with latest opengl version in mind, which I don't have and that creates the problem.

Is there any way to modify the code from latest OpenGL (4.0+) compatible code to lesser versions (e.g. < 3.0) without altering the output ? I won't be able to upgrade the graphics hardware.

Upvotes: 2

Views: 1825

Answers (1)

Tim
Tim

Reputation: 35943

You're not doing proper error checking for shader compiling and linking. It's likely you have some kind of syntax error in your shader which is preventing it from compiling, and therefore your useProgram call attempts to use an invalid program.

For each shader, after calling glCompileShader you'll want to call glGetShaderiv(shader, GL_COMPILE_STATUS, compile_status) which returns a true or false in compile_status to tell you if the compilation was a success. If it is not, you can call glGetShaderiv(shader, GL_INFO_LOG_LENGTH, length) to get the size of the infoLog, and then call glGetShaderInfoLog() to get a string which tells you any errors that occured during compilation.

In summary the compiler/linker error checking should be something like this:

void CheckError (GLuint shaderId, uint LINE)
{
  GLint bCompiled;
  glGetShaderiv(shaderId, GL_COMPILE_STATUS, &bCompiled);
  if(bCompiled == false)
  {
    GLint length;
    glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &length);
    GLchar *pInfo = new GLchar[length + 1];
    glGetShaderInfoLog(shaderId, length, &length, pInfo);
    fprintf(stderr, "called at line-%u: Compiler/Linker error: %s", LINE, pInfo);
    delete[] pInfo;
  }
}

If both shaders compile successfully, then after linking the program, you want to test the same thing on the program object with glGetProgramiv/GL_LINK_STATUS and glGetProgramInfoLog

Upvotes: 5

Related Questions