PDA

View Full Version : ? Display Lists and glColor causes slow down ?



Z-Knight
09-27-2011, 07:44 PM
I'm having a curious slowdown when creating a display list that makes no sense to me. The slowdown is quite noticeable and I was able to narrow it down to something rather silly and has me stumped.

I am rendering a 3DS model that is made of up multiple groups of triangles and I create a display list in the following manner for each model.



void createDisplaList() {
create new display list

glNewList(list, GL_COMPILE);
for (i=0; i<numGroups; i++) {
glColor3d(1.0, 1.0, 1.0); // OFFENDING CALL...CAUSES SLOWDOWN
// using this 'glDisable(GL_TEXTURE_2D)'
// instead also causes slowdown

glBegin(GL.GL_TRIANGLES);
for (j=0; j<numTrianglesInGroup[i]; j++) {
glNormal3f(...);
glVertex3f(...);
glVertex3f(...);
glVertex3f(...);
}
glEnd();
}
glEndList();
}


When I call this code I output some messages and I notice it takes a long time to create the display list. So I took out the glColor3d() call and the code progressed super fast. The models all draw fine in the end in both cases, but I can't figure out why the glColor3d() call would cause such a slowdown during the list creation.

Even if I take out the glColor3d() call and replace it with just a glDisable(GL_TEXTURE_2D) I still get that slowdown occurring...so, my thread title is probably misleading.

What foolish thing am I missing?....I just tried moving the glColor3d() call inside of my glBegin()/glEnd() block and it worked fast as I would expect. Now I know there is some kind of fundamental OpenGL concept that I'm missing and I would appreciate any insight from some experts. Thank you in advance.

ZeppelinDestruction
09-27-2011, 11:59 PM
Have you tried putting the glColor3d call outside the loop? You only need to call it once for it to be the active colour.

