PDA

View Full Version : Using glReadPixels to texture a sphere



vindy
05-07-2011, 09:40 PM
Got another problem folks. This is what I'm trying to do: I have two cubes rotating above a plane and over head and behind them is a sphere. I want to move the camera forward, turn 180 degrees around the y axis, take a screen shot using glReadPixels, restore camera to original orientation and position, covert pixel data to a texture, and map it on to the sphere. The problem I'm having is that the scene comes out in black and white when I do this. I'm stumped. Here's some of my code:

GLfloat *pix;
int arraylen;

glPixelStoref(GL_PACK_ALIGNMENT, 1);

arraylen = 400 * 400 * 3;
pix = (GLfloat *)calloc(arraylen, sizeof(GLfloat));

gluLookAt(0, 5, -22, 0, 0, 0, 0, 1, 0);
glReadPixels(0, 0, 400, 400, GL_RGB, GL_FLOAT, pix);


glEnable(GL_TEXTURE_2D);


glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 400, 400, 0, GL_RGB, GL_FLOAT, pix);

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);


glLoadIdentity();
glTranslatef(0.0f, 5.0f, -25.0f);

glNormal3f(0.0f, 0.0f, 1.0f);
glutSolidSphere(3.0f, 25, 25);

glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);

glDisable(GL_TEXTURE_2D);

Any ideas as to where I'm going wrong?

_arts_
05-08-2011, 01:00 AM
draw something between your gluLookAt and your glReadPixels.

vindy
05-08-2011, 03:36 AM
That didn't seem to do the trick.

vindy
05-08-2011, 11:33 AM
Is there anybody else that might be able to help?

V-man
05-09-2011, 05:57 AM
When you take a screenshot with your glReadPixels, the scene looks black and white?
There isn't much in that short piece of code.
The only thing I can tell you is that you should not use glTexImage2D to update a texture. Use glTexSubImage2D instead. Also, by using floats, you are causing conversion of data which tends to be slow.

Perhaps you should post the whole project and we'll see what the problem is.

george_azure
05-09-2011, 06:20 AM
I don't know how to say it, but moving around the camera, take a snapshot and then render it won't work on any graphics api. You have to call gluLookat, render the geometry you want in your texture, copy to texture, clear the scene, and then render again the geometry. And call glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T); right before glEnable(GL_TEXTURE_2D);I hope I understand your problem.

vindy
05-09-2011, 06:20 AM
I've got a ton of code in my drawScene function. I'm not sure it'll fit here. However, I've been playing with my code and managed to get it to work. I tried using glTexSubImage2D and that didn't do the trick. Instead I'm using gluBuild2DMipmaps. Unfortunately its extremely slow. Here's what I've done:

GLubyte *pix;
int width, arraylen;
GLint viewport[4];
GLuint tex;

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glGetIntegerv(GL_VIEWPORT, viewport);

width = viewport[2] * 3;
width = (width + 4) & ~3;
arraylen = width * viewport[3];
pix = (GLubyte *)calloc(arraylen, 1);

glPixelStorei(GL_PACK_ALIGNMENT, 3);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);

gluLookAt(0, 5, -20, 0, 0, 0, 0, 1, 0);

glReadPixels(0, 0, viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pix);

glEnable(GL_TEXTURE_2D);

gluBuild2DMipmaps(GL_TEXTURE_2D, 3, viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pix);

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);


glLoadIdentity();
glTranslatef(0.0f, 5.0f, -25.0f);

glNormal3f(0.0f, 0.0f, 1.0f);
glutSolidSphere(5.0f, 25, 25);

glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);

glDisable(GL_TEXTURE_2D);