OpenGL Render Target Issue


#1

I’m trying to render a model into a render target then show it with a 2d quad on the screen, however I’m seeing something strange, the model seems to be inside-out! look at the image below. The perspective is correct, I have tested CW and CCW winding, and numerous other GL states, but still things look inside out.


http://imageshack.us/photo/my-images/585/screenshot1zr.jpg

code for void renderOpenGL() callback

[code]OpenGLHelpers::clear (Colours::black.withAlpha (1.0f));

    glEnable (GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable (GL_TEXTURE_2D);
	glShadeModel(GL_SMOOTH);		 // Enables Smooth Shading
	glClearDepth(1.0f);				// Depth Buffer Setup
	glEnable(GL_DEPTH_TEST);		// Enables Depth Testing
	glDepthFunc(GL_LESS);			// The Type Of Depth Test To Do
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculation
	glDisable(GL_LIGHTING);
	
	 //========================================================================================================================
	 //Setup Render Target 1
	
	 OpenGLFrameBuffer* RT1 = OpenGLImageType::getFrameBufferFrom (renderTarget1);//renderTarget1 is created in newOpenGLContextCreated()
	 RT1->makeCurrentAndClear();

	 OpenGLHelpers::prepareFor2D (getWidth(), getHeight());
     OpenGLHelpers::setPerspective ((double)CAMERA_FOVX, getWidth() / (double) getHeight(), (double)CAMERA_ZNEAR, (double)CAMERA_ZFAR);

	 //Draw To The Render Target 1
	
	 OpenGLFrameBuffer* tex1 = OpenGLImageType::getFrameBufferFrom (logoImage);
	
	 glTranslatef (0.0f, 0.0f, -2.0f);

	 tex1->draw3D (-1.0f,  1.0f,  1.0f, -1.0f, -1.0f,  1.0f,  1.0f, -1.0f,  1.0f,  1.0f,  1.0f,  1.0f, Colours::white);
     tex1->draw3D (-1.0f,  1.0f, -1.0f,  1.0f,  1.0f, -1.0f,  1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, Colours::white);
     tex1->draw3D (-1.0f, -1.0f, -1.0f,  1.0f, -1.0f, -1.0f,  1.0f, -1.0f,  1.0f, -1.0f, -1.0f,  1.0f, Colours::white);
	
	 //-----------------------
	 //Release Render Target
	 //-----------------------
	 RT1->releaseAsRenderingTarget();
	 //========================================================================================================================
	

    OpenGLHelpers::prepareFor2D (getWidth(), getHeight());
    OpenGLHelpers::setPerspective ((double)CAMERA_FOVX, getWidth() / (double) getHeight(), (double)CAMERA_ZNEAR, (double)CAMERA_ZFAR);

	//=======================================================================================================
	//DRAW A QUAD
	//=======================================================================================================
	glTranslatef (0.0f, 0.0f, -0.645f);
	RT1->draw2D(-1,-1,1,-1,1,1,-1,1,Colours::white);[/code]

Im suspecting something wrong with makeCurrentAndClear();

Any Ideas how to just draw 3d stuff into a render target properly, thanks in advance…


#2

I think you need a z-buffer.


#3

I thought so, for depth-testing, so how can I do that? OpenGLFrameBuffer, does that not already have a depth buffer, if not how do I add it, thanks again…


#4

How can I create a OpenGLFrameBuffer that has a z-buffer with juce? I’ve looked around but still cannot figure this out, must be a trivial solution… Code sample would be appreciated. Cheers


#5

The OpenGLPixelFormat defines the depth buffer. But TBH I think a z-buffer is enabled by default, so it could be something else in your GL code that’s wrong.


#6

I was hoping if anyone else has been able to render into a openGLframebuffer? Can someone please test this…

in void newOpenGLContextCreated() Allocate the rendertarget texture

in void renderOpenGL()

[code]glEnable(GL_DEPTH_TEST);
OpenGLFrameBuffer* RT1 = OpenGLImageType::getFrameBufferFrom (renderTarget1);//RT1
RT1->makeCurrentAndClear();
OpenGLHelpers::prepareFor2D (getWidth(), getHeight());
OpenGLHelpers::setPerspective ((double)CAMERA_FOVX, getWidth() / (double) getHeight(), (double)CAMERA_ZNEAR, (double)CAMERA_ZFAR);
//---------------------------
//Draw The 3d Model
//---------------------------
RT1->releaseAsRenderingTarget();

//---------------------------
//Now Draw The 2D Quad
//---------------------------
OpenGLHelpers::prepareFor2D (getWidth(), getHeight());
OpenGLHelpers::setPerspective ((double)CAMERA_FOVX, getWidth() / (double) getHeight(), (double)CAMERA_ZNEAR, (double)CAMERA_ZFAR);
glTranslatef (0.0f, 0.0f, -0.645f);
RT1->draw2D(-1,-1,1,-1,1,1,-1,1,Colours::white);[/code]

So, The Above Code Does Draw The Cube into the Render Target and as I mentioned before even the perspective correction is correct, it’s just that things are inside out!! Why? jules, how else am I suppose to use makeCurrentAndClear() in order to get it work. Thanks for any help…


#7

Oh, you’re rendering into a framebuffer… I can’t remember whether I added support for framebuffers with depth buffers or not…


#8

Any tips, or ideas as to how I can maybe add depth-buffer support to framebuffer. Please, please this would be a good feature if you can add it. Cheers…


#9

It looks like you put the code in Jules, in FrameBuffer::Pimpl. But I don’t see any ways for the base class to create the Pimpl with a depth buffer, so you not getting one. The OpenGLFrameBuffer class will have to be extended to know whether to create a depth buffer, then presumably some testing - that’s probably a code path that hasn’t been exercised.

where the first bool says ‘no depth buffer’.

Not sure where that should go, since a FrameBuffer is made from an Image quite often… can/should an image have a depth buffer?

Bruce


#10

Ah yes, it’s in there but just never got plumbed-in. Sorry, too deep in other stuff to put my brain into openGL mode right now, but it doesn’t sound like it’d be too hard to add.


#11

I also have a problem with depth-buffer in a framebuffer.

Does someone have a solution ?

Thanks.

Eliott.


#12

I have a custom openGL engine that I´ve been testing using SDL as well as VSTGUI (so I can render software elements on top of OpenGL) but have now switched to JUCE.

I'm rendering offscreen on an multisample FBO, blitting the multisampled result to another FBO, and then binding that FBO as texture and to render to a third FBO for postprocessing. Lastly I then blit the to system (0) before the swapBuffers call.

The FBOs im using are all using depth and stencil buffers and the system as I said work in SDL and VSTGUI but not in JUCE.

The problem is that the depth information seems to be completely missing and objects i render are visible based on order they are rendered rather than on depth. Also any JUCE buttons I draw on top are either missing until i hover them or they look broken.

I´ve matched the pixelFormat in JUCE with what im using in SDL and also the other way around in case the pixelFormat in JUCE has to be what it originally was and then created the FBOs with the same depth/stencil bits to ensure compatibility. 

I´ve tried reading up on the JUCE openGL code to see if there is anything strange going on or if im just using it wrong but i´ve failed to see anything so far.

Note: I am not using any JUCE openGL functionality at all except for the render() override function and JUCEs context creation since I want it to be "GUI-independant" in case we decide to not go with JUCE as a final solution. 

 

Edit: This is how I create my FBOs, the "depthBufferBits" will be set to GL_DEPTH24_STENCIL8 which as far as i can tell also JUCE uses.


// Create the FBO
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
OpenGL_ErrorCheck();
// Rendering color information
if(colorFlag != OGL_FBOBUFFER_COLOR_OFF)
{        
    // Render color to a texture
    if(colorFlag == OGL_FBOBUFFER_COLORTEXTURE)
    {
        // Generate texture
        glGenTextures( 1, &colorTex );
        glBindTexture( GL_TEXTURE_2D, colorTex );    
        // Configure it
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );    
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL );            
        glBindTexture( GL_TEXTURE_2D, 0 );
        // Attach it to the FBO
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
        OpenGL_ErrorCheck();
    }
    // Render to a buffer instead of texture
    else 
    {
        // Generate buffer
        glGenRenderbuffers(1, &colorBuf);
        glBindRenderbuffer(GL_RENDERBUFFER, colorBuf);
        // Init buffer
        if(colorFlag == OGL_FBOBUFFER_COLOR_ON_MULTISAMPLE)
            glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaaSamples, GL_RGBA, width, height);    
        else
            glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA, width, height);
        glBindRenderbuffer( GL_RENDERBUFFER, 0 );
        // Attach it to the FBO
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuf);
        OpenGL_ErrorCheck();
    }
}
if(depthFlag != OGL_FBOBUFFER_DEPTH_OFF)
{
    // Generate depth buffer
    glGenRenderbuffers(1, &depthBuf);
    glBindRenderbuffer(GL_RENDERBUFFER, depthBuf);
    // Configure it
    if(depthFlag == OGL_FBOBUFFER_DEPTH_ON_MULTISAMPLE)
        glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaaSamples, depthBufferBits, width, height);
    else
        glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, depthBufferBits, width, height);
    glBindRenderbuffer( GL_RENDERBUFFER, 0 );
    // Attach it
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuf);
    if(stencilFlag == OGL_FBOBUFFER_STENCIL_ON)
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthBuf);            
    OpenGL_ErrorCheck();
}
// Unbind the FBO
glBindFramebuffer( GL_FRAMEBUFFER, 0 );    
OpenGL_ErrorCheck();

