glUsePorgram rise GL_INVALID_OPERATION

Hi everyone,

I’m tring to develop a windows app with opengl 3.2. I follow diferents tutorials and on all I just see a blank screen but not the object rendered. I can change the back ground color with glClearColor.
After a lot of search I see that glUseProgram rise GL_INVALID_OPERATION.

I tried a some days but I don’t know what to do to solve this. I will apreciate any help.

Sorry for my English.

Thanks.

This is the render code:

void OpenGLContext::renderScene(void) {
    //glViewport(0, 0, windowWidth, windowHeight); // Set the viewport size to fill the window
    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Clear required buffers

    int i; /* Simple iterator */
    GLuint vao, vbo[2]; /* Create handles for our Vertex Array Object and two Vertex Buffer Objects */
    //GLfloat projectionmatrix[16]; /* Our projection matrix starts with all 0s */
    //GLfloat modelmatrix[16]; /* Our model matrix  */
    /* An identity matrix we use to perform the equivalant of glLoadIdentity */

    /* Verticies to make 4 triangles in the shape of a tetrahedron */
    const GLfloat tetrahedron[12][3] = {
    {  1.0,  1.0,  1.0  }, 
    { -1.0, -1.0,  1.0  },
    { -1.0,  1.0, -1.0  },
    {  1.0,  1.0,  1.0  },
    { -1.0, -1.0,  1.0  },
    {  1.0, -1.0, -1.0  },
    {  1.0,  1.0,  1.0  },
    { -1.0,  1.0, -1.0  },
    {  1.0, -1.0, -1.0  },
    { -1.0, -1.0,  1.0  },
    { -1.0,  1.0, -1.0  },
    {  1.0, -1.0, -1.0  } };

    /* Color information for each triangle */
    const GLfloat colors[12][3] = {
    {  1.0,  0.0,  0.0  }, 
    {  1.0,  0.0,  0.0  }, 
    {  1.0,  0.0,  0.0  }, 
    {  0.0,  1.0,  0.0  },
    {  0.0,  1.0,  0.0  },
    {  0.0,  1.0,  0.0  },
    {  0.0,  0.0,  1.0  },
    {  0.0,  0.0,  1.0  },
    {  0.0,  0.0,  1.0  },
    {  1.0,  1.0,  1.0  },
    {  1.0,  1.0,  1.0  },
    {  1.0,  1.0,  1.0  } };

    /* These pointers will receive the contents of our shader source code files */
    GLchar *vertexsource, *fragmentsource;

    /* These are handles used to reference the shaders */
    GLuint vertexshader, fragmentshader;

    /* This is a handle to the shader program */
    GLuint shaderprogram;

    /* Allocate and assign a Vertex Array Object to our handle */
    glGenVertexArrays(1, &vao);

    /* Bind our Vertex Array Object as the current used object */
    glBindVertexArray(vao);

    /* Allocate and assign two Vertex Buffer Objects to our handle */
    glGenBuffers(2, vbo);

    /* Bind our first VBO as being the active buffer and storing vertex attributes (coordinates) */
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);

    /* Copy the vertex data from tetrahedron to our buffer */
    /* 36 * sizeof(GLfloat) is the size of the tetrahedrom array, since it contains 36 GLfloat values */
    glBufferData(GL_ARRAY_BUFFER, 36 * sizeof(GLfloat), tetrahedron, GL_STATIC_DRAW);
    
    /* Specify that our coordinate data is going into attribute index 0, and contains three floats per vertex */
    glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    /* Enable attribute index 0 as being used */
    glEnableVertexAttribArray(0);

    /* Bind our second VBO as being the active buffer and storing vertex attributes (colors) */
    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);

    /* Copy the color data from colors to our buffer */
    /* 36 * sizeof(GLfloat) is the size of the colors array, since it contains 36 GLfloat values */
    glBufferData(GL_ARRAY_BUFFER, 36 * sizeof(GLfloat), colors, GL_STATIC_DRAW);

    /* Specify that our color data is going into attribute index 1, and contains three floats per vertex */
    glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, 0);

    /* Enable attribute index 1 as being used */
    glEnableVertexAttribArray(1);

    /* Read our shaders into the appropriate buffers */
    vertexsource = filetobuf("tutorial3.vert");
    fragmentsource = filetobuf("tutorial3.frag");

    /* Assign our handles a "name" to new shader objects */
    vertexshader = glCreateShader(GL_VERTEX_SHADER);
    fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);

    /* Associate the source code buffers with each handle */
    glShaderSource(vertexshader, 1, (const GLchar**)&vertexsource, 0);
    glShaderSource(fragmentshader, 1, (const GLchar**)&fragmentsource, 0);

    /* Compile our shader objects */
    glCompileShader(vertexshader);
    glCompileShader(fragmentshader);

    /* Assign our program handle a "name" */
    shaderprogram = glCreateProgram();
    
    /* Attach our shaders to our program */
    glAttachShader(shaderprogram, vertexshader);
    glAttachShader(shaderprogram, fragmentshader);
    
    /* Bind attribute 0 (coordinates) to in_Position and attribute 1 (colors) to in_Color */
    glBindAttribLocation(shaderprogram, 0, "in_Position");
    glBindAttribLocation(shaderprogram, 1, "in_Color");

    /* Link our program, and set it as being actively used */
    glLinkProgram(shaderprogram);
    glUseProgram(shaderprogram);

    /* Create our projection matrix with a 45 degree field of view
     * a width to height ratio of 1 and view from .1 to 100 infront of us */
    //perspective(projectionmatrix, 45.0, 1.0, 0.1, 100.0);

    /* Loop our display rotating our model more each time. */
    for (i=0; i < 360; i++)
    {

        /* Make our background black */
        glClearColor(0.0, 0.0, 0.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        /* Invoke glDrawArrays telling that our data consists of individual triangles */
        glDrawArrays(GL_TRIANGLES, 0, 12);

        /* Swap our buffers to make our changes visible */
        //SDL_GL_SwapWindow(window);
        SwapBuffers(hdc); // Swap buffers so we can see our rendering

    }

    /* Cleanup all the things we bound and allocated */
    glUseProgram(0);
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDetachShader(shaderprogram, vertexshader);
    glDetachShader(shaderprogram, fragmentshader);
    glDeleteProgram(shaderprogram);
    glDeleteShader(vertexshader);
    glDeleteShader(fragmentshader);
    glDeleteBuffers(2, vbo);
    glDeleteVertexArrays(1, &vao);
    free(vertexsource);
    free(fragmentsource);
}

