glDrawElements error!!!!

Hi I am a beginner of OpenGL. Currently working on a co op job, developing a OpenGL application.

I have to use several glDrawElements calls on two different vertex array in one function.

The first vertex array size is arround 17379, the index array size for the first vertex array is around 5793. I am using this vertex array to draw points.

The second vertex array size and the size of its index array are all very small arround 3000, I am using them to draw meshes.

The problem is, the program throws access violation run time error as long as I use glDrawElements to draw the first vertex array. The second vertex array works fine all the time.

I thought the problem is cause by incorrect index array, but I use glbegin glend and glvertex3f in a forloop to draw second vertex array, the problem diapears. It seems that problem is just the glDrawElements.

I also tried to reduce the size of the first vertex array and its index array, the problem disappears!

Any body knows what might cause this kind of problem? I mean the access violation error caused by glDrawElements.

I am stucked, and I know my explaination of the question is not clear, I can provide more detail if you want.
Thank you very much!!! Because its my first co op job, I dont want my employeer disappoint.

Why is your index array smaller than your vertex array? If you are drawing GL_POINTS and you are drawing the entire vertex array then you should have the same amount of indices as you do vertices.

If running other commands causes it to start working it might be because the other commands have allocated memory with data that the first vertex array is bleeding into. Just like accessing array element 12 of a 10 element array, you can still get the data but it will usually be garbage.

Post some code, whats your glDrawElements command look like and how are you creating your arrays?

How are you creating the veretx arrays. Could u post the code here. My guess is that you are not putting the data appropriately. Just to check, you can try rendering the first vertex array directly using glDrawArrays and see if the error still comes up.

oh shouldnt the size of index array 3 times smaller than vertex array? because vertex array is float *, and index array is unsigned int *, each index in index array corresponds to 3 indices of vertex array, and this 3 indices stand for x, y, z coordinate of current vertex?

I will try to post code tommorrow, because the code is large I need to simplify them so that you dont have to see too much unrelated code.

Thanks!

I tried to use glDrawArrays and the error still there. But I tried to use for loop to render, in the for loop I traversed index array and used each index in index array to get each vertex in vertex array, and then use glVertex3f to render current vertex. Everything are working properly, so I guess the index array and vertex array are good… Or I missed something…?

I will try to post related code tommorrow, because I have to simplify the code so that you dont have to see too much unrelated code

Thanks!

should I use glBindBuffer before using glDrawElements? dose the problem appears because I used 2 different vertex and index array on glDrawElements? so that opengl will remember 2 vertex/index arrays, so that there will be some thing wrong in the inner part of the opengl? like segmentation fault? … ok I dont really know what I am asking , but maybe you can get my idea…? I will post code tommorrow though. Thanks !

should I use glBindBuffer before using glDrawElements? dose the problem appears because I used 2 different vertex and index array on glDrawElements? so that opengl will remember 2 vertex/index arrays, so that there will be some thing wrong in the inner part of the opengl? like segmentation fault? … ok I dont really know what I am asking , but maybe you can get my idea…? I will post code tommorrow though. Thanks !

Are you using vertex arrays or vertex buffer objects I cant say much unless u post a small snippet of code esp. the part you put the vertex/index data and the rendering part.

This is the render method of the program.
I have replaced the variable names, so that you can just search for variable names stated below to see the use of glDrawElements on the two vertex arrays.

vertex array 1 is vertexArray_1
size of vertex array 1 is Size_Of_VertexArray_1

index Array 1 is indexArray_1
size of index array 1 is Size_Of_IndexArray_1

vertex array 2 is vertexArray_2
size of vertex array 2 is Size_Of_VertexArray_2

index Array 2 is indexArray_2
size of index array 2 is Size_Of_IndexArray_2

I also commented where in the code the access violation error occurs, and by commenting which part of the code the program will run regularly.


