PBO缓冲区内容是什么意思?

时间:2018-08-24 04:18:14

标签: java opengl pbo

我试图通过使用PBO(使用OpenGL的像素缓冲对象)来实现颜色选择系统,当我完成时,我意识到映射时从PBO出来的数字根本没有任何意义。我让我的应用程序渲染了不同颜色的大方块,结果 DID 在这些不同颜色之间发生了变化,但是即使在分析了数字之后,我也仍然无法理解。

例如,单击纯红色可得到 (-1,0,0),而纯蓝色给出了(-1,0,-1),但在所有逻辑上,纯绿色给出了(-1,0,-1),青色也给出了(-1,0,0 ),黄色则为(76,-1,0)。

显然,这些数字是错误的,因为两种不同的颜色可以导致相同的字节格式。全红色不应该是(127,0,0)吗?

这是我用于初始化的代码,大小为3,因为我只读取一个像素。

conda config --add channels conda-forge 
conda update pip

这是我用来读取像素的代码

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

如果我做的任何假设都不对,请纠正我。我打算使用此系统,通过将每个gui元素渲染到具有唯一颜色的fbo并测试单击哪个像素颜色来判断正在单击哪个gui元素。预先感谢任何可以提供帮助的人!

2 个答案:

答案 0 :(得分:1)

终于我终于找到了问题!

首先,使用Byte.toUnsignedInt(byte),您可以将pbo给您的颜色转换为传统的0-255范围内的rgb数字。

第二,这是主要问题,当OpenGL要求像素坐标填充pbo时,它相对于右下角。我的问题是我使用的是GLFW,它给出相对于右上角的坐标,这意味着在屏幕垂直中间的颜色选择是准确的,但是当我在其他地方进行颜色选择时,它正在获取我正在寻找的屏幕的反面部分。要解决此问题,只需从窗口高度中减去鼠标单击的y坐标即可。

感谢您的帮助和想法!

答案 1 :(得分:0)

有两种可能,但是我没有设置我的openGL系统进行测试-但是您可以尝试任何一种方法。我也不太了解Java(我的领域是C,C ++等)

编辑

1)您已从GL_UNSIGNED_BYTE中请求glReadPixels()数据,但是您正在以签名格式打印。 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

我希望所有这些都对您有所帮助,尽管对我们俩来说,这都是一种相似的学习经历。