Fragment:

#version 150
precision highp float;
in  vec3 ex_Color;
out vec4 gl_FragColor;

void main(void) {
    gl_FragColor = vec4(ex_Color,1.0);
}

Vertex:

 #version 150 core  
in vec3 in_Position;
in vec3 in_Color;  
out vec3 pass_Color;  
void main(void)
{
    gl_Position = vec4(in_Position, 1.0);
    pass_Color = in_Color;
}

What happens if you replace “ex_Color” everywhere in fragment shader with “pass_Color”?

According to the documentation, there are three ways to get GL_INVALID_OPERATION with glUseProgram:

I’m guessing it’s #1: your program failed to link and you didn’t check the GL_LINK_STATUS bit.

[edit]

This is most likely because your vertex program output is not named the same as your fragment program input. OpenGL doesn’t know that “in ex_Color” in the fragment program matches the “out pass_Color” from the vertex program.

Hi, thanks to answer.
It’s different because I did many tests and i change it. But putting the same name didn’t solve the problem. :S
It’s strange because if I compile a tutorial on the net the problem is the same, I can’t see objects rendered on the window. I can only see the windows with the background color.
I tried with SDL, without it… I also try to reinstall Ati drivers. But without success…

I get GL_LINK_STATUS after linking with glGetProgramiv(shaderprogram, GL_LINK_STATUS, &linkStatus). This put linkStatus to 0. This is GL_FALSE no? I don’t understant what I’m doing wrong…

I made in/out names match as mentioned in the previous post and then cut and pasted your C-code into a generic SDL code and it worked fine.

What hardware GPU do you have?

Maybe adding a check function


void CheckShader(GLuint id, GLuint type, GLint *ret, const char *onfail)
{
 //Check if something is wrong with the shader
 switch(type) {
 case(GL_COMPILE_STATUS):
   glGetShaderiv(id, type, ret);
   if(*ret == false){
    int infologLength =  0;
    glGetShaderiv(id, GL_INFO_LOG_LENGTH, &infologLength);
    GLchar buffer[infologLength];
    GLsizei charsWritten = 0;
    std::cout << onfail << std::endl;
    glGetShaderInfoLog(id, infologLength, &charsWritten, buffer);
    std::cout << buffer << std::endl;
   }
   break;
 case(GL_LINK_STATUS):
   glGetProgramiv(id, type, ret);
   if(*ret == false){
    int infologLength =  0;
    glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infologLength);
    GLchar buffer[infologLength];
    GLsizei charsWritten = 0;
    std::cout << onfail << std::endl;
    glGetProgramInfoLog(id, infologLength, &charsWritten, buffer);
    std::cout << buffer << std::endl;
   }
   break;
 default:
   break;
 };
}

