Invalid operation after glUseProgram

I’m a begginer with glsl.I tried to load and use shaders in my program.According to gDEbugger,my shaders have been compiled successfully and the program has been linked successfully too.
But when I use a VBO to render something, an OPENGL error occurred,
Function Name: glDrawArrays
Error code: GL_INVALID_OPERATION.
Error description:
The specified operation is not allowed in the current state. The offending function is ignored, having no side effect other than to set the error flag.
Here are my source code:
glUseProgram(p);
glEnableClientState(GL_VERTEX_ARRAY);
//VBO
GLuint iVertexBuffer = 0;
glGenBuffers(1, &iVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, iVertexBuffer);
length=length*sizeof(VertexArray);
glBufferData(GL_ARRAY_BUFFER, length,VertexArray, GL_STATIC_DRAW);
delete [] VertexArray;
glBindBuffer(GL_ARRAY_BUFFER, iVertexBuffer);
glVertexPointer( 2, GL_INT, 0, (char *) NULL );
length=imageInUseSize[1]*2+1;
glDrawArrays(GL_TRIANGLE_FAN,0,length);
glUseProgram(0);

Thank you in advance.

First, avoid GL_INT vertex array data, that might not be accelerated. Use GL_FLOAT.

There are a little too many “length” variables with different meanings inside that snippet to know what’s going on.

Is the length=imageInUseSize[1]2+1; matching the number of vertices you put into the draw buffer earlier with length=lengthsizeof(VertexArray);

Are all other attribute arrays disabled?

int length=imageInUseSize[1]*4+2;
int *VertexArray=new int[length];

The length of the vertexarray is imageInUseSize[1]*4+2,and the number of vertices is imageInUseSize[1]*2+1.
IS it wrong?
And also the using of uniforms is an invalid operation?

GLint loc1,loc2,loc3,loc4,loc5,loc6,loc7,loc8,loc9,loc10,loc11,loc12,loc13,loc14,loc15;

loc1 = glGetUniformLocation(p,"centerscale");
glUniform1f(loc1,centerScale);

loc2=glGetUniformLocation(p,"offset");
glUniform2f(loc2,offsetX,offsetY);

loc3=glGetUniformLocation(p,"imageViewportSize");
glUniform2f(loc3,static_cast<float>(imageViewportSize[0]),
	            static_cast<float>(imageViewportSize[1]));

I’m sure all the other array attributes are disabled.

GL_LIST_MODE is GL_COMPILE, does it matter?

light,blend,texture1d,GL_PACK_ALIGNMENT are true

Sorry, you simply need to post more code (use the code tags!) or debug that more thoroughly.

For example things not visible inside your code snippet:
length=length*sizeof(VertexArray);

What is length before this point?
The sizeof() on the array variable already returns the total number of bytes in that array. So unless length is 1 before, this accesses the array out of bounds in glBufferData (=> could crash).

glUniform only works on the currently bound program (obviously because it has no program object as parameter), you must issue glUniform calls AFTER glUseProgram(yourprogram).

PACK_ALIGNMENT is related to pixel store, not vertex arrays.

And what have display lists to do with any of the above?

Other things to try: Does the code above run if you use standard vertex arrays and no VBO?

the length before this point is int length=imageInUseSize[1]*4+2

The display list has nothing with my code.I just tried to extent other people’s class library.And I find an error(invalid operation) when it comes to glcalllist,but I think it would have no side effect,is that right?

I have tried just vertex array,failed too

 int centerj=imageInUseSize[1]/2;
  int centeri=(rowBounds[centerj*2]+rowBounds[centerj*2+1])/2;

 int length=imageInUseSize[1]*4+2;
 float *VertexArray=new float[length];

  *VertexArray=centeri;
  *(VertexArray+1)=centerj;
  for ( j = 0; j < imageInUseSize[1]; j++ )
  {
     VertexArray[2+2*j] = static_cast<float>(rowBounds[j*2]);
     VertexArray[2+2*j+1]=static_cast<float>(j);
  }
  k=2+2*j;
  i=0;
  j--;
  for(;j>=0;j--)
  {
	  VertexArray[k+2*i]=static_cast<float>(rowBounds[j*2+1]);
      VertexArray[k+2*i+1]=static_cast<float>(j);
	  i++;
  }

