PDA

View Full Version : OpenGL State weirdness...



scratt
05-15-2008, 08:36 PM
I have put this in the beginner section although I don't consider myself a beginner at CG, but I do have some gaps in knowledge with OpenGL so please forgive if I am doing something stupid... and thanks for reading this through.

I realize that from this general description people cannot immediately put their finger on the problem... What I am hoping for is that someone can point out something that I may be missing. I think I have tried everything, so obviously there is something I have not considered..

I have a vertex array of about 1,000,000 points which in a GLUT Sandbox I have created works perfectly.. It uses quite a complex set of threading, load balancing, and multiple display lists to get this dynamic field of stars to draw very very quickly, and update on a per case basis.

The threading, load balancing, and even point update sections can be turned off and it will revert to simply a set of display lists which will just blat the points from a vertex array into our viewing context.

When I put this into a main loop in my main simulation on the first pass through the loop the points draw perfectly. On subsequent passes through the loop the geometry seems to be off, and I get strange patters of points, often in spherical arrangements, and sometimes nothing at all... This is affected by my viewpoint position and orientation.

So in order I started looking for matrix, attribute, and even shader settings which I may have left on from a previous part of the main loop. I then sequentially commented everything out of the main loop apart from the points plotting. Grrr! No change.

I have no OpenGL errors, and no stack errors, and have even tried drawing these points with a newly created view and model-view matrix which overrides any matrix settings when we enter the point code.

I have tried setting, re-setting and also protecting state variables and so on.. and also checking what Client States I have enabled, and re-disabling anything which might conflict. but nothing seems to solve this problem.

I have read the OpenGL list of common pitfalls about 20 times, and keep thumbing my Red Book looking for what simple thing I must be missing...

It's totally ironic that I have shader driven water and such like coming out of my ears in this sim, and yet on a simple glDrawArrays() I am falling down!

Anyone point me in the direction of something else to research.. After 2 days looking at this on and off I am now considering reworking my entire main app... which seems stupid for such a trivial problem..

Thanks for any help.

CatDog
05-16-2008, 02:32 AM
Providing screenshots of the first and second pass would be a good idea, I think.

*edit*
Some suggestions that come to mind:

1. Right before calling the display lists, use glGet() to read back the current projection and modelview matrices. Check if they are as expected AND if they are the same before every pass.

2. If that doesn't reveal any mistakes, try replacing the display lists by calling glDrawArrays directly. For debugging it's always good to have an immediate render path available, because it may expose defective drivers and you've got the chance to examine the array contents right before they are drawn.

3. Reduce the number of points. Does it work for lower point counts?

CatDog

scratt
05-16-2008, 03:11 AM
Good idea..

Two pictures in my .Mac public folder..

Conveniently labelled.. problem and noproblem!

Pictures (http://idisk.mac.com/scratt-Public?view=web)

Basically in my Sandbox (all the time) and on the first full frame of my main app the stars display correctly.. After that I get bits and bobs of stars, but never really anything resembling my starfield. What points I do get are always without colour.. and quite often the circular pattern illustrated shows up.

Often there is nothing, just my planets and other bits and bobs I am testing with.

As you'll see in the problem shot there are lots of other things, including some point arrays drawn at another point in the main loop all playing nicely together!

CatDog
05-16-2008, 03:25 AM
Uhm. Are you shure you've got the array pointers right?

It looks like your stars are rendered using a planets vertex array! This would explain the circles...

CatDog

scratt
05-16-2008, 03:29 AM
With regards to 1:

If you assume that these points are all projected onto a thin band a long way out from the viewpoint so they have enough differential to give parallax, but are always drawn behind the main scene.. What I have already tried is making a brand new identity matrix, and even a new projection matrix just before I draw the stars. This does not help.

With regards to 2:

I have both an immediate render path and a display list. THe funny thing is that with the immediate render path I don't even get the first pass of stars to draw correctly.

I have not tried suggestion 3.. But will do so.

scratt
05-16-2008, 03:31 AM
Uhm. Are you shure you've got the array pointers right?

It looks like your stars are rendered using a planets vertex array! This would explain the circles...

CatDog

I do agree. And have investigated this. However the array pointers are setup to known addresses just before the call to glDrawArray every time. Both in the display list, and also in the immediate version. I also have a really slooow immediate version which recalculates all of the points and sends them each frame! Obviously the one in the display list cannot change. And even if I remove the planets, and all other draw functions from the main loop I still have similar problems.

Am I perhaps making a really n00bish mistake here.. Is there some way that the pointers for the transfer of points is getting altered before the transfer is complete?!?! I can't see how this is possible, but I may be making some incorrect assumption by flying off to do other stuff immediately after the glDrawArrays() command.

EDIT - btw I really appreciate your input as this is driving me crazy.

CatDog
05-16-2008, 03:41 AM
I bet it's got something to do with the array pointers...

All threading is turned off, so that the data (or GL states) beeing altered by another thread is no possibility, right?


I have both an immediate render path and a display list. THe funny thing is that with the immediate render path I don't even get the first pass of stars to draw correctly.
This is worth thinking about, isn't it? I'd try to fix this first.

Let's see what others suggest...

CatDog

scratt
05-16-2008, 03:52 AM
Yes. Threading is off at the moment.

I have to agree with you that it's the array pointers. That would also explain why the colours are borked too! I just wish I could see why!

Thanks for your input, and yes I'll get the immediate mode fixed first.
The frustrating thing is the reason I have a SandBox is to develop each of these modules separately and independently using classes to protect variables to avoid just this sort of problem! :)