And use it as


    /* Compile our shader objects */
    glCompileShader(vertexshader);
    glCompileShader(fragmentshader);

  GLint ret;
  CheckShader(vertexshader, GL_COMPILE_STATUS, &ret, "unable to compile the vertex shader!");
  CheckShader(fragmentshader, GL_COMPILE_STATUS, &ret, "unable to compile the fragment shader!");
...
  // Link our program, and set it as being actively used
  glLinkProgram(shaderprogram);
  CheckShader(shaderprogram, GL_LINK_STATUS, &ret, "unable to link the program!");

This should give more verbose information to stdout/console that may help you see what the problem is.

Hi!

I think the problem are Ati drivers… I install the newest version but it doesn’t work. The strange is that I try the tutorial and examples that there are on the net and nothing. It doesn’t work.
Mondey or tuesday I will have a Nvidia gtx 460 with 2Gb ram :slight_smile: Next try will be with this card. And maybe I can test with tesellation … hehe

Edit: I have ATI Radeon HD 3850

OOOHHH Finlally !!

I attach CheckShader function to my program and this what I get:

unable to compile the fragment shader!
Fragment shader failed to compile with the following errors:
ERROR: 0:4: error(#168) Reserved built-in name gl_FragColor
ERROR: error(#273) 1 compilation errors. No code generated

unable to link the program!
Fragment shader(s) were not successfully compiled before glLinkProgram() was called. Link failed.

I change gl_FragColor for out_FragColor and then it works!! I can see half of the screen in blue.

Thanks a lot.

Edit: I think it’s not solved yet. Just I can see is half of the screen blue and half white. But not the object…

Edit: I think it’s not solved yet. Just I can see is half of the screen blue and half white. But not the object…

It takes the whole screen because your coordinates for the tetrahedron are covering the max ±1 range of the screen (since you do not use the modelview or projection matrices). Are you sure you defined the vertices of the tetrahedron correctly? If you added rotation I suspect you would see the 3D structure more clearly that you defined in the const GLfloat tetrahedron[12][3]. Or do you really want to use GL_TRIANGLE_STRIP instead of GL_TRIANGLES in glDrawArrays?

A quick and dirty way to rotate and shrink the scale in half is to add a few functions to your tutorial3.vert shader as follows


#version 150 core  
in vec3 in_Position;
in vec3 in_Color;  
out vec3 pass_Color;

float cos_angle(vec3 v1, vec3 v2)
{
    return dot(normalize(v1), normalize(v2)); 
}

vec3 rotate_to_match(vec3 geom, vec3 velocity)
{
    //rotate geometry to match velocity (valid for vz!=0)
    //for vz!=0 see http://bobobobo.wordpress.com/2009/03/15/rotating-a-vector-to-match-up-with-another-vector/
    vec3 y = vec3(0.0,1.0,0.0);
    if (length(velocity.xz) < 1e-10) return geom;
    velocity = normalize(velocity);
    vec3 a = cross(y,velocity); // rotation axis
    float cosA = cos_angle(y, velocity);
    float sinA = sqrt(1-cosA*cosA); //problem? only positive sinaA returned
    mat3 s = mat3( vec3( 0.0, a.z,-a.y),
                   vec3(-a.z, 0.0, a.x),
                   vec3( a.y, a.x, 0.0) );
    mat3 uut =  mat3( vec3( a.x*a.x, a.x*a.y, a.x*a.z),
                      vec3( a.y*a.x, a.y*a.y, a.y*a.z),
                      vec3( a.z*a.x, a.z*a.y, a.z*a.z) );
    mat3 m = uut + cosA*(mat3(1.0)-uut)+sinA*s;
    return m*geom;
}
  
void main(void)
{
    gl_Position = vec4(rotate_to_match(0.5*in_Position, vec3(1.,1.,1.)), 1.0);
    pass_Color = in_Color;
}

Thanks! I will try when I have time.