2016-01-13 245 views
0

我在Java中使用LWJGL,它具有與C++ OpenGL相同的函數名稱。請注意,我不得不使用OpenGL的「舊」固定功能管線。OpenGL:讀取幀緩衝區的深度紋理

//the initialization method 
public void init(int width, int height) { 
    //initializing the PBO 
    pbo_id = glGenBuffers(); 
    // [...] 

    //initializing the Framebuffer 
    framebufferObject = glGenFramebuffers(); 
    framebufferTexture = glGenTextures(); 

    depthBuffer = glGenRenderbuffers(); 

    framebufferFilter = GL_NEAREST; 

    glBindTexture(GL_TEXTURE_2D, framebufferTexture); 

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 
    glTexParameterf(GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL_CLAMP); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer)null); 
    glBindFramebuffer(GL_FRAMEBUFFER, framebufferObject); 
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebufferTexture, 0); 

    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height); 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer); 

    glBindTexture(GL_TEXTURE_2D, 0); 
} 

//this is called after the world was rendered to the framebuffer 
public void capture() { 
    //binding the PBO 
    glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id); 

    //binding the Framebuffer's texture 
    glBindTexture(GL_TEXTURE_2D, framebuffer_id); 

    //storing the Framebuffer's contents in the PBO 
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 

    //unbinding the Framebuffer 
    glBindTexture(GL_TEXTURE_2D, 0); 

    //unbinding the PBO 
    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); 
} 

我怎麼會深度圖的內容(我想被初始化爲深度緩存)存儲在:

我目前正在成功地使用下面的代碼繪製幀緩衝區的RGB內容PixelBufferObjects PBO而不是「主」幀緩衝區內容?

UPDATE: 這是我使用的閱讀深度圖的內容,現在PBO該代碼:

public void captureDepthMap() { 
    //binding the PBO 
    glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id); 

    glPixelStorei(GL_PACK_ALIGNMENT, 1); 
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 

    //binding the FBO 
    glBindFramebuffer(GL_FRAMEBUFFER, framebufferObject); 

    //storing the Depth Map's contents in the PBO 
    glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8, 0); 

    //unbinding the FBO 
    glBindFramebuffer(GL_FRAMEBUFFER, 0); 

    //unbinding the PBO 
    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); 
} 

產生的圖像僅僅是黑色的但是。 這可能是什麼原因造成的?我可能搞砸了一些GL格式嗎?

+0

使用深度紋理附件而不是渲染緩衝區,並且從不使用像33190這樣的幻數。我不知道常量是什麼,我也不打算查看它。 –

+0

@ AndonM.Coleman我用GL_DEPTH_COMPONENT24代替了它的幻數,它與此類似。 – CrushedPixel

+0

從幀緩衝區檢索數據的規範方法是'glReadPixels'。使用像素包緩衝區PBO綁定的方式將空指針傳遞給數據參數將使其與PBO異步讀取。另請注意,glGetTexImage僅在(桌面)OpenGL中受支持,但在ES配置文件中並不支持WebGL。所以爲了前向兼容性,你不應該使用glGetTexImage – datenwolf

回答

1

綁定「framebuffer的紋理」並沒有什麼意義。此紋理僅表示一個(顏色緩衝區)附件。您可以將多個紋理附加到幀緩衝區,深度緩衝區也可以作爲紋理進行存儲。

如果您使用深度紋理附件而不是渲染緩衝區,則可以按照讀取顏色附件的相同方式進行讀取。唯一的區別是格式和數據類型:GL_DEPTH_COMPONENTGL_UNSIGNED_INT_24_8

或者,您可以使用glReadPixels (...)從附加的渲染緩衝區讀取。由於您必須指定一個矩形才能讀取,因此API涉及更多一點。

+0

這就是我目前使用'glReadPixels'從framebuffer的紋理讀取:'glReadPixels(0,0,getFrameWidth(),getFrameHeight(),GL_RGB,GL_UNSIGNED_BYTE,0) ;',我將如何去閱讀Renderbuffer?我會如何將其綁定? – CrushedPixel

+0

@CrushedPixel:只要將它附加到Frambuffer對象上,就可以「綁定」渲染緩衝區。幀緩衝區只能有一個深度附件,所以你不需要做任何事情。當您調用'glReadPixels(...)'時,只需使用FBO即可,並使用正確的格式和數據類型。我上面給出的例子是一個32位打包數據類型,它是如何在GPU上本地存儲24位深度緩衝區(其餘的8位是未使用的填充或模板緩衝區),所以它應該轉換爲從渲染緩衝區直接複製到沒有數據轉換的pixelbuffer。 –

+0

謝謝。我更新了我的帖子,根據您的建議顯示了我的當前代碼,但是結果渲染看起來不正確。 – CrushedPixel