Sign in to follow this  
Hydrael

Destroyed glDrawElements Index Arrays

Recommended Posts

Hello everyone, I have a very confusing problem regarding the index array of glDrawElements. The project I'm working on, is a world editor, which imports heightmaps - therefore I have a huge polygon count (50.000 to 3.000.000, depending on size) stored in a Vertex Buffer. You probably can imagine, that performance ain't all too good, when trying to render the whole thing at once. So I implemented frustum culling and checked every polygon for visibility. Things got better, but due to the high polygon count, checking every poly if it is within the frustum or not also takes way too much time. So I had to reduce the amount of visibility checks. That's why I came up with the idea to subdivide my world into logical units (with every LU being 4096 polys). Those logical units I generate using an array of unsigned ints, each representing an element within my vertex buffer (LUPointer). That's the index array I use for glDrawElements. To make things easier, I created another array with each element pointing to the first element of a logical unit within LUPointer. I hope it is understandable. Now, let's come up to my problem: Rendering the world works perfectly with really good performance. But when trying to include the logical unit algorithm in my picking routine, the index array (LUPointer) is being destroyed for some reason I just can't understand. Down below is the critical piece of code. When coming to glLoadName, the program alwys crashes at i=1704 and the debugger shows, that LUPointer has the adress 0x00000ca2. I just don't get it, why it does that. I don't do anything else with LUPointer than reading its values throughout the whole program (except for the initialization routine of course) The small loop in the beginning of the code snippet I included to see if element 1704 is ok before going into the real code - and it is.
for(int x=0;x<BufferCount;x++)
{
	if(x==1704)
		GLuint z=LUPointer[x];
}
if(LU)
{
	for(int x=0;x<LUCount*LUCount;x++)
	{
		if(Frustum->SphereInFrustum(LUMid[x].GetX(),LUMid[x].GetY(),LUMid[x].GetZ(),LURadius))
		{
			size=LUSpecificSize[x];
			from=LUArray[x];
			for(GLuint i=0;i<size;i+=6)
			{
				glLoadName(LUPointer[from+i]/6);
			        glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,&LUPointer[from+i]);
			}
		}
	}
}


Any help would be really appreciated - I'm working on this error for days now and I just don't get it. Thanks in advance Chris

Share this post


Link to post
Share on other sites
size probably isn't divisible by 6 so the condition i < size is still true but you don't have 6 elements left for drawing, so you have a buffer overflow :)

you should also do
glDrawElements(GL_TRIANGLES,size,GL_UNSIGNED_INT,&LUPointer[from])
instead of the for loop. It is way more efficient.

Share this post


Link to post
Share on other sites
That's what I also thought first.
But size is way larger than 1704 elements (64*64*6 in fact), and since I always increment i by 6, it should always be dividable by 6.
Drawing the elements without a for loop, I do when rendering the actual scene (in which case I don't have any problems at all).
The code I posted is used to find out, which element my mouse is floating over (glLoadName). That code is being rendered to the selection buffer, and not to the screen. I can't think of any other way to do that :/

Today I was taking apart my code piece by piece and still didn'f find out, what causes the program to crash - very frustrating :(

But thanks a lot for the response.

Chris

Share this post


Link to post
Share on other sites
I just found following line in the glDrawElements specs:

Vertex attributes that are modified by glDrawElements have an unspecified value after glDrawElements returns. For example, if GL_COLOR_ARRAY is enabled, the value of the current color is undefined after glDrawElements executes. Attributes that aren't modified remain unchanged.

Could it maybe have something to do with that?

[Edited by - Hydrael on June 24, 2005 12:00:50 AM]

Share this post


Link to post
Share on other sites
I don't think so. post some more contex I don't see anything else in your code that could be cousing this.

Share this post


Link to post
Share on other sites
I can't imagine, that the problem lies somewhere else.

For example: Elsewhere in the program i call this method:

void COpenGLWindow::DrawVertexBufferSolid(CFrustum *Frustum)
{
GLuint size=0;
GLuint from=0;
glEnableClientState( GL_VERTEX_ARRAY ); // Disable Vertex Arrays
glEnableClientState( GL_COLOR_ARRAY ); // Disable Texture Coord Arrays
glVertexPointer( 3, GL_FLOAT, 0, VertexBuffer);
glColorPointer(3,GL_FLOAT,0,ColorBuffer);
if(LU)
{
for(int x=0;x<LUCount*LUCount;x++)
{
size=LUSpecificSize[x];
from=LUArray[x];
if(Frustum->SphereInFrustum(LUMid[x].GetX(),LUMid[x].GetY(),LUMid[x].GetZ(),LURadius))
glDrawElements(GL_TRIANGLES,size,GL_UNSIGNED_INT,&LUPointer[from]);
}
}
glDisableClientState( GL_COLOR_ARRAY ); // Disable Texture Coord Arrays
glDisableClientState( GL_VERTEX_ARRAY ); // Disable Vertex Arrays

}



This one I use to render the scene to the screen and it works perfectly.

Back in the previous posted code, I even tried this:

.
.
.
for(GLuint i=0;i<size;i+=6)
{
/* glLoadName(LUPointer[from+i]/6);*/
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,&LUPointer[from+i]);
}
.
.
.



I still messes up - always when i=1704. Somehow glDrawElements causes itself to crash by corrupting its index array.
This drives me nuts :/

Share this post


Link to post
Share on other sites
Either you have an index in the array that is bigger than your vertex array or
from+i+5
is bigger than your index arrays size (which it probably isn't since the drawing is done ok). I don't see any other possibility.

With contex I meant the initialasation code :)

Share this post


Link to post
Share on other sites
Oh my god, that's so embarrassing.
Within the inner for-loop was this statement

VisibleUnderMouse[a++]=LUPointer[from+i];





which I didn't post, because I thought it is not relevant and might confuse.
Well - in fact it was exactly this statement screwing everything up because I just copy/pasted it from elsewhere and forgot to increase the array size for VisibleUnderMouse - it simply was too small, so it overwrote LUPointer.

Please excuse me for wasting your time while I go study "C++ for dummies" once again ;)
And thanks for the help of course.

Just in case of interest, here is the initialization routine:

for(int LUy=0;LUy<LUCount;LUy++)
{
for(int LUx=0;LUx<LUCount;LUx++)
{
for(int y=0;y<LUSize;y++)
{
for(int x=0;x<LUSize*6;x++)
{
LUPointer[i]=((LUy*LUSize)*(Elemsx*6))+((LUx*(LUSize*6))+x)+(y*(Elemsx*6));

}
}
}
}


Share this post


Link to post
Share on other sites
We all get stuck some time with something stupid.

Btw. If you are drawing the triangles like this

____
|\ |
| \|
----


You should consider using quads. It is 4 verticles vs. 6.

Share this post


Link to post
Share on other sites
Hmm...you are right about the quads. I'll keep that in mind and implement it, as soon as I have fixed my other bugs ;)

Thanks

Share this post


Link to post
Share on other sites
actually you should use a triangle-strip instead - same amount of verts, but unlike quads tri-strips are supported nativly on hardware (and you get a serious speed boost while using them), while quads require your graphics card to turn it into 2 triangles before rendering.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this