And this is how I blit the results between FBOs / system framebuffer


GLuint flags;
    if(bufferColorFlag != OGL_FBOBUFFER_COLOR_OFF)
        flags = GL_COLOR_BUFFER_BIT;
    if(bufferDepthFlag != OGL_FBOBUFFER_DEPTH_OFF)
        flags |= GL_DEPTH_BUFFER_BIT;
    if(bufferStencilFlag != OGL_FBOBUFFER_STENCIL_OFF)
        flags |= GL_STENCIL_BUFFER_BIT;
    // Make sure no other FBO is bound.
    glBindFramebuffer( GL_FRAMEBUFFER, 0 );
    // Bind this FBO for reading
    glBindFramebuffer( GL_READ_FRAMEBUFFER, fbo );
    OpenGL_ErrorCheck();
    // Bind the other FBO (or system) for drawing
    if(otherFBO)
        glBindFramebuffer( GL_DRAW_FRAMEBUFFER, otherFBO->GetFBOHandle());
    else
        glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0);    
    OpenGL_ErrorCheck();
    
    // Copy over the selected information    
    glBlitFramebuffer( 0, 0, width, height, 0, 0, width, height, flags, GL_NEAREST );
    OpenGL_ErrorCheck();
    // Reset read and draw buffer.
    glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 );
    glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 );
    OpenGL_ErrorCheck();

Does anyone have some idea that comes to mind?

 

Edit2: If I render straight to the current openGL context and skipping my FBO voodoo, the depth seems to be working for the scene, however, what I do inside the paint(...) event still looks weird, as well as the buttons looking weird.

Cannot link pic or add as an attachment hmm.

Edit3: I managed to solve it, I had to completely disable everything depth related after being done rendering. So these calls at the very end of the render(..) function did the trick so now everything works as intended with the FBOs and everything :)


    glDisable(GL_CULL_FACE);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_DEPTH_CLAMP);