PDA

View Full Version : texturing matrix problem



xandey
08-02-2002, 11:04 AM
Hi, I'm having a problem with textures in a (rather large) program I'm working on. What happens is this: when I initialize a texture in the normal way, it looks like it was read in with the wrong width or something... ie the scanlines are screwed up.

I found that if I insert the following code into my program before rendering (I'm just rendering a square now for testing) it displays the texture, only it displays it divided into quadrants that are all upside down.

glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);

I'm baffled. I'm using texture objects, so I am calling glGenTextures(1,&texture_id); in the init function where I load the texture file and all, but I can't find what kindof opengl setting could screw with the texture matrix, especially since it gets created for each new texture (right?) and this is the only part of the program that uses this texture.

thanks for any help,
Sandy

Nutty
08-02-2002, 12:03 PM
Sounds more like a texture format problem, than a matrix problem.

What image format are you loading up, and what format parameters are you supplying to OpenGL when you create the texture?

Also what hardware etc..?

Thanks,
Nutty

[This message has been edited by Nutty (edited 08-03-2002).]

xandey
08-06-2002, 09:42 AM
Hi nutty, thanks for responding.

I'm using an nVidia GeForce 4ti um, 4600? the faster one.

Here's what I do:

glPushAttrib(GL_ALL_ATTRIB_BITS);

//I read in a ppm file into "GLubyte * pixels;" as follows:
//read header, 255 is the length,
//read in one byte for each: red, green, blue.
//order these pixels together in pixels array: RGBRGBRGB... ect
//Oh, and width and height is in the header.

//Then:
glGenTextures(1,&texture_id);
glBindTexture(GL_TEXTURE_2D, texture_id);
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

gluBuild2DMipmaps(GL_TEXTURE_2D,3,cols,rows,GL_RGB ,GL_UNSIGNED_BYTE,pixels);

glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_NORMALIZE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D, texture_id);

//Enable lighting materials

//Then here's my hack that seems to fix it:

glMatrixMode(GL_TEXTURE);
glPushMatrix();
glLoadIdentity();
glScalef(.5,-.5,0);
glTranslatef(1,1,0);

//switch back to matrix mode:
glMatrixMode(GL_MODELVIEW);

//translate

//rotate

glBindTexture(GL_TEXTURE_2D, texture_id);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DE CAL);

then draw some geometry, I've been doing a sqaure for debugging

at the end I pop the matrix's.

