PDA

View Full Version : glUsePorgram rise GL_INVALID_OPERATION



Junky
09-11-2010, 08:27 PM
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, &amp;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;
}

marshats
09-11-2010, 09:46 PM
What happens if you replace "ex_Color" everywhere in fragment shader with "pass_Color"?

Alfonse Reinheart
09-11-2010, 10:00 PM
According to the documentation, there are three ways to get GL_INVALID_OPERATION with glUseProgram:



GL_INVALID_OPERATION is generated if
program is not a program object.

GL_INVALID_OPERATION is generated if
program could not be made part of current
state.

GL_INVALID_OPERATION is generated if
transform feedback mode is active.

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.

Junky
09-12-2010, 05:20 AM
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, &amp;linkStatus). This put linkStatus to 0. This is GL_FALSE no? I don't understant what I'm doing wrong...

marshats
09-12-2010, 12:49 PM
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, &amp;infologLength);
GLchar buffer[infologLength];
GLsizei charsWritten = 0;
std::cout << onfail << std::endl;
glGetShaderInfoLog(id, infologLength, &amp;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, &amp;infologLength);
GLchar buffer[infologLength];
GLsizei charsWritten = 0;
std::cout << onfail << std::endl;
glGetProgramInfoLog(id, infologLength, &amp;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, &amp;ret, "unable to compile the vertex shader!");
CheckShader(fragmentshader, GL_COMPILE_STATUS, &amp;ret, "unable to compile the fragment shader!");
...
// Link our program, and set it as being actively used
glLinkProgram(shaderprogram);
CheckShader(shaderprogram, GL_LINK_STATUS, &amp;ret, "unable to link the program!");

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

Junky
09-12-2010, 01:05 PM
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 :) Next try will be with this card. And maybe I can test with tesellation ... hehe

Edit: I have ATI Radeon HD 3850

Junky
09-13-2010, 12:59 AM
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...

marshats
09-13-2010, 06:31 PM
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;
}

Junky
09-14-2010, 05:38 AM
Thanks! I will try when I have time.