glReadPixels()函数中"data"参数的用法是什么?

17

我正在尝试使用glReadPixels从图像中获取颜色数据。我应该使用glReadPixels,但似乎无法弄清楚。这是一个更大的项目的一部分,但现在我只想知道如何正确地使用它。

我查了一下,得到了类似于这样的东西:

    void glReadPixels(GLint x, 
       GLint y, 
       GLsizei width, 
       GLsizei height, 
       GLenum format, 
       GLenum type, 
       GLvoid* data);

但我不确定我应该在最后一个参数中输入什么,而且当我这样做时,我该如何使用它。真的需要帮助!(例如:如何使用它的简单示例,或如何获取颜色)


如何一次性读取整个屏幕的示例:https://dev59.com/CG025IYBdhLWcg3wtoVA#36236839 - Ciro Santilli OurBigBook.com
3个回答

27

data接受一个指向你为glReadPixels准备的缓冲区的指针,用于存放数据。就像这样:

switch(format) {
case GL_BGR:
case GL_RGB:
    components = 3; break;

case GL_BGRA:
case GL_RGBA:
    components = 4; break;

case GL_ALPHA:
case GL_LUMINANCE:
    components = 1; break;
}

GLubyte *data = malloc(components * width * height);
if( data ) {
    glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, data);
}

1
干得好。我想要补充一下,前两个参数(x和y)几乎总是0,0,因为它们指定了像素区域的左下角。 - ahoffer
GL_PACK_ALIGNMENT是什么?还有GL_PACK_ROW_LENGTH呢? - Zbyl
@Zbyl:应该设置GL_PACK_ALIGNMENT,但确切的值取决于目标格式。GL_PACK_ROW_LENGTH可以保持为0,除非您想要更新由数据指向的缓冲区的子部分。但是,仅仅读取整个图片时这并不是必需的。 - datenwolf
如何获取默认缓冲区的“format”? - Ciro Santilli OurBigBook.com

19

使用示例:

#include <GL/glut.h>
#include <iostream>

int mx = 0, my = 0;
void display()
{
    glClearColor( 0, 0, 0, 1 );
    glClear( GL_COLOR_BUFFER_BIT );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glOrtho( -10, 10, -10, 10, -1, 1 );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    glScalef( 5, 5, 5 );
    glBegin( GL_TRIANGLES );
    glColor3ub( 255, 0, 0 );
    glVertex2f( -1, -1 );
    glColor3ub( 0, 255, 0 );
    glVertex2f( 1, -1 );
    glColor3ub( 0, 0, 255 );
    glVertex2f( 0, 1 );
    glEnd();

    // 4 bytes per pixel (RGBA), 1x1 bitmap
    unsigned char pixels[ 1 * 1 * 4 ] = { 0 };
    glReadPixels( mx, my, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels );
    std::cout << "r: " << static_cast< int >( pixels[ 0 ] ) << '\n';
    std::cout << "g: " << static_cast< int >( pixels[ 1 ] ) << '\n';
    std::cout << "b: " << static_cast< int >( pixels[ 2 ] ) << '\n';
    std::cout << "a: " << static_cast< int >( pixels[ 3 ] ) << '\n' << std::endl;

    glutSwapBuffers();
}

void mouse( int x, int y )
{
    mx = x;
    my = glutGet( GLUT_WINDOW_HEIGHT ) - y;
    glutPostRedisplay();
}

int main( int argc, char **argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
    glutInitWindowSize( 800, 600 );
    glutCreateWindow( "glReadPixels() example" );
    glutDisplayFunc( display );
    glutPassiveMotionFunc( mouse );
    glutMainLoop();
    return 0;
}

使用鼠标获取像素的RGBA值。


1
我在向量释放期间遇到了崩溃。我使用以下方法进行了修复:unsigned char pixels[4]; - num3ric
我正在尝试运行这段代码,但是所有像素的值都是空的(NULL)。有什么想法是什么原因导致的吗?我正在使用glut-3.7.6。 - masad
2
@masad:切换到FreeGLUT,或尝试在glReadPixels()调用之前添加glFinish() - genpfault
1
@genpfault 非常感谢!它起作用了!!我添加了函数调用并将我的库更改为FREEGLUT。 - masad
@masad:FreeGLUT修复了它还是glFinish()?还是两者都需要? - genpfault
1
@genpfault FREEGLUT已经修复了。glFinish()在输出中不会改变任何内容。 - masad

2

data是指向你正在尝试读取的像素数据的指针。看一下一些示例代码,并在调用之前查找几行以上,以了解它们如何初始化。通常只需分配大小为x * y * depth的内容即可。您将其作为&data传递。尝试读取已知颜色的1x1像素块,并查看它返回了什么样的信息。


1
数据是指向您要写入的像素数据的指针。笔误:应为“写入”,而非“读取”。 - Damon
我想我的措辞有些欠妥:“您正在尝试读取的像素数据存储在data中”。他们正在将像素读入data中。 - Tim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接