glewInit();
  glGenBuffers = (PFNGLGENBUFFERSARBPROC) wglGetProcAddress("glGenBuffers");
  glBindBuffer = (PFNGLBINDBUFFERARBPROC) wglGetProcAddress("glBindBuffer");
  glBufferData = (PFNGLBUFFERDATAARBPROC) wglGetProcAddress("glBufferData");
  glDeleteBuffers = (PFNGLDELETEBUFFERSARBPROC) wglGetProcAddress("glDeleteBuffers");
 glDisable( GL_LIGHTING );
   initShader();

  //load shader
   GLuint v=0,f=0,p=0;
   char *vs = NULL,*fs = NULL;
   glCreateProgram_ptr glCreateProgram;
   if(0 == (glCreateProgram = reinterpret_cast<glCreateProgram_ptr>(wglGetProcAddress("glCreateProgram"))))
    exit(0);

	v = glCreateShader(GL_VERTEX_SHADER);
	f = glCreateShader(GL_FRAGMENT_SHADER);


	vs = textFileRead("F:\\&#31243;&#24207;\\vtkbin\\raycaster.vert");
	fs = textFileRead("F:\\&#31243;&#24207;\\vtkbin\\raycaster.frag");

	const char * vv = vs;
	const char * ff = fs;

	glShaderSource(v, 1, &vv,NULL);
        glShaderSource(f, 1, &ff,NULL);


	glCompileShader(v);
	glCompileShader(f);

	printShaderInfoLog(v);
	printShaderInfoLog(f);
	
	p = glCreateProgram();

	glAttachShader(p,v);
	glAttachShader(p,f);
	glLinkProgram(p);
	printProgramInfoLog(p);
	glUseProgram(p);

    glEnableClientState(GL_VERTEX_ARRAY);
      GLuint iVertexBuffer = 0;
    glGenBuffers(1, &iVertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, iVertexBuffer);
	length=length*sizeof(float);
    glBufferData(GL_ARRAY_BUFFER, length,VertexArray, GL_STATIC_DRAW);
	delete [] VertexArray; 
  
    glBindBuffer(GL_ARRAY_BUFFER, iVertexBuffer);
    glVertexPointer( 2, GL_FLOAT, 0, (char *) NULL );  
    length=imageInUseSize[1]*2+1;
	glDrawArrays(GL_TRIANGLE_FAN,0,length);


	glUseProgram(0);
    GLint loc1,loc2,loc3,loc4,loc5,loc6,loc7,loc8,loc9,loc10,loc11,loc12,loc13,loc14,loc15;

	loc1 = glGetUniformLocation(p,"centerscale");
	glUniform1f(loc1,centerScale);

	loc2=glGetUniformLocation(p,"offset");
    glUniform2f(loc2,offsetX,offsetY);

	loc3=glGetUniformLocation(p,"imageViewportSize");
    glUniform2f(loc3,static_cast<float>(imageViewportSize[0]),
		            static_cast<float>(imageViewportSize[1])); 

Ok, your new code now.

int length=imageInUseSize[1]*4+2;
float *VertexArray=new float[length];

length = length * sizeof(VertexArray);
glBufferData(GL_ARRAY_BUFFER, length,VertexArray, GL_STATIC_DRAW);

That should crash mightily.

Assume imageInUseSize[1] == 1

int length = 1*4+2 = 6
float *VertexArray=new float[6]; // 6 * 4 = 24 bytes.

length = length * sizeof(VertexArray); // == 6 * 6 * sizeof(float) = 144.
glBufferDataglBufferData(GL_ARRAY_BUFFER, 144, VertexArray, GL_STATIC_DRAW);

Booom!

Instead of
length = length * sizeof(VertexArray);
use
length = sizeof(VertexArray);
or
length *= sizeof(VertexArray[0]); // a float
or
length *= sizeof(float);

Thank you very much!I just didn’t see that.
I have modified my codes according to your advice, still crash.
The codes above length*=sizeof(float)

and sizeof(vertexarray)=4.because vertexarray is a pointer

>>and sizeof(vertexarray)=4. because vertexarray is a pointer.<<

Ok, I was mislead on the array thing because of the new float[] allocation. Would still be fatal under 64-bit where the pointer size is 8 bytes.

Thank you! I traced my program.
float *VertexArray=new float[ 1310]
glBufferData(GL_ARRAY_BUFFER, 5240,VertexArray, GL_STATIC_DRAW);
glDrawArrays(GL_TRIANGLE_FAN,0,655)
Maybe it’s not because the length of arrays.
I tried vertex at a time,still,when it came to glEnd ,invalid operation.I’m so confused. Maybe it’s because of glcalllist above.

I seemed to understand what’s wrong,but I don’t know how to solve the problem.I found my codes are in the display list, the display list is an invalid operation ,So whatever I draw would be wrong

Thank you, Relic! Finally find my problem, before drawing something ,I should give the uniforms.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.