Zengar
05-16-2008, 03:53 AM
The basic course of action is (as CatDog already indirectly suggested) to implement a slow, but simple and working solution first. Meaning, start with immediate mode. If this works, make it faster by using VBOs or display lists. If your rendering algorithm is as complex as you say, the error may be anywhere... and it is difficult to find it without having the code to play with.

-NiCo-
05-16-2008, 03:56 AM
I would like to help out, but the link to your public folder shows up empty in firefox on linux. The only advice I can give you right now is to check whether you used any of the commands listed below that can change behavior between immediate mode and display lists.


Certain commands, when called while compiling a display list, are not com-
piled into the display list but are executed immediately. These commands fall in
several categories including
Display lists: GenLists and DeleteLists.
Render modes: FeedbackBuffer, SelectBuffer, and RenderMode.
Vertex arrays: ClientActiveTexture, ColorPointer, EdgeFlagPointer, Fog-
CoordPointer, IndexPointer, InterleavedArrays, NormalPointer, Secondary-
ColorPointer, TexCoordPointer, VertexAttribPointer, and VertexPointer.
Client state: EnableClientState, DisableClientState, EnableVertexAttrib-
Array, DisableVertexAttribArray, PushClientAttrib, and PopClientAttrib.
Pixels and textures: PixelStore, ReadPixels, GenTextures, DeleteTextures,
and AreTexturesResident.
Occlusion queries: GenQueries and DeleteQueries.
Vertex buffer objects: GenBuffers, DeleteBuffers, BindBuffer, BufferData,
BufferSubData, MapBuffer, and UnmapBuffer.
Program and shader objects: CreateProgram, CreateShader, DeletePro-
gram, DeleteShader, AttachShader, DetachShader, BindAttribLocation,
CompileShader, ShaderSource, LinkProgram, and ValidateProgram.
GL command stream management: Finish and Flush.
Other queries: All query commands whose names begin with Get and Is (see
chapter 6).

scratt
05-16-2008, 04:18 AM
Hmm.. Thanks guys..

I am theorizing now that the vertex array pointers stay setup by chance from the initial creating of the display list so that would explain why I get a "first pass" that draws ok with the display list call. That is done quite early in the programs initialization.

Making a small leap from that.. If I have some other issue that corrupts those pointers then that would also explain why dropping the display list and going to immediate mode may not work at all.. i.e. The array structures I have set up have got corrupt pointers by the time the main loop gets to use them...

Thanks all. I have something to go on.. and will post back for giggles once I sort it out.

Lord crc
05-16-2008, 03:33 PM
I'd implement the draw call myself, using the spec. as basis, and make sure that works. It should allow you go through the code and see what's going on with the pointers and so.

scratt
05-17-2008, 09:09 AM
Just though I'd report back and say thanks for helping me with suggestions...

I still don't know what it was exactly.

I looked at the work it would take me to write a generic version of the draw routine, and the fact that I had always intended to move the whole thing to a Buffer Object system and decided to go the latter route. My hope was that doing that carefully and it being a very different way of drawing the stars, that it would shake out the problem.

Luckily it did, and it paid off in spades too. By load balancing the updating of sets of Buffer Objects I have an effectively 0 CPU load module. And for quite a small GPU memory footprint I have ended up with a 5 fold frame rate increase!

From drawing 100,000 stars at 300 fps I am now able to draw the same number of stars at around 1200 fps. What's more I can do around 1,000,000 stars at close to 200 fps for some reason! Buffer Objects are cool!

I expect that to increase further once I segment groups of stars and do some very rudimentary group frustum culling.

Fun stuff! Thanks again. I hope I can help people out here myself in the future.