2013-05-03 157 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

相關問題