I’m a newb to GL and am trying to create a spiffy GL app. My app uses render to texture via FBOs, and I have a C++ object to encapsulate a GL texture, with startRenderTo() and endRenderTo() methods. I do this because it seems there are about 8000 different ways to do RTT in GL, depending on whether it’s multisampled or not, is a format you can render to (e.g. 4 components) or one you can’t directly (e.g. 1 component), needs 6 renders for a cubemap, and so forth. I don’t care about the minutia of the setup, so I just want to say:
tx->startRenderTo();
do_renderings();
tx->endRenderTo();
I have built this, and it works great as long as I don’t nest them. I can RTT and get exactly the result I want no matter if it’s MSAA, cube, or a single component. GLSL shaders are applied and work great. Whee!
But here is my problem: sometimes when rendering to a texture, that in turn needs another RTT so I can use it to render the first. I don’t know this in advance, so I want the following. I can’t easily do the inner ones in a non-nested way since it’s really part of a more complex custom scene graph:
tx0->startRenderTo();
tx1->startRenderTo();
tx1->endRenderTo();
tx2->startRenderTo();
tx2->endRenderTo();
tx3->startRenderTo();
tx3->endRenderTo();
tx4->startRenderTo();
tx4->endRenderTo();
tx0->endRenderTo();
Now I have a problem. In the above sequence, the first several inner RTT’s work OK, but when I get to tx3, the NV driver hangs in glDrawElements(). I’m about 99% sure I’m not doing any of the usual glDrawElement mistakes such as enabling arrays I’m not using or rending more data than I have. I’ve checked this very closely. For debugging I glDisableClientState all but the GL_VERTEX_ARRAY, and I have used the very same vertex array ID for lots of rendering before this such as tx1 and tx2, and I haven’t touched it. Nowhere else in my app enables any draw elements client state - just a single function. I’m pretty sure I’m not overflowing something. Also if I do overflow something on purpose, I see an app segfault, which I don’t here - it just hangs in the NV driver, and takes kill -9 to terminate the app.
I’m actually suspecting something is going wrong in my startRenderTo/endRenderTo methods, although I have no idea what. At the beginning of startRenderTo(), I do this so that I can restore the buffer bindings later:
for (uint32 x=0; x<maxDrawBuffer; ++x) {
GLDBG(glGetIntegerv(GL_DRAW_BUFFER0 + x, (GLint*)(oldDrawBuffer+x)));
// For some reason, GL gives us GL_BACK here but doesn't
// like it when set again in glDrawBuffers
if (oldDrawBuffer[x] == GL_BACK)
oldDrawBuffer[x] = 0;
}
GLDBG(glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, (GLint*)&oldFBId));
GLDBG(glGetIntegerv(GL_RENDERBUFFER_BINDING, (GLint*) &oldRenderBuffer));
Then at the end of endRenderTo():
GLDBG(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, oldFBId));
GLDBG(glDrawBuffers(maxDrawBuffer, oldDrawBuffer));
GLDBG(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, oldRenderBuffer));
Is there some fundamental reason I can’t stop in mid-stream when rendering to some framebuffer, start rendering to a second one, then later bind the first one again and carry on?
Funny thing is that it works for several of the inner RTT’s. Alas I have no indication whatsoever of what might be wrong :-(. I’ve made a lot of mistakes in my use of GL so far but I’ve always been able to figure them out. This one has had me stuck for days now. I don’t even know how to debug it. This is a hobby project so I cannot afford gDebugger. I’m using Ubuntu 64 10.04.
Any ideas would be awesomely appreciated and I’d buy you a beverage of your choice if you were ever in the area if you can think of something I’m overlooking.
I could post the whole of my start/end render to methods, but they’re kind of big by necessity to handle all the different RTT cases.
EDIT There are no glGetError codes set, ever - I check them at every single gl call, which is what my GLDBG macro above does.