void CMeshH::Render()
{
	glPushMatrix();	
	cgGLBindProgram(myCgVertexProgram_mesh);	
	cgGLEnableProfile(myCgVertexProfile_mesh);	
	cgGLBindProgram(myCgFragmentProgram_mesh);	
	cgGLEnableProfile(myCgFragmentProfile_mesh);	
	cgSetParameter4f(myCgFragmentParam_c, 1,0,0,1);	
	cgGLSetTextureParameter(myCgFragmentParam_decal, SPHERE_TEX_ID);	
	cgUpdateProgramParameters(myCgFragmentProgram_mesh);		
	glEnable(GL_POINT_SPRITE);
	glTexEnvi(GL_POINT_SPRITE,GL_COORD_REPLACE,GL_TRUE);
	cgGLSetStateMatrixParameter(myCgVertexParam_modelViewProj,
				    CG_GL_MODELVIEW_PROJECTION_MATRIX, 
			            CG_GL_MATRIX_IDENTITY);
	cgGLEnableTextureParameter(myCgFragmentParam_decal);

	cgUpdateProgramParameters(myCgVertexProgram_mesh);

    	glEnable(GL_TEXTURE_2D);
    	glBindTexture(GL_TEXTURE_2D, SPHERE_TEX_ID);
	glEnable(GL_BLEND);	
	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(3, GL_FLOAT, 0, vertexArray_1);
	glPointSize(sphereRadius);

	//The access violation is thrown at this glDrawElements call. 
	glDrawElements(GL_POINTS,Size_Of_indexArray_1,GL_UNSIGNED_INT,indexArray_1);
		
		/*    If I uncomment this for loop, and comment glDrawElements call above, the program renders as usual 
		int t=0;
		glBegin(GL_POINTS);
		for(int i=0;i<Size_Of_indexArray_1;i++)
		{
			
			glVertex3f(wound->vertexArray_1[3*indexArray_1[i]],
				   wound->vertexArray_1[3*indexArray_1[i]+1],
				   wound->vertexArray_1[3*indexArray_1[i]+2]);
			t+=3;
		
		}
		glEnd();
		*/

	glVertexPointer(3, GL_FLOAT, 0, vertexArray_2);
	glEnableClientState(GL_NORMAL_ARRAY);
	glNormalPointer(GL_FLOAT, 0, mpNormalArray);

	glDisable(GL_POINT_SMOOTH);
	glDisable(GL_POINT_SPRITE);

	//disable CG shading
	cgGLDisableProfile(myCgVertexProfile_mesh);
	
	cgGLDisableProfile(myCgFragmentProfile_mesh);
	
	cgGLDisableTextureParameter(myCgFragmentParam_decal);
	glDisable(GL_TEXTURE_2D);
	

	glColor3f(mRed, mGreen, mBlue);

	if (LTE_WIRE_FRAME){
		glPushAttrib(GL_POLYGON_BIT);
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
		glColor3f(0.0f, 0.0f, 1.0f);

	}
	else {
		glShadeModel(GL_SMOOTH);

		if (!mOpaque)
		{
			glEnable(GL_BLEND);
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
			glColor4f(mRed_Body, mGreen_Body, mBlue_Body, mAlpha_Body);
		}

		if (mTextureEnabled)
		{
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, mOuterTexture);
		 	// enable and specify the texture coordinate array
			if (mTextureEnabled && mpTexCoordArray)
			{
				glEnableClientState(GL_TEXTURE_COORD_ARRAY);
				glTexCoordPointer(2, GL_FLOAT, 0, mpTexCoordArray);
			}
			else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
		}
	}

	// enable and specify the colour array
    	if (mpColourArray != 0){
		glEnableClientState(GL_COLOR_ARRAY);
		glColorPointer(4, GL_FLOAT, 0, mpColourArray);
	}
	else glDisableClientState(GL_COLOR_ARRAY);

	
	glDrawElements(GL_TRIANGLES,Size_Of_indexArray_2, GL_UNSIGNED_INT, indexArray_2);
	
	if (!LTE_WIRE_FRAME && mTextureEnabled) 
	   glBindTexture(GL_TEXTURE_2D, mGrooveTexture);
	glDrawElements(GL_TRIANGLES, mGrooveIndexArraySize, GL_UNSIGNED_INT, mpGrooveIndexArray);

	if (!mOpaque) glDisable(GL_BLEND);

    	glFlush();

	if (mTextureEnabled)
		glDisable(GL_TEXTURE_2D);

	
	glDisableClientState(GL_NORMAL_ARRAY);
	if (LTE_WIRE_FRAME)
		glPopAttrib();

    	glPopMatrix();

	glDisableClientState(GL_VERTEX_ARRAY);

}

