2013-05-03 117 views
0

我想在JOGL 2.0中实现简单的阴影映射技术,并且我很难将深度值渲染到纹理中。也许我做的完全错误,但奇怪的是渲染场景的颜色正常工作。我也发现了类似的问题在这里计算器,这是在这里问:Render the depth buffer into a texture using a frame bufferJOGL 2.0,渲染纹理的深度缓冲区

和问题是通过调用

gl.glDrawBuffer(GL2.GL_NONE); 
gl.glReadBuffer(GL2.GL_NONE); 

然而,这并不在我的情况帮助解决。当我以正常的颜色渲染场景时,功能正常工作。下面是结果:

Render scene into texture (RGBA)

然而,试图呈现深度值之后,它只是呈现白色(以及一些不与场景都对应)

Depth values rendering problem

----更新的代码,这是目前工作正常:

private void initializeFBO3(GL2 gl) { 

//Create frame buffer 
gl.glGenFramebuffers(1, frameBufferID, 0); 
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBufferID[0]); 

// ------------- Depth buffer texture -------------- 
gl.glGenTextures(1,depthBufferID,0); 
gl.glBindTexture(GL2.GL_TEXTURE_2D, depthBufferID[0]); 

gl.glTexImage2D(GL2.GL_TEXTURE_2D,   // target texture type 
     0,         // mipmap LOD level 
     GL2.GL_DEPTH_COMPONENT,   // internal pixel format 
              //GL2.GL_DEPTH_COMPONENT 
     shadowMapWidth,      // width of generated image 
     shadowMapHeight,     // height of generated image 
     0,       // border of image 
     GL2.GL_DEPTH_COMPONENT,  // external pixel format 
     GL2.GL_UNSIGNED_INT,  // datatype for each value 
     null); // buffer to store the texture in memory 

//Some parameters 
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST); 
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST); 
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_EDGE); 
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_EDGE);  


//Attach 2D texture to this FBO 
gl.glFramebufferTexture2D(GL2.GL_FRAMEBUFFER, 
     GL2.GL_DEPTH_ATTACHMENT, 
     GL2.GL_TEXTURE_2D, 
     depthBufferID[0],0); 

gl.glBindTexture(GL2.GL_TEXTURE_2D, 0); 

//Disable color buffer 
//https://stackoverflow.com/questions/12546368/render-the-depth-buffer-into-a-texture-using-a-frame-buffer 
gl.glDrawBuffer(GL2.GL_NONE); 
gl.glReadBuffer(GL2.GL_NONE); 

//Set pixels ((width*2)* (height*2)) 
//It has to have twice the size of shadowmap size 
pixels = GLBuffers.newDirectByteBuffer(shadowMapWidth*shadowMapHeight*4); 

//Set default frame buffer before doing the check 
//http://www.opengl.org/wiki/FBO#Completeness_Rules 
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0); 

int status = gl.glCheckFramebufferStatus(GL2.GL_FRAMEBUFFER); 

// Always check that our framebuffer is ok 
if(gl.glCheckFramebufferStatus(GL2.GL_FRAMEBUFFER) != GL2.GL_FRAMEBUFFER_COMPLETE) 
{ 
    System.err.println("Can not use FBO! Status error:" + status); 
} 
} 

public void display(GLAutoDrawable drawable) { 
    GL2 gl = drawable.getGL().getGL2(); // get the OpenGL graphics context 
    gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); 

    gl.glLoadIdentity(); // reset the model-view matrix 

    //Render scene into Frame buffer first 
    gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBufferID[0]); 
     renderSmallScene(gl); 

    //Read pixels from buffer 
    gl.glBindFramebuffer(GL2.GL_READ_FRAMEBUFFER, frameBufferID[0]); 
    //Read pixels 
    gl.glReadPixels(0, 0, shadowMapWidth, shadowMapHeight, GL2.GL_DEPTH_COMPONENT , GL2.GL_UNSIGNED_BYTE, pixels); 

    //Switch back to default FBO 
    gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0); 
     drawSceneObjects(gl); 


    //Draw pixels, format has to have only one 
    gl.glDrawPixels(shadowMapWidth, shadowMapHeight, GL2.GL_LUMINANCE , GL2.GL_UNSIGNED_BYTE, pixels); 

    } 

工作结果:

Rendering depth component

+0

您是否启用了深度测试? glEnable(GL_DEPTH_TEST)? – Dirk 2013-05-03 07:13:26

+0

是的,深度测试已启用。 – jay 2013-05-05 19:57:07

回答

1

您必须阅读有关一般使用FBO和OpenGL。

在您的代码中,您可以在每个框架中创建FBO及其附件。这是错误的。它的开销很大。在init上构建你的FBO只需要一次。其次,你必须绑定FBO才能绘制它(或从中读取),否则OpenGL会绘制默认的FBO。看一看herehere

所以,一旦你的FBO已经准备好你渲染成这样的:

glBindFrameBuffer((GL_DRAW_FRAMEBUFFER, yourFbo); 

    drawSceneObjects(gl); 

glBindFrameBuffer((GL_READ_FRAMEBUFFER, yourFbo); 

    readPixelsHere() 


glBindFrameBuffer((GL_FRAMEBUFFER, 0);///switch to default FBO 

事实上,在你的情况,你离开绑定的FBO,只需拨打

glBindFrameBuffer((GL_READ_FRAMEBUFFER, yourFbo); 

绘制几何图形后。另外,如果您不使用着色器,则没有理由将纹理作为FBO附件使用。请改为创建渲染缓冲区。

+0

花了我很长时间才回到它。根据你的建议,我已经优化了代码,现在好多了。为了获得深度贴图纹理,我必须克服几个问题。我会更新我的问题并添加一些结论。 – jay 2013-07-05 12:23:50

相关问题