mhagain
09-28-2011, 02:05 AM
This may sound bizarre, but have you tried glColor3f instead? There's no point whatsoever in using doubles as most current consumer hardware doesn't support them (or doesn't have great support for them) internally; trying to store a double in a display list might be punting you back to some kind of emulation mode, or otherwise causing it to choke.

Dark Photon
09-28-2011, 04:16 AM
Also, you can bump your glBegin outside of both loops just inside the glNewList. No reason to break a batch; more likely that you will get one batch in the display list.

Z-Knight
09-28-2011, 07:44 AM
The example I gave was rather simplified to make my point. I need to keep the glColor call inside my loop because I actually have more than a simple color - I have texturing code, etc based on what each group within the 3D model is comprised off. This is why I can't have on big glBegin(GL_TRIANGLES) call because I need to have separate calls for each separate group because it may have a texture or different material associated with just that group.

Note that when I ran my example I commented out all of that texturing code and I truly only did have the one glColor3d() call. I doesn't seem to even matter if it is glColor3d() that is causing the issue because even when I replace it wi th glDisable(GL_TEXTURE_2D) outside of my glBegin(GL_TRIANGLES) block is still causes problems.

And no, these problems are not happening on the rendering - they are only happening on the display list creation. In my testing I've been using a set of 3D models that each have a display list created for them. As I loop over my 3DS models I output a message of when I'm starting/ending my display list creation and when I have the code, as listed above, I notice my messages appear slowly one after the other. When I remove those calls I see those same messages just zip by. I'll put some timing flags to make sure that this is happening inside the loop and not outside - but I don't see how an a call to glColor3d() would have such a negative effect on anything down the line.

Thanks for the suggestions.

Onumis
09-28-2011, 08:01 AM
Maybe you can drop those old deprecated immediate mode openGL calls and replace them with buffer objects and vertex attributes (use GLSL).

+info:
http://www.arcsynthesis.org/gltut/Basics/Tut02%20Vertex%20Attributes.html

Z-Knight
09-28-2011, 08:03 AM
I put in some timing calls to see if can measure the bottleneck and I found NO CHANGE in timing...everything was happening super fast. I believe I have something else in my main code that is being affected by this and so I don't believe my original question is valid.

I'm doing all of this in JOGL (Java + OpenGL) and I have a separate thread that I start to process my model (load it, create the display lists) and in this thread I have my glCallList() calls as well. I wonder if having the glCallList() call being called from this loading thread is somehow being affected by these extra calls outside of the glBegin block. The separate thread was written so that the model pieces get loaded one at a time in the background - but they don't display once they are loaded, instead they seem to display all together at the very end. This implies to me that the glCallList() to render the first piece doesn't do anything until the last piece is loaded...but maybe calling it is causing a slowdown and somehow those extra calls that are in my initial question expose this problem more than normal.

I need to put in some flag that says load the model and create the display lists, but don't actually render anything until the very end.

Sorry for any confusion...thanks for helping me out.

Z-Knight
09-28-2011, 08:06 AM
Maybe you can drop those old deprecated immediate mode openGL calls and replace them with buffer objects and vertex attributes (use GLSL).

+info:
http://www.arcsynthesis.org/gltut/Basics/Tut02%20Vertex%20Attributes.html


I have Vertex Array rendering and VBO rendering coded up as well, but I'm seeing worse performance than using display lists so. Also because of the way that the 3DS model can have multiple textures and multiple materials I wanted to ensure I first render correctly in immediate mode and then optimize my Vertex Arrays/VBOs to render the same.

I believe my Vertex Array/VBO rendering being worse than display lists (but better than just Immediate mode only) are a result of the junk video card I have on my work laptop (nVidia Quadro NVS 140M)...I could also be coding them inefficiently but that is why I want to ensure my display list works correctly first.

Z-Knight
09-28-2011, 02:46 PM
I think the issue I'm getting bit by is something I would not expect. I put in a bunch of timing calls all over the place just see where my bottleneck is occurring.

Before I would render a 3D model I would first do a 'saveState()' call which is basically a function call to save some state variables for me:



public void saveState() {
isTextureEnabled = glIsEnabled(GL_TEXTURE_2D);
isLightingEnabled = glIsEnabled(GL_LIGHTING);
isMaterialEnabled = glIsEnabled(GL_COLOR_MATERIAL);
isCullingEnabled = glIsEnabled(GL_CULL_FACE);
isDepthEnabled = glIsEnabled(GL_DEPTH_TEST);
}


In my rendering I just enabled/disable the various states based on how the object is to be drawn. For example, if part of the object has a texture then I enable the texture and then draw it and for the remaining part I disable the texture again and draw the material,....and so on.

In the end I return all of my states to what they were prior to my rendering...so that the rest of the scene continues to render with the states it would have if the model was never drawn.

Somehow, adding this extra glColor3d() or even glDisable() call is causing one of my glIsEnabled() calls to take a VERY LONG time to complete....but ONLY the first or second time the display list is called - I believe it is just the first time. The offending one is for the texture: glIsEnabled(GL_TEXTURE_2D)....all others are ~0 milliseconds to complete.

Now, I have learned that requesting the status of a state variable can be expensive, also enabling/disabling one can be because OpenGL handles the states in a big SWITCH statement and that can cause issues. It is recommended that you keep track of the states yourself as much as possible and only enable/disable the states if they need to be rather than just repeating an enable/disable call.

Anyway, I don't quite know why this wouldn't be happening all the time and only if I put one of these extra lines in my code...that surprises me a bit and so I will have to do more digging.




=== EDIT ===================================
I'm not sure anything I said above is true...I'm having the weirdest performance issue and my only explanation is that calling a display list the first time is a bit slow. I'm getting a consistent 22 second delay between display calls possibly due to this but I don't actually know.

Please ignore my comments and this thread until I strip out my code to the basics and verify where exactly my problem exists. So frustrating!!!