This is the render method of the program.
I have replaced the variable names, so that you can just search for variable names stated below to see the use of glDrawElements on the two vertex arrays.

vertex array 1 is vertexArray_1
size of vertex array 1 is Size_Of_VertexArray_1

index Array 1 is indexArray_1
size of index array 1 is Size_Of_IndexArray_1

vertex array 2 is vertexArray_2
size of vertex array 2 is Size_Of_VertexArray_2

index Array 2 is indexArray_2
size of index array 2 is Size_Of_IndexArray_2

I also commented where in the code the access violation error occurs, and by commenting which part of the code the program will run regularly.


void CMeshH::Render()
{
	glPushMatrix();	
	cgGLBindProgram(myCgVertexProgram_mesh);	
	cgGLEnableProfile(myCgVertexProfile_mesh);	
	cgGLBindProgram(myCgFragmentProgram_mesh);	
	cgGLEnableProfile(myCgFragmentProfile_mesh);	
	cgSetParameter4f(myCgFragmentParam_c, 1,0,0,1);	
	cgGLSetTextureParameter(myCgFragmentParam_decal, SPHERE_TEX_ID);	
	cgUpdateProgramParameters(myCgFragmentProgram_mesh);		
	glEnable(GL_POINT_SPRITE);
	glTexEnvi(GL_POINT_SPRITE,GL_COORD_REPLACE,GL_TRUE);
	cgGLSetStateMatrixParameter(myCgVertexParam_modelViewProj,
				    CG_GL_MODELVIEW_PROJECTION_MATRIX, 
			            CG_GL_MATRIX_IDENTITY);
	cgGLEnableTextureParameter(myCgFragmentParam_decal);

	cgUpdateProgramParameters(myCgVertexProgram_mesh);

    	glEnable(GL_TEXTURE_2D);
    	glBindTexture(GL_TEXTURE_2D, SPHERE_TEX_ID);
	glEnable(GL_BLEND);	
	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(3, GL_FLOAT, 0, vertexArray_1);
	glPointSize(sphereRadius);

	//The access violation is thrown at this glDrawElements call. 
	glDrawElements(GL_POINTS,Size_Of_indexArray_1,GL_UNSIGNED_INT,indexArray_1);
		
		/*    If I uncomment this for loop, and comment glDrawElements call above, the program renders as usual 
		int t=0;
		glBegin(GL_POINTS);
		for(int i=0;i<Size_Of_indexArray_1;i++)
		{
			
			glVertex3f(wound->vertexArray_1[3*indexArray_1[i]],
				   wound->vertexArray_1[3*indexArray_1[i]+1],
				   wound->vertexArray_1[3*indexArray_1[i]+2]);
			t+=3;
		
		}
		glEnd();
		*/

	glVertexPointer(3, GL_FLOAT, 0, vertexArray_2);
	glEnableClientState(GL_NORMAL_ARRAY);
	glNormalPointer(GL_FLOAT, 0, mpNormalArray);

	glDisable(GL_POINT_SMOOTH);
	glDisable(GL_POINT_SPRITE);

	//disable CG shading
	cgGLDisableProfile(myCgVertexProfile_mesh);
	
	cgGLDisableProfile(myCgFragmentProfile_mesh);
	
	cgGLDisableTextureParameter(myCgFragmentParam_decal);
	glDisable(GL_TEXTURE_2D);
	

	glColor3f(mRed, mGreen, mBlue);

	if (LTE_WIRE_FRAME){
		glPushAttrib(GL_POLYGON_BIT);
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
		glColor3f(0.0f, 0.0f, 1.0f);

	}
	else {
		glShadeModel(GL_SMOOTH);

		if (!mOpaque)
		{
			glEnable(GL_BLEND);
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
			glColor4f(mRed_Body, mGreen_Body, mBlue_Body, mAlpha_Body);
		}

		if (mTextureEnabled)
		{
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, mOuterTexture);
		 	// enable and specify the texture coordinate array
			if (mTextureEnabled && mpTexCoordArray)
			{
				glEnableClientState(GL_TEXTURE_COORD_ARRAY);
				glTexCoordPointer(2, GL_FLOAT, 0, mpTexCoordArray);
			}
			else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
		}
	}

	// enable and specify the colour array
    	if (mpColourArray != 0){
		glEnableClientState(GL_COLOR_ARRAY);
		glColorPointer(4, GL_FLOAT, 0, mpColourArray);
	}
	else glDisableClientState(GL_COLOR_ARRAY);

	
	glDrawElements(GL_TRIANGLES,Size_Of_indexArray_2, GL_UNSIGNED_INT, indexArray_2);
	
	if (!LTE_WIRE_FRAME && mTextureEnabled) 
	   glBindTexture(GL_TEXTURE_2D, mGrooveTexture);
	glDrawElements(GL_TRIANGLES, mGrooveIndexArraySize, GL_UNSIGNED_INT, mpGrooveIndexArray);

	if (!mOpaque) glDisable(GL_BLEND);

    	glFlush();

	if (mTextureEnabled)
		glDisable(GL_TEXTURE_2D);

	
	glDisableClientState(GL_NORMAL_ARRAY);
	if (LTE_WIRE_FRAME)
		glPopAttrib();

    	glPopMatrix();

	glDisableClientState(GL_VERTEX_ARRAY);

}

