PDA

View Full Version : glReadPixels addressing or indexing problem



Andy Robertson
01-11-2006, 01:57 PM
Folks,
I am using glReadPixels to grab the screen buffer and dump to a bmp file. I am not getting the desired results so I simplified my code to simply generate a cvs file with ones and zeros to check my understanding of how this works. Clearly I am not doing something correct. have I completely misunderstood how this command pushes data into the assigned memory buffer. Are my indices wrong? Is my sizing wrong?

It appears that the data being generated is a 32 bit unsigned integer. Could there be a size conflict with GL_UNSIGNED_INT and unsigned int?

I am using mingw with g++/fltk on a pc.

Any help is greatly apprecieated. A cleaned up snippet follows....



// Declare a pointer to an unsigned int
unsigned int *ImageBuff = NULL;
.
.
.
// Allocate memory for w by h pixels by 3 values
ImageBuff = (unsigned int*) malloc(sizeof(GL_UNSIGNED_INT) * w() * h() * 3);
.
.
// now read the pixels into the buffer in RGB
glReadPixels(x(), y(), w(), h(), GL_RGB, GL_UNSIGNED_INT, ImageBuff);
.
.
.
// Now write out the data in CVS format for review
int imax = w();
int jmax = h();
ofstream BitMapFile("BitMap.cvs", ios::trunc | ios::out);
for(i = 0; i < imax; i++)
{
for (j = 0; j < jmax; j ++)
{
index = j * i * 3;
if(ImageBuff[index + 0] >> 0&amp;&amp; ImageBuff[index + 1] >> 0 &amp;&amp; ImageBuff[index + 2] >> 0 )
{
cerr << i << " " << j
<< " " << ImageBuff[index + 0]
<< " " << ImageBuff[index + 1]
<< " " << ImageBuff[index + 2] << "\n";
}
BitMapFlag = 0;
if(ImageBuff[index + 0] >> 0&amp;&amp; ImageBuff[index + 1] >> 0 &amp;&amp; ImageBuff[index + 2] >> 0 )BitMapFlag = 1;
BitMapFile << BitMapFlag;
if(j < (jmax - 1))
{
BitMapFile << ",";
}
else
{
BitMapFile << "\n";
}
}
}What am I missing here?

Thanks
- Andy

Bob
01-11-2006, 02:37 PM
Since GL_UNSIGNED_INT is a constant integer with value 5125, sizeof(GL_UNSIGNED_INT) is equal to sizeof(5125). This is clearly not how sizeof is supposed to be used in this case. You want the size of the datatype GLuint, so use sizeof(GLuint). In this particular case you may get the desired value anyway as the constant integer 5125 and the datatype GLuint may be of the same size. That is, however, purely an accident, or a silent error of you like, and should be fixed immediately.

The way you calculate the index variable is wrong. It should be index = (i * jmax + j) * 3.

Right shifting a value by zero bits, as you do three times in the if-statement is not wrong in itself, it's just useless as it doesn't do anything. Any reason why it's there?

Andy Robertson
01-12-2006, 09:25 AM
Thanks Bob,
I see the declaration issue. I need to spend a little more time with how GL uses it's own type declarations. I thought GL_UNSIGNED_INT was an equivelancy to whatever the appropriate OS dependent variable was, did not catch on that it was an enumeration used by GL internally an that there were directly declared types like GLuint.

I am still a bit unclear on the indexing.
With index = (i * jmax + j)*3
isn't index + 0 the R byte,
index + 1 the G byte and
index + 2 the B byte for a GL_RGB buffer?

I wanted to write a 1 to my file if any of the RGB data was non zero.

Am I still misunderstanding the data generated by glReadPixels?

Thanks again
- Andy

Bob
01-13-2006, 03:37 AM
Correct concerning indices and corresponding color channel.

If you want to write a 1 if any color channel is non-zero, then, in the if-statements, you would use the greater-than operator instead of the bitwise right-shift operator. Or you could use the not-equal-to operator instead.

On top of that, you should use the logical OR instead of logical AND to check if any channel is non-zero. With logical AND, it would check if all channels are non-zero instead.
</font><blockquote><font size="1" face="Verdana, Arial">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">if(ImageBuff[index + 0] != 0

Bob
01-13-2006, 03:42 AM
Wierd, was logged in as I posted but still posted as as unregistered. And the code was incomplete aswell :confused:

Anyway, trying again with a new one, as I can't edit my post.
</font><blockquote><font size="1" face="Verdana, Arial">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">if(ImageBuff[index + 0] != 0

Bob
01-13-2006, 03:44 AM
I give up. :mad:

if(ImageBuff[index + 0] != 0 OR ImageBuff[index + 1] != 0 OR ImageBuff[index + 2] != 0) BitMapFlag = 1;Where OR is a double pipe, logical OR.