I do have a problem when I try and map the texture to a more complex object. (I'm using a .ply file with texture coordinates) and it doesn't work is the simplest explanation. It looks incorrect, things are in the wrong place, but with this hack when I map it to a square with the corners the corners of the texture then it appears okay.

thanks,
Sandy

Dan82181
08-06-2002, 12:41 PM
If you are having to do the glScalef and glTranslatef on the texture matrix, then something else is wrong (maybe your texture coordinates, or your image is stored in a manor different than you think?) Loading the identity matrix into the texture matrix causes your texture coordinates to remain the way that they are. When you use the

glScalef(0.5,-0.5,0.0);
glTranslatef(1,1,0);

You are doing the following...

([1 0 0 0] [0.5 0 0 0] [1 0 0 1])
([0 1 0 0]*[ 0 -0.5 0 0]*[0 1 0 1])*TexCoord
([0 0 1 0] [ 0 0 1 0] [0 0 1 0])
([0 0 0 1] [ 0 0 0 1] [0 0 0 1])

so you are basically doing
s = (0.5 * s) + 0.5
t = (-0.5 * t) - 0.5
r = r
q = q
to each texture coordinate. Which over the [0,1] interval maps
s -> [0.5,1]
t -> [-0.5,-1]
r -> [0,1]
q -> [0,1]
Which in turn will be using the right half of the texture and invert the bottom half (basically, the bottom right of the texture and it's flipped upsidedown)

And you are sure that you are popping both the modelview and the texture matrix when you are done specifying your primitives?

You could also use the glGetFloatv(GL_TEXTURE_MATRIX, &somefloatarray) at the beginning of your setup to make sure that the top texture matrix it is indeed the identity matrix.

Speaking of the texture matrix, are you by chance using multitexturing? Each texture unit has it's own texture matrix. Are you sure you are set back to the right texture unit you want? And that you are popping the appropriate texture matrix for the right texture?

Are you perhaps using the glPixelTransfer[if] command somewhere and forgot to set it back (I know it's for pixels, but perhaps it is modifying your texture in some undesireable way?)

Dan

xandey
08-06-2002, 02:13 PM
I understand my transformations inside the texture matrix. What I don't understand is why do I have to do them. When I print out the texture matrix at the beginning I get strange values, but then I load the identity and get the identity back when i check. So far so good. Now however if I display a square with texture coords: (0,0)(1,0)(1,1)(0,1) these are specified counterclockwise starting from the bottom left. Then I get 4 copys of my texture, all are upside down and not backwards.

Shouldn't this be loaded over the entire [0,1] interval for s and t? not just the quadrant form [.5,1]? I know I'm reading the pixels correctly because I then wrote them back to a file in raw format and was able to display them in matlab. I also checked the pixeltransfer values for map stencil which was the only one taht I thought could possibly effect this and it was false.

As to the actual texture coordinates, They look like they could be wrong, but I'm getting them directly from a cyberware scanner and through their cySurf software, so I have no idea how to troubleshoot that. They don't go above 1.0 or below 0.0 however.

When I load the texture onto a square though it appears correctly, but when i load it only the object it isn't right, it looks all distorted. kinda like the texture has been magnified before it was applied. or the texture coordinates are being mapped from [0,1] -> [.4,.6]

Thanks guys,
Sandy

WhatEver
08-06-2002, 03:30 PM
Can you give us screenshots of the before and after glLoadIdentity for the TEXTURE_MATRIX?

The default texture matrix should be alright. Did you do a search in your project to see if there's a place fubaring your texture matrix?

If you're using uvs ranging from 0.0f to 1.0f your mapping should not show 4 images.

Also, are you new to using textures or have you used textures before but didn't have this problem?

WhatEver
08-06-2002, 03:32 PM
One other thing to keep in mind. The uvs might be flipped. Flip the y(or t or v or whatever you want to call it) by doing this:

y=1.0f-y;

Dan82181
08-06-2002, 08:05 PM
Yes, some pics would be nice if possible. I was also thinking, could texgen be on?

Dan

xandey
08-07-2002, 07:41 AM
tex gen? is that like for generating texture coordinates? you think it's ignoring the texture coords I give it and supplying it's own? how would I check that?
I'm pushing and popping GL_ALL_ATTRIB_BITS. but I guess that doesn't change any settings, only saves them to go back later.

Anyway, here's some screen shots:
http://www.seas.upenn.edu/~aiv/question.html

Sorry they're 1024x768, but I just dumped them to file and flipped them vertically. What kinda setting would do that? flip something vertically? the readpixels looks like this:
glReadPixels(0,0,width,height,GL_RGB,GL_UNSIGNED_B YTE,buffer);
buffer is an unsigned char *

I noticed that when I dumped to file everything was flipped, so that's simmilar to the flip in the y direction when I read in my texture.

thanks guys,
Sandy

Dan82181
08-07-2002, 09:44 AM
You can check to see if texture coordinate generation is enabled for the active texture unit by calling

glIsEnabled(GL_TEXTURE_GEN_{Q,R,S,T});
will return GL_TRUE if texture coord generation is on for the specified coordinate and only on the active texture unit. One other thing that would tip you off that texture coordinate generation is on is that if you move or rotate the object and/or the camera, the texture(s) would 'move' or 'swim' through the object.

What OS are you running under? If you're using Windows, you can do ALT+PrintScreen to capture the application window instead of having to call a glReadPixels(...) to get the image. Then just paste into mspaint or something and you have your screen capture. Don't know about X though, I guess it would be dependant on your WM.

You mentioned that you are using
glPushAttrib(GL_ALL_ATTRIB_BITS);
Are you by chance also using vertex and/or texture coordinate arrays? They have a seperate set for pushing and popping values like so
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
...
glPopClientAttrib();
I think they are supposed to push and pop all the texture units, but I'm not 100% sure on that.

As far as I can tell from the screen shots, it has to be something to do with texture coordinates, either before or after you supply them to OpenGL. And you're saying that none of the coordinates goes over the [0,1] interval, so there shouldn't be any repeating.

What's up with the background, or is that you markingup the image over certain things?

Dan

xandey
08-07-2002, 01:26 PM
It WORKS!! thanks so much dan. The problem was texture generation. It was turned on for Q R S T, all of them. I added a group of glDisables and I nolonger had to do the scaling. It still reads stuff upside down, but it's a really easy hack and I'm tired of screwing with it.

I never saw a swimming effect though. I could immagine what you're talking about, like if I rotate the object the texture should flow over it as though it were projected in from a sphere surrounding the object. That wasn't happening. I can move it all around with the spaceball (6d mouse)

As to arrays, I couldn't figgure out how to get an array of polygons (from a .ply file) the only thing I could think of was to break the polygons into triangles and call drawArrays with triangles. (too complicated) Right now I'm specifying primitives inside for loops, and I plan on putting display lists in once I get it working.

As to the background, this is part of research for tele-immersion http://www.seas.upenn.edu/whatsnew/tele-im2.html (it's 3d teleconferencing software) so the background is an office. I'm doing stereo rendering with two polarized rear projectors.

I'm trying to add virtual objects from files http://www.opengl.org/discussion_boards/ubb/smile.gif

Thanks again guys!