Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

glReadPixels() "data" argument usage?

I'm trying to use glReadPixels to get color data from an image. I'm supposed to be using glReadPixels but I can't seem to figure it out. It's part of a much larger project, but right now all I want is to know how to properly use this.

I looked it up and got something like this:

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

But I'm not sure what I should be putting in as that last argument, and when I do, how I would even use it. Help would really be appreciated! (ie: a simple example of how to use it, or how to get the color)

like image 632
CustardBun Avatar asked Jan 12 '12 19:01

CustardBun


3 Answers

data takes a pointer to some buffer you prepared for glReadPixels to put the data into. Like this:

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);
}
like image 91
datenwolf Avatar answered Oct 07 '22 02:10

datenwolf


Usage example:

#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;
}

Use the mouse to get the RGBA value for a pixel.

like image 41
genpfault Avatar answered Oct 07 '22 04:10

genpfault


data is the pointer to the pixel data you're trying to read. Take a look at some example code, and look a few lines above that call to find out how they're initializing it. Usually it will just be an allocation of size something like x * y * depth. You'd pass it in as &data. Try reading a 1x1 pixel block of known color and see what kind of information it gives back.

like image 41
Tim Avatar answered Oct 07 '22 04:10

Tim