PDA

View Full Version : Issues mixing textured and non-textured objects



deegee
03-11-2011, 04:12 PM
Hi,

I am writing a CAD-like application.
This application renders mostly colored primitives and objects using fixed mode VBOs and a few DisplayLists.

I need to add a couple of textured objects to the scene, but I ran into issues with the texture state messing up the non-textured object's colors after texturing is disabled.

My code is very clean and well written and I am consistent with making sure that OpenGL states that are enabled get disabled, etc.
I read OpenGL books for hours and googled but I can't find any information on anyone giving examples of mixed rendering like this.

Before the render loop I have initialized OpenGL, loaded textures, set up my objects into VBOs and DisplayLists, etc.
The Textures are set up as:
glGenTextures(num, ids)
glBindTexture(TEXTURE_2D, id)
glTexImage2D(texture_parms)
glTexParameteri(filtering and wrapping)
<repeat same for next id>

The render loop is basically:

- set camera
- set lights

- render textured items:
glEnable(TEXTURE_2D)
glBindTexture(TEXTURE_2D, id)
<render object using texture #id>
glBindTexture(TEXTURE_2D, 0)
glDisable(TEXTURE_2D)

- render DisplayLists of various object types and formats
<render objects>

- render VBO batch of VVVNNNC objects (no textures)
<enable wire/facet/smooth as per user choice>
glEnable(Lighting)
<render batch>
glDisable(Lighting)
<reset wire/facet/smooth>

- render DisplayLists of various object types and formats
<render objects, typically those with blend alpha last>

What is occurring is that all of the VBO and DisplayList objects that are rendered after the textured object(s) are getting their color modulated by the last texture color.
If I change glTexEnvi to GL_REPLACE then of course the object colors get replaced instead so everything goes solid single color.

In my texturing I am not calling any other OpenGL functions other than what is listed above.
The call to glDisable(TEXTURE_2D) is apparently not disabling texturing, or at least not resetting how colors are managed after that.

I have UI buttons that control the rendering of the various groups of objects, and if I stop rendering the textured object and redraw the scene, the issue does not go away, so the call to the Texture2D is setting some OpenGL state that is not getting reset, or my understanding of how OpenGL manages colors in a mixed render scenario is incorrect. :)

I even tried pushing/popping all attribs around the rendering of the textured object and it does the same thing.

Ideas?

Ilian Dinev
03-11-2011, 08:58 PM
The display-lists contain state. Maybe they contain glEnable(gl_texture_2d) ?

I suppose you crosschecked between a radeon and a geforce?

deegee
03-11-2011, 10:32 PM
The DisplayLists contain geometry only (lines or triangles) since they are only scene "helpers" such as grids, each with a glColor call before the rendering of the displaylist, and the VBOs are all I+VVVNNNC array data. No TexCoords, no calls to any texture APIs, no enabling of any texture states.

The only OpenGL texture API calls are in the single class that contains the one object that is being rendered with texturing.
And I made sure that any state I enabled at the start of its render code is disabled at the end.
If that class gets rendered even once then is removed from the render loop, the issue with the changed coloring on the DisplayLists and VBO objects persists and does not go back to normal even if I delete and re-create a DisplayList or VBO object, so the call to the texturing appears to be changing (setting or clearing) some OpenGL state that is changing the rendered colors.
The last texel color rendered from the textured object is the color that all of the DisplayList and VBO objects get tinted to.
It has me really puzzled as I am not doing anything oddball in my code (that I am aware of). :)


Yes, I checked on both ATI and NVidia in case it was a driver issue or bug. Both show the identical issue.

Ilian Dinev
03-11-2011, 11:26 PM
Last 5 ideas:

1) check for glActiveTexture, where the argument != GL_TEXTURE0
2) check for mismatched glEnableClientState(GL_TEXTURE_COORD_ARRAY) and similar

3) even if nothing is mismatched, right before the drawing of DLs and VBOs enforce everything, starting with:

glActiveTexture(GL_TEXTURE0);
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);


4) with GLIntercept or GLSLDevil do a sanity-check of what GL functions your code actually calls and when. There could be a hidden array-overflow somewhere in the project, manifesting this incorrect behaviour.

5) it's a bug, which you can currently only avoid by binding a tiny white 1x1 texture.

_arts_
03-12-2011, 02:43 AM
I think you haven't checked this: simply comment this simple class with texture object. What happend then ?

From the symptoms you said, this is most certainly a texture state that hasn't been removed before. If it's not your code, it might be a bad library you could use for loading images, or loading models.

deegee
03-12-2011, 08:35 AM
* FIXED *

A new day with a fresh look at the code and I found a bug in my code right away.
There was a single line bug in my textured class's Render() function so it was exiting after rendering the object but before it called the glDisable(GL_TEXTURE_2D).
I can't believe that I missed it while looking at the code for hours. This was a noob mistake. :p

Thanks for your help guys and sorry for this being my fault. :)