2013-05-03 3 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); 

를 호출하여 해결 : 나 또한 여기에 요청합니다 유래에서 여기에 비슷한 질문을 발견했다. 일반적으로 장면을 색상으로 텍스처로 렌더링하면 함수가 제대로 작동합니다. 그러나, 깊이 값을 렌더링하기 위해 노력 후, 그냥 (모든 장면과 일치하지 않는 무언가) 화이트 색상

Depth values rendering problem

를 렌더링

Render scene into texture (RGBA)

다음은 결과입니다 이제 제대로 작동

---- 업데이트 된 코드 :

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); 

    } 

근무 결과 : 당신은 일반적으로 FBO 및 OpenGL을 사용하는 방법에 대한 읽을 수 있어야합니다

Rendering depth component

+0

깊이 테스트를 사용 설정 했습니까? glEnable (GL_DEPTH_TEST)? – Dirk

+0

예, 깊이 테스트가 사용됩니다. – jay

답변

1

.

코드에서 FBO 및 첨부 파일을 각 프레임에 만듭니다. 그건 틀립니다. 오버 헤드가 큽니다. 초기화시 FBO를 한 번만 구성하십시오. 두 번째로 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