【发布时间】:2019-01-30 12:27:35
【问题描述】:
我试图通过使用 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 并测试点击了哪个像素颜色。提前感谢任何可以提供帮助的人!
【问题讨论】:
-
我发送了一些想法。此外,如果您发现我的回答有帮助,您可以考虑通过单击答案左侧的赞成/反对箭头下方的“勾选”来接受答案:-)。这样做可以鼓励响应者提供帮助 - 但您没有义务接受
-
glReadPixels会产生 GL 错误吗?你确定你的颜色应该在读取位置,而不是在读取和缓冲区交换之间绘制吗?你可以吗?从前端缓冲区读取? -1 值看起来是正确的,因为您从 GL 请求无符号字节,但 java 只有有符号字节(但应该有将其转换为无符号 int 的函数)。 -
我的猜测是您忘记将鼠标坐标从默认窗口系统约定(原点在左上角)转换为 GL 约定(原点在左下角)。此外,正如答案中已经指出的那样,将无符号值打印为有符号会导致一些混乱。但我还有其他问题:您为什么要使用古老的 ARB 和 EXT 扩展?十年前,这些东西就在核心 GL 中。但这也是一个有争议的问题,因为:你为什么要使用 PBO?你使用它的方式只会增加巨大的开销,而且你仍然会强制 CPU-GPU 完全同步。