glReadPixels Question

Started by
4 comments, last by faculaganymede 19 years, 1 month ago
glExperts, I have a problem with glReadPixels. In my program, after each drawScene operation, I wanted to read the RGBA values from color buffer to a data array so I can index the value of each color component of every pixel. I setup a function called ig3dArrayCalloc to allocate a 3D array:

void ***ig3dArrayCalloc
(
	int	num_rows,
	int num_cols,
	int num_layers,
	int	element_size
)
/*------------------------------ LOCAL DECLARATIONS -------------------------*/
{
	void ***array3d=NULL;
	int	row_index;
	int col_index;

/*--------------------------------- FUNCTION BODY ---------------------------*/

	array3d=(void ***)calloc(num_rows, sizeof(void **));
	if(array3d==NULL)
	{
		igSetErrorMessage("ig2dArrayCalloc: memory allocation error");
		return(NULL);
	}

	for(row_index=0; row_index<num_rows; row_index++)
	{
		array3d[row_index]=(void **)calloc(num_cols, sizeof(void*));
		if(array3d[row_index]==NULL)
		{
			igSetErrorMessage("ig2dArrayCalloc: memory allocation error");
			return(NULL);
		}

		for(col_index=0; col_index<num_cols; col_index++)
		{
			array3d[row_index][col_index]=(void *)calloc(num_layers,element_size);
		}
	}
	

	return (array3d);
}

So the following call produces a 3D array -> image[g_height][g_width][4] image=(unsigned char***)ig3dArrayCalloc(g_height, g_width, 4, sizeof(unsigned char)); However, when I call glReadPixels, it changes the 3D array to a 1D array: glReadPixels( 0, 0, sig_shared_data.g_width, sig_shared_data.g_height, GL_RGBA, GL_UNSIGNED_BYTE, image); But, if I allocate the data array this way: unsigned char image2[512][512][4]; ...and call glReadPixels, image2 seems to be just fine. glReadPixels( 0, 0, sig_shared_data.g_width, sig_shared_data.g_height, GL_RGBA, GL_UNSIGNED_BYTE, image2); Can someone explain to me why this happens? Thanks.
Advertisement
glReadPixels takes a pointer to where you want the entire image stored, not a pointer to an array of pointers to an array of pointers for each pixel in the image. It's a huge difference. You should allocate a single block of memory large enough to hold the entire image.
Thank you for your reply, Brother Bob.

I was trying to avoid having to use one big block of memory. In my program, after the glReadPixels call, I will need to modify some of the data values, and then do a glDrawPixels call to draw the modified image data. All the packing and unpacking of the RGBA data are kind of messy.

The main purpose of doing these routines is to add noise to the image scene. I am sure there is a better way to go about it (that I don't know of), so I appreciate any suggestions. Please note, multitexturing does not work in my computer.
In case anyone's interested, I found a better way to add noise --> use glBlendFunc.
Quote:Original post by faculaganymede
In case anyone's interested, I found a better way to add noise --> use glBlendFunc.
just a word of advice, glReadPixels is slow at best, when programming for realtime applications (specificaly games) you should try your very best to avoid it. read-backs in GL tend to be expensive.
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website
Thanks for the advice, Silvermace.

I think the best method would be to use multitexturing, but it doesn't work on my PC. So, glBlendFunc is the 2nd best :)

P.S. For the application I am working on, speed is good but not critical.

This topic is closed to new replies.

Advertisement