简体   繁体   English

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

[英]What does the PBO buffer content mean?

I was trying to implement a color picking system by using a PBO(pixel buffer object using OpenGL), and when I finished, I realized the numbers that came out of the PBO when mapped didn't make any sense at all. 我试图通过使用PBO(使用OpenGL的像素缓冲对象)来实现颜色选择系统,当我完成时,我意识到映射时从PBO出来的数字根本没有任何意义。 I made my application render big squares of different colors and the result DID change between these different colors, but even after analyzing the numbers, I can't make sense of it. 我让我的应用程序渲染了不同颜色的大方块,并且结果DID在这些不同颜色之间发生了变化,但是即使在分析了数字之后,我也仍然无法理解。

For example, clicking on pure red gave me bytes of (-1,0,0), while pure blue gave (0,0,-1), but against all logic, pure green gives (-1,0,-1), cyan also gives (-1,0,0), and yellow gives (76,-1,0). 例如,单击纯红色给出的字节为(-1,0,0),而纯蓝色给出的字节为(0,0,-1),但是在所有逻辑上,纯绿色给出的字节为(-1,0,-1) ,青色也给出(-1,0,0),黄色给出(76,-1,0)。

Obviously these numbers are wrong, given that two different colors can result in the same byte formation. 鉴于两种不同的颜色可以导致相同的字节格式,因此这些数字显然是错误的。 Shouldn't a fully red color be (127,0,0)? 全红色不应该是(127,0,0)吗?

Here is the code I used for initialization, size 3 because I am only reading one pixel. 这是我用于初始化的代码,大小为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

And here is the code I used for reading the pixels 这是我用来读取像素的代码

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

If I am wrong in any assumptions I have made, please correct me. 如果我做的任何假设都不对,请纠正我。 I am planning perhaps to use this system to tell which gui element is being clicked by rendering each of them to an fbo with a unique color and testing which pixel color was clicked on. 我打算使用此系统,通过将每个gui元素渲染到具有唯一颜色的fbo并测试单击哪个像素颜色来判断正在单击哪个gui元素。 Thanks in advance for anyone who can help! 预先感谢任何可以提供帮助的人!

At long last I have finally found the issue! 终于,我终于找到了问题!

Firstly, using Byte.toUnsignedInt(byte), you can turn the color that the pbo gives you into your traditional 0-255 range rgb numbers. 首先,使用Byte.toUnsignedInt(byte),您可以将pbo给您的颜色变成传统的0-255范围内的rgb数字。

Secondly, this being the primary issue, when OpenGL asks for pixel coordinates to fill a pbo, it is relative to bottom right. 其次,这是主要问题,当OpenGL要求像素坐标填充pbo时,它相对于右下角。 My issue was that I was using GLFW which gives coordinates relative to top right, meaning color picking in the vertical middle of the screen was accurate, but that it was getting the inverse part of the screen I was looking for when color picking elsewhere. 我的问题是我使用的是GLFW,它给出相对于右上角的坐标,这意味着在屏幕垂直中间的颜色选择是准确的,但是当我在其他地方进行颜色选择时,它正在获取我正在寻找的屏幕的反面部分。 To fix this, simply subtract the mouse click's y coordinate from the window height. 要解决此问题,只需从窗口高度中减去鼠标单击的y坐标即可。

Thanks for the help and ideas! 感谢您的帮助和想法!

There are a couple of possibilities, but I don't have my openGL system set up to test - but you can try these anyhow. 有两种可能,但是我没有设置我的openGL系统进行测试-但是您可以尝试任何一种方法。 Also I don't know Java too well ( C,C++ etc is my domain) 我也不太了解Java(我的领域是C,C ++等)

EDIT 编辑

1) You have asked for GL_UNSIGNED_BYTE data from glReadPixels() , but you are printing out in signed format. 1)您已经从glReadPixels()请求GL_UNSIGNED_BYTE数据,但是您正在以签名格式进行打印。 GL_UNSIGNED_BYTE has values 0-256, so negative values are not possible! GL_UNSIGNED_BYTE值为0-256,因此不可能使用负值! Try to format you printout for UNSIGNED_BYTE and see where that leads. 尝试格式化打印输出的UNSIGNED_BYTE然后查看结果。 (from your code I can see this is now fixed). (从您的代码中,我现在可以看到此问题已解决)。

2) As derhass pointed out in his comments, you should not be using the ARB (architecture Review Board) extension versions of OpenGL buffer functions since these are part of OpenGL core for quite a long time now. 2)正如derhass在他的评论中所指出的那样,您不应使用OpenGL缓冲区功能的ARB(体系结构审查委员会)扩展版本,因为它们是OpenGL核心的一部分,已有相当长的时间了。 See https://www.khronos.org/opengl/wiki/History_of_OpenGL for version history. 有关版本历史记录,请参见https://www.khronos.org/opengl/wiki/History_of_OpenGL From this I can see glBindBufferARB (for example) was deprecated in 2003. It may or not impact your particular problem, but replace glXXXXXARB() with glXXXXX() thorughout, and make sure your OpenGL libraries are recent (v4 or later). 由此可见,例如glBindBufferARB(例如)在2003年已弃用。它可能会或不会影响您的特定问题,但是请使用glXXXXX()替换glXXXXXARB(),并确保您的OpenGL库是最新的(v4或更高版本)。

3) Also credit derhass, and reading your GitHub code, your getMousePosition() via glfwGetCursorPos returns screen coordinates (0,0 is top left of your window) so you need to convert to viewport coordinates (0,0 is bottom left) to read the framebuffer. 3)同样感谢derhass,并读取您的GitHub代码,通过glfwGetCursorPos的getMousePosition()返回屏幕坐标(窗口的左上角为0,0),因此您需要转换为视口坐标(窗口的左下角为0,0)才能读取帧缓冲区。 Your code at GitHub seems not to be making the conversion. 您在GitHub上的代码似乎没有进行转换。

4) Also credit derhass, you dont' need to use PBO at all for basic color picking. 4)另外,由于无需信用证明,您完全不需要使用PBO进行基本的颜色选择。 glReadPixels() default target is the framebuffer, so you can safely dispense with the VBO and get color, depth and stencil data directly from the framebuffer. glReadPixels()的默认目标是帧缓冲区,因此您可以安全地省去VBO,直接从帧缓冲区获取颜色,深度和模板数据。 (you need to enable the depth and stencil buffers). (您需要启用深度和模板缓冲区)。

5) If you are selecting on a 3D scene, you will also need to convert (unproject) the viewport coordinates and depth back to worldcoordinates to be able to identify which object you have clicked on. 5)如果要在3D场景中进行选择,则还需要将视口坐标和深度转换(取消投影)为世界坐标,以便能够识别单击的对象。 See https://en.wikibooks.org/wiki/OpenGL_Programming/Object_selection for some ideas on selection. 有关选择的一些想法,请参见https://en.wikibooks.org/wiki/OpenGL_Programming/Object_selection

I hope all this helps a bit, although it feels a like learning experience for both of us. 我希望所有这些都对您有所帮助,尽管对我们俩来说,这都是一种相似的学习经历。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM