我正在尝试使用glReadPixels存储像素数据,但到目前为止,我设法一次只存储一个像素。我不确定这是否可行。我目前有这个:
unsigned char pixels[3];
glReadPixels(50,50, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixels);
将它存储在数组中的好方法是什么,这样我就可以得到这样的值:
pixels[20][50][0]; // x=20 y=50 -> R value
pixels[20][50][1]; // x=20 y=50 -> G value
pixels[20][50][2]; // x=20 y=50 -> B value
我想我可以简单地把它放在一个循环中:
for ( all pixels on Y axis )
{
for ( all pixels in X axis )
{
unsigned char pixels[width][height][3];
glReadPixels(x,y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixels[x][y]);
}
}
但我觉得必须有更好的方法来做到这一点。但我确实需要我的数组就像上面描述的代码一样。那么for循环的想法是好的,还是有更好的方法呢?
答案 0 :(得分:5)
glReadPixels
只是按照{strong>设置的R, G, B, R, G, B, ...
}从屏幕左下角向上右上方返回字节。 From the OpenGL documentation:
glReadPixels从帧缓冲区返回像素数据,从 左下角位于(x,y)位置的像素进入客户端 内存从位置数据开始。几个参数控制 在将像素数据放入客户端存储器之前处理像素数据。 这些参数使用三个命令设置:glPixelStore, glPixelTransfer和glPixelMap。该参考页面描述了 对glReadPixels的影响大多数,但不是所有参数 由这三个命令指定。
调用GL_RGB
数千次的开销很可能会花费相当多的时间(取决于窗口大小,如果循环需要1-2秒,我不会感到惊讶)。
建议您只调用glReadPixels
一次,并将其存储在大小为glReadPixels
的字节数组中。从那里你可以用(width - x) * (height - y) * 3
引用像素的组件位置,其中data[(py * width + px) * 3 + component]
和px
是你要查找的像素位置,py
是R,G,或像素的B分量。
如果你绝对必须将它放在一个三维数组中,你可以编写一些代码来在component
调用后重新排列1d数组。
答案 1 :(得分:1)
如果您将像素数组定义如下:this:
unsigned char pixels[MAX_Y][MAX_X][3];
你会像这样访问它:
pixels[y][x][0] = r;
pixels[y][x][1] = g;
pixels[y][x][2] = b;
然后,您将能够通过一次glReadPixels调用读取像素:
glReadPixels(left, top, MAX_Y, MAX_X, GL_RGB, GL_UNSIGNED_BYTE, pixels);
答案 2 :(得分:0)
你能做的是在结构中声明一个简单的一维数组,并使用运算符重载来方便下标符号
struct Pixel2d
{
static const int SIZE = 50;
unsigned char& operator()( int nCol, int nRow, int RGB)
{
return pixels[ ( nCol* SIZE + nRow) * 3 + RGB];
}
unsigned char pixels[SIZE * SIZE * 3 ];
};
int main()
{
Pixel2d p2darray;
glReadPixels(50,50, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &p.pixels);
for( int i = 0; i < Pixel2d::SIZE ; ++i )
{
for( int j = 0; j < Pixel2d::SIZE ; ++j )
{
unsigned char rpixel = p2darray(i , j , 0);
unsigned char gpixel = p2darray(i , j , 1);
unsigned char bpixel = p2darray(i , j , 2);
}
}
}
在这里,您可以一次性读取50 * 50像素,使用operator()( int nCol, int nRow, int RGB)
运算符可提供所需的便利。出于性能原因,您不希望进行太多glReadPixels
次呼叫