I’m not sure exactly what you meant when you were describing your method of finding the plane. In any case, doing this with glGetFloatv on every frame is unneccessary and causes your program to be unneccessarily slow.
One thing is certain, the way you are using the modelview matrix is wrong, and it looks like you are trying to fix it by using glGetFloatv, but you really should fix it by ordering your matrix operations correctly.
First, lets look at how to find the plane equation for your shadow. Then I’ll give you some fixed rendering pseudocode which will fix your matrix problems.
If you are just drawing a table that faces upward, the plane equation is
x = 0
y = 1
z = 0
w = however far the y offset is from the origin.
(in the function I gave you these correspond to
plane.coefficents[0] through plane.coefficients[3])
If you are going to be rotating it so it no longer faces upwards, then its a bit trickier. In that case, you should apply any rotations you will be doing to the table to the plane equation as well. Look up math stuff on google to find out how to do this. Do NOT depend on OpenGL’s modelview matrix to do all of your transformation math for you. The matrix stacks are there for a very specific purpose, which is NOT to aid you in calculating data that should be calculated PRIOR to your rendering loop. The modelview and projection matrices are there to transform the vertices you send to opengl before they get drawn on the screen and NOTHING else.
In any case, to get this thing working, I suggest you start with a table that always faces upwards and use the plane equation I gave you above. This makes it dead simple to find the actual plane equation that you want. All you have to do is put the table surface’s y offset in the w coefficient.
Getting the position of your light should also be dead simple since you should be storing it directly. You should have some struct or class that holds the absolute x,y,z position of your light. Thats all you need. You dont need to get the modelview matrix and transform it or anything goofy like that.
Finally, gluLookAt just modifies the modelview matrix to do a camera transformation. You can do these transformations on your own instead of using gluLookAt (with glTranslate, glRotate, or glMultMatrix). I prefer to calculate the matrix myself and use glMultMatrix. However, for your purposes right now, you should probably stick with gluLookAt to keep things simple.
Hope you’re still following…
I will rewrite the steps for you. Take notice, because this is the correct way to do it, and if you fight it, it will only ensure your failure.
The steps assume you have the matrix mode set to modelview and have already set up your projection matrix correctly (with gluPerspective, glOrtho, or glFrustum) at initialization or somehwere else.
During Init
store the plane equation of the plane you want to cast a shadow on. Any time this changes in the future, recalculate the plane equation. For starters, keep your table facing up, and use the simple plane equation I gave you above. Once you have that working you can experiment with rotating the table.
Render Scene:
-
Set the modelview matrix to the identity (glLoadIdentity)
-
gluLookAt(or do your own camera transformation)
-
Call glLightfv with your light’s ABSOLUTE coordinates in 3d space. DO NOT USE glTranslate, glRotate, etc., or make any other modifications to the modelview matrix.
-
Push Matrix
-
Do modelview transformations for your table
-
Draw Table
-
Pop Matrix
-
Push Matrix
-
Do modelview transformations for object that will cast shadow
-
Draw Object
-
Pop Matrix
//shadow drawing part
12. Push Matrix
13. Call the function I gave you in my previous post using your plane equation and your light’s absolute coordinates
14. glMultMatrix with the matrix returned by #13
15. Do Same transformation as #9
16. set shadow drawing properties (color to gray, depth buffer settings, etc.)
17. Draw object that casts the shadow (it will be squished onto the table surface)
18. Pop Matrix
Repeat steps 8 through 18 for each object that you want to cast a shadow. You can also switch it so 12-18 come before 8-11.
Hope that helps.
Just a final word on this…
You have a problem that a lot of beginning opengl programmers have which is overdependence on the matrix stacks and the high level matrix functions. Symptoms of this include lots of calls to glGetFloatv, glRotate, and gluLookAt, and undesired matrix transformations (such as objects moving when you move the camera).
The problem is that if you dont know how to do the matrix math yourself, when you get to things like shadow casting, collision detection, character/vehicle movement, camera movement, etc. you will be totally lost. Once you realize this, you will want to do the math yourself, so you can keep copies of the matrices around for purposes other than rendering.