I’m not understanding why you’re using “vertexArray_1” in your glVertexPointer call but “wound->vertexArray_1” in your glVertex3f call; this indicates that you’re actually using different memory locations for each.

This kind of violation generally occurs when you overflow a vertex array or when you have a client state enabled but no pointer (or the wrong/a bad pointer) set for it. If, for example, “vertexArray_1” is NULL (I assume that “wound->vertexArray_1” is non-NULL as it doesn’t crash) your glVertexPointer is actually pointing to memory at address 0, which will generally not be readable by your program. Have you run this program in a debugger? Do so and check the value of “vertexArray_1” at your glVertexPointer call.

oh sorry I didnt clean up the code completely…
in the original code, vertex array 1 is wound->vertexArray. But because I want to make the
code more clear to demostrade the problem, I replace wound->vertexArray with vertexArray_1.

for wound->vertexArray_1, I just forgot to remove the “wound->”…~~

I updated the driver of graphics card, now the program has lower probability to crash. But it still crashes.

Actually the problem is, the program dosent crash when I run it. In the program there is a button to let program regenerate vertex and index array and display it again. The program will crash if I click it 4-5 times.

I made a guess:
It seems that, the opengl or something in lower level, that I dont have control upon, is accumulating the vertex array pointer every time I call glVertexPointer.

So, when I run the program at the beginning, the vertex array dosent exceed limit of glDrawElements, so the program dosent crash. And I click the button several times, the accumulated vertex array is too large so that exceeds glDrawElements’ vertex/ index array size limit, thus it crashes.

Is that kind of guess possible…? By the way, the vertex and indices array are fine because I carefully tested them. They are all successfully deallocated and reinitialized when I click the button.

AND! the most strange part is, if I dont render vertex array 2, the vertex array 1 works fine with glDrawElements…

Neither glDrawElements nor glVertexPointer behave like you’ve described unless you’re doing something wrong. Can you confirm that you’re disabling both your color array and your texcoord array before drawing vertex array 1 (or after drawing your other stuff)? If these are shorter than your vertex array 1, and if they’re still enabled, they will overflow during your first glDrawElements.

Problem is solved! As u said, i didnt disable previous texcoord array.
Thanks alot.
Another question is, now i tried to increase vertex array to over 100000, the program dosent crash. But isnt the gldrawelements’s limit is 33000?

There’s no real limit unless you’re using VBOs (in which case there’s still no limit, but there will be a point at which you fall back to software emulation). I’m not sure where your figure of 33000 comes from; the limit for VBOs is entirely hardware dependent.

Got it. Thanks very much