projective texturing problems

okay trying to get projective textures working, from this link:
http://www.opengl.org/resources/tutorials/sig99/advanced99/notes/node80.html

so, this is how i set up the texture matrix:

[cpp]
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
// Offset
glTranslatef(.5f, .5f, .0f);
// Bias
glScalef(.5f, .5f, 1.0f);
// light frustum
projection.SetM();
// light view
light.LookAtM();

GLfloat Splane[] = {1.f, 0.f, 0.f, 0.f};
GLfloat Tplane[] = {0.f, 1.f, 0.f, 0.f};
GLfloat Rplane[] = {0.f, 0.f, 1.f, 0.f};
GLfloat Qplane[] = {0.f, 0.f, 0.f, 1.f};

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_S, GL_EYE_PLANE, Splane);
glEnable(GL_TEXTURE_GEN_S);

glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_T, GL_EYE_PLANE, Tplane);
glEnable(GL_TEXTURE_GEN_T);

glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_R, GL_EYE_PLANE, Rplane);
glEnable(GL_TEXTURE_GEN_R);

glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_Q, GL_EYE_PLANE, Qplane);
glEnable(GL_TEXTURE_GEN_Q);
[/cpp]

hrmm the inverse of the light transform seems to work better, but still not properly.

projection is the same projection i use on my camera and light
light.LookAtM multiplys the lights view matrix with the existing ogl matrix

what im doing is rendering the scene from the light after that like so:
[cpp]
glMatrixMode(GL_MODELVIEW);
light.LookAt();

transform2.SetM(); // a matrix that spins my quad
//draw a quad
[/cpp]

what i would want to see if the texture being projected strait on my screen, top left of the screen being 1 corner of the texture, while the bottom right would be the opposite corner… and would be projected strait on to the scene right, or would it only be like this in ortho mode?

what i get is just weird… will post a demo if people need to see whats going on…

You are definitely in the right ballpark.

I don’t think texgen Q is right.

Just turn that off, it could screw up perspective projection, I’ve used s,t,r and with Q left alone it’ll be 1.0 and then be calculated based on the projective matrix. So when you have a projection on the stack definitely leave texgen Q off.

Hmm… looking at that Q texgen setting it is 0,0,0,1 I think it will produce 1.0 anyway because all vertex coords have an implied 1.0 W anyway but might as well leave it off unless you’re using vertex4f.

Anyway, moving on, your lookat on the modelview will transform the texgen correctly if you texgen in object space, however you are performing a texgen in eye space. This is why you need the inverse viewing matrix on the modelview. Lookat just won’t do the job, it’s 100% wrong when you start with EYE_LINEAR vertex values. Also the texgen eye_linear you are using is the better option because you don’t have to shadow model matrix manipulations on the texture matrix stack.

If you have no model manipulations, in other words your modelview only contains your model matrix when you sent the object vertices) then your setup should work if you change to an OBJECT_LINEAR texgen, but inverse viewing matrix would be the better option and stick with the EYE_LINEAR.

Eye linear texgen does an implicit postmultiplication of the parameters with the inverse of the current modelview matrix.

The equation becomes

g = p1’*xe + p2’*ye + p3’*ze + p4’*we

with

(p1’ p2’ p3’ p4’) = (p1 p2 p3 p4)*Minv

where Minv is the inverse of the modelviewmatrix at the time you specify the eye-planes.

(xe ye ze we) are the eye space coordinates.

If you use the same modelview matrix for drawing, the equation becomes

g = p1’xe + p2’ye + p3’ze + p4’we
= p1
xo + p2
yo + p3
zo + p4
zo

(xo yo zo wo) are the object space coordinates.

because the matrix multiplication of the inverse modelviewmatrix at the time of the eye plane specification and the modelview matrix at drawing time result in the identity matrix.
So drawing a quad now, will result in seeing the texture itself like you want it.

You are updating only the texture matrix, so the modelview matrix at the time where you specify the eye planes is not necessarily the identity matrix.
For your code to work, it should be the identity matrix. But in that case you will get the same result whether you use object linear or eye linear.
To take advantage of the eye linear, you have to split up te texcoordgeneration in GL_TEXTURE and GL_MODELVIEW. The GL_TEXTURE need only to be set up once, and the modelview can be updated each frame if necessary.

Referring to the url you posted. By setting the modelviewmatrix , I assume they mean setting the GL_MODELVIEW instead of postmultiplying it with the texture matrix.

This is the way I would do it:

glMatrixMode(GL_TEXTURE);

glLoadIdentity();
glTranslatef(.5f, .5f, .0f);
glScalef(.5f, .5f, 1.0f);
projection.SetM();

glMatrixMode(GL_MODELVIEW)
glLoadIdentity();
light.LookAtM();

Greetz,

Nico

EDIT: changed code

This is accomplished by transforming the supplied plane equation at the time the glTexGen parameters for EYE_LINEAR is specified. If the modelview matrix is identity it has no effect, if it is the viewing matrix you get the transformation to world space without adjusting the texture matrix because the texgen plane equations are transformed one time only.

So if you want to exploit this it is critical that your viewing matrix is on the modelview stack when you specify the plane equations for the texgen. Optionally just stick identity on the modelview and go with the inverse view matrix on the texture matrix stack. Both should have equivalent results for EYE_LINEAR.