Two FBOs inside eachother.

Started by szoltomi, August 17, 2011, 18:11:03

Previous topic - Next topic

szoltomi

Hello!
Is it possible to do the following:

I draw some objects into a texture-bound FBO (let's call it 'A').
Then I draw texture 'A' into another texture-bound FBO ('B') with some other objects.
Finally I draw texture 'B' to the screen.

I already written the code for this, but instead of the texture of 'A', I only get a white, empty texture. I don't know wether this is a limitation of FBOs, or I did something wrong.
When I draw them separately the rendering happens correctly.

And the reason I do this: I am too much used to the top-left origin of the coordinate system, however, when I use FBOs, a flipped ortographics projection caused strange behaviour in the modelview translation of the FBO texture. using a second FBO for flipping everything seems the simplest fix for it. No, glScale(1,-1,1) didn't work.

CodeBunny

This is wasteful and backwards. Simply fix how you set up your orthogonal projection in your first FBO. No need to use two entirely separate FBOs to do something that you can achieve by making correct calls.

szoltomi

Quote from: CodeBunny on August 17, 2011, 19:23:05
This is wasteful and backwards. Simply fix how you set up your orthogonal projection in your first FBO. No need to use two entirely separate FBOs to do something that you can achieve by making correct calls.

That would only work for the first FBO. I have the UI outside of it, and it will still end up flipped.

Do you know how does modelview transformation work when using FBOs in a flipped ortographic projection though? Sadly I can't give a much better answer than things are not where they are supposed to be, and it's somehow related to the screen and the viewport's size.

szoltomi

I found the problem, bah.

I forgot to bind the texture before binding the FBO when I render into it.

Also, wasteful or not, I'll make it work first, then I'll make it efficient.

CodeBunny

While I agree with the classic "premature optimization is the root of all evil," there's a difference between premature optimization and simply making correct design decisions. From the way you described your problem it sounded like you came up with the double-FBO setup simply to fix a bug with your orthogonal settings. With that understanding in mind, and since I know that it's perfectly possible to have correct orthogonal settings when working with FBOs, my recommendation was to simply fix your code. You would end up with a much faster, much more efficient, far more sensible result.

However, at the end of the day it's what works that matters. So, if you fixed it, good job.

szoltomi

I too would like to find out what that bug is exactly, so I could fix that. I needed a solution fast though, so I could work on other stuff efficiently, that's why I used this workaround, but it also bugged me wether nested FBOs can work, since they might needed to be used elsewhere.

Do you know how should I handle the viewport and ortographic projection correcty in an FBO with different size than the screen? I belive this is where I do something wrong.

CodeBunny

First, you should put up your FBO/ortho code.

szoltomi

Sorry for the delay, I was busy with some work and didn't have time/mood to code.

I decided to not prune the code, since it usually causes more trouble than it helps. Here are my drawing methods (It's broken into two classes for my comfort):

DrawerMethods
DMinerDrawer
(pastebin)

CodeBunny

I'm a little confused by your code. Could you separate out your FBO calls from everything else (which is really a good readability decision in general) and paste that? Also, small comments (simply saying what each method is supposed to do and why) would be a big help.

szoltomi

It's 4 AM here, but I'm anticipating fixing this, so I decided to prune, comment out and post the code now. I hope I didn't make any silly mistakes.

DMinerDrawer
DrawerMethods

DMinerDrawer contains the outer "logic" of the renderer.
init() is called before the start of the draw loop.
drawEverything() is  called once in every draw tick.
drawWorldToTexture() and drawFBOTextureToWindow() are explained in the code.

DrawerMethods contains basic OpenGL methods and sprite drawing. Maybe I'll separate the basic openGL stuff from the sprites once I'm finished with the renderer.

initDraw() initializes the window and the OpenGL state machine.
initFBOTexture creates a texture bound FBO.
bindFBO and unBindFBO are quite self-explainatory.
below these are some small methods for easier use of OpenGL calls, each a few line of code at most.


Thanks for the time and effort you spend helping!