簡體   English   中英

PBO緩沖區內容是什么意思?

[英]What does the PBO buffer content mean?

我試圖通過使用PBO(使用OpenGL的像素緩沖對象)來實現顏色選擇系統,當我完成時,我意識到映射時從PBO出來的數字根本沒有任何意義。 我讓我的應用程序渲染了不同顏色的大方塊,並且結果DID在這些不同顏色之間發生了變化,但是即使在分析了數字之后,我也仍然無法理解。

例如,單擊純紅色給出的字節為(-1,0,0),而純藍色給出的字節為(0,0,-1),但是在所有邏輯上,純綠色給出的字節為(-1,0,-1) ,青色也給出(-1,0,0),黃色給出(76,-1,0)。

鑒於兩種不同的顏色可以導致相同的字節格式,因此這些數字顯然是錯誤的。 全紅色不應該是(127,0,0)嗎?

這是我用於初始化的代碼,大小為3,因為我只讀取一個像素。

pboid = glGenBuffersARB(); //Initialize buffer for pbo
glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pboid); //bind buffer
glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, 3,GL_DYNAMIC_READ); //create a pbo with 3 slots
glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); //unbind buffer

這是我用來讀取像素的代碼

glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pboid); //Bind the pbo
glReadPixels((int)lastMousePosition.x,(int)lastMousePosition.y,1,1, GL_RGB, GL_UNSIGNED_BYTE, 0); //Read 1 pixel
ByteBuffer colorBuffer = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY_ARB); //Map the buffer so we can read it
for(int x = 0; x < colorBuffer.limit(); x++)
{
    System.out.println("color byte: " + colorBuffer.get(x)); //Print out the color byte
}
glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT); //Unmap the buffer so it can be used again
glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); //Unbind the pbo

如果我做的任何假設都不對,請糾正我。 我打算使用此系統,通過將每個gui元素渲染到具有唯一顏色的fbo並測試單擊哪個像素顏色來判斷正在單擊哪個gui元素。 預先感謝任何可以提供幫助的人!

終於,我終於找到了問題!

首先,使用Byte.toUnsignedInt(byte),您可以將pbo給您的顏色變成傳統的0-255范圍內的rgb數字。

其次,這是主要問題,當OpenGL要求像素坐標填充pbo時,它相對於右下角。 我的問題是我使用的是GLFW,它給出相對於右上角的坐標,這意味着在屏幕垂直中間的顏色選擇是准確的,但是當我在其他地方進行顏色選擇時,它正在獲取我正在尋找的屏幕的反面部分。 要解決此問題,只需從窗口高度中減去鼠標單擊的y坐標即可。

感謝您的幫助和想法!

有兩種可能,但是我沒有設置我的openGL系統進行測試-但是您可以嘗試任何一種方法。 我也不太了解Java(我的領域是C,C ++等)

編輯

1)您已經從glReadPixels()請求GL_UNSIGNED_BYTE數據,但是您正在以簽名格式進行打印。 GL_UNSIGNED_BYTE值為0-256,因此不可能使用負值! 嘗試格式化打印輸出的UNSIGNED_BYTE然后查看結果。 (從您的代碼中,我現在可以看到此問題已解決)。

2)正如derhass在他的評論中所指出的那樣,您不應使用OpenGL緩沖區功能的ARB(體系結構審查委員會)擴展版本,因為它們是OpenGL核心的一部分,已有相當長的時間了。 有關版本歷史記錄,請參見https://www.khronos.org/opengl/wiki/History_of_OpenGL 由此可見,例如glBindBufferARB(例如)在2003年已棄用。它可能會或不會影響您的特定問題,但是請使用glXXXXX()替換glXXXXXARB(),並確保您的OpenGL庫是最新的(v4或更高版本)。

3)同樣感謝derhass,並讀取您的GitHub代碼,通過glfwGetCursorPos的getMousePosition()返回屏幕坐標(窗口的左上角為0,0),因此您需要轉換為視口坐標(窗口的左下角為0,0)才能讀取幀緩沖區。 您在GitHub上的代碼似乎沒有進行轉換。

4)另外,由於無需信用證明,您完全不需要使用PBO進行基本的顏色選擇。 glReadPixels()的默認目標是幀緩沖區,因此您可以安全地省去VBO,直接從幀緩沖區獲取顏色,深度和模板數據。 (您需要啟用深度和模板緩沖區)。

5)如果要在3D場景中進行選擇,則還需要將視口坐標和深度轉換(取消投影)為世界坐標,以便能夠識別單擊的對象。 有關選擇的一些想法,請參見https://en.wikibooks.org/wiki/OpenGL_Programming/Object_selection

我希望所有這些都對您有所幫助,盡管對我們倆來說,這都是一種相似的學習經歷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM