noeska
11-01-2004, 05:15 PM
i came up with this. But rotation still is no good:
//create the reflection texture
procedure CreateTexture;
var
CP: array [0..3] of Double;
begin
//set up clipping plane
cp[0]:=0.0; //x
cp[1]:=0.0; //y
cp[2]:=0.000001; //z has to be somewhat larger then 0
cp[3]:=0.0; //w
//set up the viewport
glViewport(0, 0, M_SIZE, M_SIZE);
//clear the buffers
glClearColor(0.0, 0.0, 0.1, 0.0); // Background color
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
//set the camera pos
glLoadIdentity;
glLoadmatrixd(@matM);
// gltranslatef(mirrorpos.x,mirrorpos.y,mirrorpos.z);
// glrotatef(mirrorrot.x,1,0,0);
// glrotatef(mirrorrot.y,0,1,0);
// glrotatef(mirrorrot.z,0,0,1);
//mirror it
glScalef(1.0, 1.0, -1.0);
//enable clipping plane
glClipPlane(GL_CLIP_PLANE0, @CP);
glEnable(GL_CLIP_PLANE0);
//translate the mirror from its position back to 0
//actualy the scene is rotated with the reverse matrix of the mirror?
glrotatef(-mirrorrot.y,0,1,0);
glrotatef(-mirrorrot.x,1,0,0);
glrotatef(-mirrorrot.z,0,0,1);
gltranslatef(-mirrorpos.x,-mirrorpos.y,-mirrorpos.z);
//draw the scene...
DrawObjects;
//disable the clipping plane
glDisable(GL_CLIP_PLANE0);
//copy the color buffer to a texture creating a new texture if necessary
if (Reflection <> 0) then
begin
glBindTexture(GL_TEXTURE_2D, Reflection);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_CLAMP);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
M_SIZE, M_SIZE);
end else
begin
glGenTextures(1, @Reflection);
glBindTexture(GL_TEXTURE_2D, Reflection);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_CLAMP);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0,
M_SIZE, M_SIZE, 0);
end;
//restore the viewport
glViewport(0, 0, WND_XSIZE, WND_YSIZE);
end;
//calculate the texture coordinates for a vertex and send them to OpenGL
procedure RenderVertex(vX, vY, vZ: Single);
var
tX, tY, tZ: Double;
const
vp: TGLVectori4 = (0,0,1,1); //dummy viewport
begin
//calculate the window coordinates of the vertex
gluProject(vX, vY, vZ, matM, matP, vp, @tX, @tY, @tZ);
//use the window coords as texture coords
glTexCoord2f(tX, tY);
glVertex3f(vX, vY, vZ);
end;
// Function to draw the actual scene
procedure glDraw();
var
i,j: integer;
begin
Time := GetTickCount / 1000.0;
//set mirror pos...
// mirrorpos.x:=Sin(Time * 1.3);
// mirrorpos.y:=Sin(Time * 1.3);
// mirrorpos.z:=Sin(Time * 1.3);
mirrorrot.x:=Sin(Time * 1.3) * 60;
mirrorrot.y:=Sin(Time * 1.4) * 60;
mirrorrot.z:=Sin(Time * 1.5) * 60;
glLoadIdentity;
//set camera pos...
gltranslatef(0,-5,-20);
// glrotatef(90,0,1,0);
//Get the modelview and projection matrices
glGetDoublev(GL_MODELVIEW_MATRIX, @matM);
glGetDoublev(GL_PROJECTION_MATRIX, @matP);
CreateTexture; //create the mirror texture
glClearColor(0.0, 0.0, 0.2, 0.0); // Background color
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); //comment this line out the see the last renderend mirror scene
glLoadIdentity();
glLoadmatrixD(@matM);
glLightfv(GL_LIGHT0, GL_POSITION, @lp); //position light
//render the mirror
glColor4f(1, 1, 1, 0.8); // make the water transparent.
gldisable(GL_LIGHTING);
glenable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, Reflection); //use calculated mirror texture
glpushmatrix();
//place the mirror
gltranslatef(mirrorpos.x,mirrorpos.y,mirrorpos.z);
glrotatef(mirrorrot.z,0,0,1);
glrotatef(mirrorrot.x,1,0,0);
glrotatef(mirrorrot.y,0,1,0);
//do the actual rendering
//by using RenderVertex the texture coords are recalculated
for I := -(mirrorsize div 2) to (mirrorsize div 2) - 1 do
begin
glBegin(GL_QUAD_STRIP);
for J := -(mirrorsize div 2) to (mirrorsize div 2) do
begin
RenderVertex(I / M_DETAIL - 0.5,
J / M_DETAIL - 0.5, 0.0);
RenderVertex((I + 1) / M_DETAIL - 0.5,
J / M_DETAIL - 0.5, 0.0);
end;
glEnd;
end;
glpopmatrix();
gldisable(GL_TEXTURE_2D);
glenable(GL_LIGHTING);
//draw the scene...
drawobjects();
// Flush the OpenGL Buffer
glFlush();
end;
[/code]
//create the reflection texture
procedure CreateTexture;
var
CP: array [0..3] of Double;
begin
//set up clipping plane
cp[0]:=0.0; //x
cp[1]:=0.0; //y
cp[2]:=0.000001; //z has to be somewhat larger then 0
cp[3]:=0.0; //w
//set up the viewport
glViewport(0, 0, M_SIZE, M_SIZE);
//clear the buffers
glClearColor(0.0, 0.0, 0.1, 0.0); // Background color
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
//set the camera pos
glLoadIdentity;
glLoadmatrixd(@matM);
// gltranslatef(mirrorpos.x,mirrorpos.y,mirrorpos.z);
// glrotatef(mirrorrot.x,1,0,0);
// glrotatef(mirrorrot.y,0,1,0);
// glrotatef(mirrorrot.z,0,0,1);
//mirror it
glScalef(1.0, 1.0, -1.0);
//enable clipping plane
glClipPlane(GL_CLIP_PLANE0, @CP);
glEnable(GL_CLIP_PLANE0);
//translate the mirror from its position back to 0
//actualy the scene is rotated with the reverse matrix of the mirror?
glrotatef(-mirrorrot.y,0,1,0);
glrotatef(-mirrorrot.x,1,0,0);
glrotatef(-mirrorrot.z,0,0,1);
gltranslatef(-mirrorpos.x,-mirrorpos.y,-mirrorpos.z);
//draw the scene...
DrawObjects;
//disable the clipping plane
glDisable(GL_CLIP_PLANE0);
//copy the color buffer to a texture creating a new texture if necessary
if (Reflection <> 0) then
begin
glBindTexture(GL_TEXTURE_2D, Reflection);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_CLAMP);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
M_SIZE, M_SIZE);
end else
begin
glGenTextures(1, @Reflection);
glBindTexture(GL_TEXTURE_2D, Reflection);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_CLAMP);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0,
M_SIZE, M_SIZE, 0);
end;
//restore the viewport
glViewport(0, 0, WND_XSIZE, WND_YSIZE);
end;
//calculate the texture coordinates for a vertex and send them to OpenGL
procedure RenderVertex(vX, vY, vZ: Single);
var
tX, tY, tZ: Double;
const
vp: TGLVectori4 = (0,0,1,1); //dummy viewport
begin
//calculate the window coordinates of the vertex
gluProject(vX, vY, vZ, matM, matP, vp, @tX, @tY, @tZ);
//use the window coords as texture coords
glTexCoord2f(tX, tY);
glVertex3f(vX, vY, vZ);
end;
// Function to draw the actual scene
procedure glDraw();
var
i,j: integer;
begin
Time := GetTickCount / 1000.0;
//set mirror pos...
// mirrorpos.x:=Sin(Time * 1.3);
// mirrorpos.y:=Sin(Time * 1.3);
// mirrorpos.z:=Sin(Time * 1.3);
mirrorrot.x:=Sin(Time * 1.3) * 60;
mirrorrot.y:=Sin(Time * 1.4) * 60;
mirrorrot.z:=Sin(Time * 1.5) * 60;
glLoadIdentity;
//set camera pos...
gltranslatef(0,-5,-20);
// glrotatef(90,0,1,0);
//Get the modelview and projection matrices
glGetDoublev(GL_MODELVIEW_MATRIX, @matM);
glGetDoublev(GL_PROJECTION_MATRIX, @matP);
CreateTexture; //create the mirror texture
glClearColor(0.0, 0.0, 0.2, 0.0); // Background color
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); //comment this line out the see the last renderend mirror scene
glLoadIdentity();
glLoadmatrixD(@matM);
glLightfv(GL_LIGHT0, GL_POSITION, @lp); //position light
//render the mirror
glColor4f(1, 1, 1, 0.8); // make the water transparent.
gldisable(GL_LIGHTING);
glenable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, Reflection); //use calculated mirror texture
glpushmatrix();
//place the mirror
gltranslatef(mirrorpos.x,mirrorpos.y,mirrorpos.z);
glrotatef(mirrorrot.z,0,0,1);
glrotatef(mirrorrot.x,1,0,0);
glrotatef(mirrorrot.y,0,1,0);
//do the actual rendering
//by using RenderVertex the texture coords are recalculated
for I := -(mirrorsize div 2) to (mirrorsize div 2) - 1 do
begin
glBegin(GL_QUAD_STRIP);
for J := -(mirrorsize div 2) to (mirrorsize div 2) do
begin
RenderVertex(I / M_DETAIL - 0.5,
J / M_DETAIL - 0.5, 0.0);
RenderVertex((I + 1) / M_DETAIL - 0.5,
J / M_DETAIL - 0.5, 0.0);
end;
glEnd;
end;
glpopmatrix();
gldisable(GL_TEXTURE_2D);
glenable(GL_LIGHTING);
//draw the scene...
drawobjects();
// Flush the OpenGL Buffer
glFlush();
end;
[/code]