Question

There don't seem to be a lot of examples online of how to properly use the raster transformation methods provided with OpenGL.

I've drawn a simple triangle, and I am trying to merely copy the triangle and redraw it somewhere else. I'm getting very unusual results that I don't understand:

Given the triangle (pink): verts [3] = { {10.0, 25.0}, {125.0, 25.0}, {60.0, 60} };

I displayed the triangle:

glClear (GL_COLOR_BUFFER_BIT);  // Clear display window.
glColor3f (1.0, 0.5, 0.5);      // Set initial fill color (pink).
triangle (verts);           // Display colored triangle.

I then did the following in an effort to redraw the triangle via raster transformations:

GLubyte *data [115][35];
glReadPixels(10, 25, 115, 35, GL_RGB, GL_UNSIGNED_BYTE, data);
glRasterPos2i(50,100);  
glDrawPixels(35, 115, GL_RGB, GL_UNSIGNED_BYTE, data);

What I thought this was doing was copying all the pixels starting at (10, 25) moving right and up 300 pixels. This more than encompass the triangle.

I thought that by then drawing the pixels it would merely draw them identically as they are, but instead it is drawing a gray box that I don't even remotely understand.

What is the proper use of glReadPixels(...); and glDrawPixels(...)?

Why is my current use giving a gray box and in no way copying or drawing the pixels in the image?

enter image description here

Was it helpful?

Solution

After a lengthy chat, a few issues were exposed:

  1. GL_RGB pixels are not well liked by glReadPixels (...) and glDrawPixels (...)

    • Using the default pixel store, GL tries to store each row it reads on a 4-byte boundary; 3-byte RGB pixels make an absolute mess out of this and many other things in OpenGL.

    • You must call glPixelStorei (GL_PACK_ALIGNMENT, 1) before glReadPixels (...) with a GL_RGB format, or it may pad the end of each row in the output with extra bytes to satisfy 4-byte row alignment. Left unchecked, the default alignment will eventually lead to a memory overrun.

    • Likewise, you need to use glPixelStorei (GL_UNPACK_ALIGNMENT, 1) before glDrawPixels (...) so that it does not try to skip bytes to maintain 4-byte alignment while reading rows from your input data.

  2. Your array was declared incorrectly, you were allocating an array of pointers.

    • A pointer to a GLubyte is considerably larger than a GLubyte itself (4-8x as large depending on the compiler / CPU).

    • The proper way to declare your pixel array is GLubyte data [115 * 35 * 3], to store 115 * 35 pixels, each 3-bytes.

  3. The raster position is in object-space coordinates, but the position in glReadPixels (...) is in window-space coordinates.

    • Without an appropriate projection matrix, viewport, etc. the scale between coordinate systems (object and window) will not match, and you cannot accurately say that your triangle is 115 pixels tall and 35 pixels wide (those are its object-space dimensions).
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top