glReadPixels存储x,y值

时间:2012-01-21 15:16:48

标签: c++ opengl glut

我正在尝试使用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循环的想法是好的,还是有更好的方法呢?

3 个答案:

答案 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次呼叫