PDA

View Full Version : Texture Projection



Bruno
08-30-2006, 07:23 AM
Hello,

Well, this is the problem.,
I'm currently rendering the shadows(trees) of a outdoor scene to a texture, and projecting it back on the terrain.
The light source is above the player position, and the light destiny is the player itself.
This works ok, except as the player moves, so does the ligth and so do the shadows on the terrain
So, i wanted to do all this with a orthogonal matrix instead of a perspective matrix.
So far, i was able to render the trees to a texture using a orthogonal matrix, but i'm having huge problems in projecting her back to the terrain.,
I'm gonna post the working source for the prespective matrix, and the modified source for the orthogonal matrix., maybe you guys can spot what am i doing wrong.,
Basically the code calls "Build_ShadowMap" to build the shadowmap, and "Render_Projected_Trees" is later called, to render it on top of the terrain.
I hope someone can help,
thanks,
Bruno

Using a Prespective Matrix



void Level::Setup_Texture_Matrix(int xRes,int yRes)
{
// Prepare the texture matrix for the projected texture:
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(0.5, 0.5, 0);
glScalef(0.5, 0.5, 1);
gluPerspective(Engine.FOV, g_window->init.width/g_window->init.height, 0.03f, 135.0f);
glGetFloatv(GL_TEXTURE_MATRIX, Shadow_Matrix);
glMatrixMode(GL_MODELVIEW);
// Set up TexGen:
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glEnable(GL_TEXTURE_GEN_Q);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(Engine.FOV, g_window->init.width/g_window->init.height, 0.03f, 135.0f);
glMatrixMode(GL_MODELVIEW);
}








void Level::Build_Shadowmap()
{

glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, g_BIG_SHADOWframeBuffer );
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Big_Shadow, 0 );
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, g_BIG_SHADOWdepthRenderBuffer );
glViewport( 0, 0, 2048, 2048 );


Setup_Texture_Matrix(2048,2048);

float PS[]={1, 0, 0, 0};
float PT[]={0, 1, 0, 0};
float PR[]={0, 0, 1, 0};
float PQ[]={0, 0, 0, 1};

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
/////////////////////////////////////////////////////////////////////////////////////////////

gluLookAt(CameraP[0]+2,
CameraP[1] + 100,
CameraP[2],
CameraP[0],
CameraP[1],
CameraP[2],
0,1,0);

Render_TREES_To_Texture();

glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_GEN_Q);

glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
glViewport( 0, 0, g_window->init.width, g_window->init.height );


}



void Level::Setup_Shadow_Receivers()
{
float PS[]={1, 0, 0, 0};
float PT[]={0, 1, 0, 0};
float PR[]={0, 0, 1, 0};
float PQ[]={0, 0, 0, 1};

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
// Set the TexGen planes:
glTexGenfv(GL_S, GL_EYE_PLANE, PS);
glTexGenfv(GL_T, GL_EYE_PLANE, PT);
glTexGenfv(GL_R, GL_EYE_PLANE, PR);
glTexGenfv(GL_Q, GL_EYE_PLANE, PQ);

//setTU0;
// Set the TexGen planes:
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glEnable(GL_TEXTURE_GEN_Q);
// Draw the shadow receivers using the projected shadow texture:
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, shadow);


glMatrixMode(GL_TEXTURE);
glLoadMatrixf(Shadow_Matrix);

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(Camera_Matrix);

}




/// To make the projection on the terrain

void Level::Render_Projected_Trees(Camera pos)
{


glGetFloatv(GL_PROJECTION_MATRIX, Proj_MAT2);
glActiveTextureARB(GL_TEXTURE0_ARB);
glGetFloatv(GL_TEXTURE_MATRIX, Tex_MAT);

Setup_Shadow_Receivers();

glMatrixMode(GL_TEXTURE);
glActiveTextureARB(GL_TEXTURE0_ARB);
glLoadIdentity();

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(Engine.FOV, g_window->init.width/g_window->init.height, 0.03f-0.003, cull_Dis);//lscape->land_options.view_distance); // ???
glMatrixMode(GL_MODELVIEW);

glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);

glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

glDisable(GL_CULL_FACE);
glEnable(GL_ALPHA_TEST);

glAlphaFunc( GL_NOTEQUAL, 1);

glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT);
glBlendFunc(0,0x0303);

glColor4f(0.2, 0.2,0.2,0.5);

glEnable(GL_BLEND);


glGetFloatv(GL_PROJECTION_MATRIX, Proj_MAT);


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(Engine.FOV, g_window->init.width/g_window->init.height, 0.033-0.003,550);

glMatrixMode(GL_MODELVIEW);
glGetFloatv(GL_MODELVIEW_MATRIX,Cam_Matrix);



glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glEnable(GL_TEXTURE_GEN_Q);
lscape->Enable_RS();
lscape->Position_In_World = Position_In_World;
myFog.OriginalFog();
glEnable(GL_FOG);
glDepthMask(0);

glPushMatrix();

if(nShadow_far > 0) glBindTexture(GL_TEXTURE_2D,Big_Shadow);


glTranslatef(-Position_In_World[0],-Position_In_World[1],-Position_In_World[2]);



glMatrixMode(GL_TEXTURE);
glGetFloatv(GL_TEXTURE_MATRIX,Texture1_Matrix);
glLoadIdentity();

glTranslatef(0.5,0.5,0);

glScalef(0.5, 0.5, 1);


gluPerspective(Engine.FOV, g_window->init.width/g_window->init.height, 0.033, 550);

gluLookAt(CameraP[0]+2,
CameraP[1] + 100,
CameraP[2],
CameraP[0],
CameraP[1],
CameraP[2],
0,1,0);

glMatrixMode(GL_MODELVIEW);

lscape->RenderS_terrain();

glActiveTextureARB(GL_TEXTURE0_ARB);
glMatrixMode(GL_TEXTURE);


}Using a Orthogonal Matrix


void Level::Setup_Texture_Matrix(int xRes,int yRes)
{
float P_roj[16];

// Prepare the texture matrix for the projected texture:
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(0.5, 0.5, 0);
glScalef(0.5, 0.5, 1);
glOrtho(-512,512,-512,512,-100,10000);

glGetFloatv(GL_TEXTURE_MATRIX, Shadow_Matrix);
glMatrixMode(GL_MODELVIEW);
// Set up TexGen:
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glEnable(GL_TEXTURE_GEN_Q);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
// Set a square viewport for the texture:
//glViewport(0, 0, shadowX,shadowY);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-512,512,-512,512,-100,10000);
glMatrixMode(GL_MODELVIEW);


}






void Level::Build_Shadowmap()
{

glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, g_BIG_SHADOWframeBuffer );
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Big_Shadow, 0 );
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, g_BIG_SHADOWdepthRenderBuffer );
glViewport( 0, 0, 2048, 2048 );


Setup_Texture_Matrix(2048,2048);

float PS[]={1, 0, 0, 0};
float PT[]={0, 1, 0, 0};
float PR[]={0, 0, 1, 0};
float PQ[]={0, 0, 0, 1};

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
/////////////////////////////////////////////////////////////////////////////////////////////

gluLookAt(CameraP[0]+2,
CameraP[1] + 100,
CameraP[2],
CameraP[0],
CameraP[1],
CameraP[2],
0,1,0);

Render_TREES_To_Texture();

glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_GEN_Q);

glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
glViewport( 0, 0, g_window->init.width, g_window->init.height );

}


void Level::Setup_Shadow_Receivers()
{
float PS[]={1, 0, 0, 0};
float PT[]={0, 1, 0, 0};
float PR[]={0, 0, 1, 0};
float PQ[]={0, 0, 0, 1};

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
// Set the TexGen planes:
glTexGenfv(GL_S, GL_EYE_PLANE, PS);
glTexGenfv(GL_T, GL_EYE_PLANE, PT);
glTexGenfv(GL_R, GL_EYE_PLANE, PR);
glTexGenfv(GL_Q, GL_EYE_PLANE, PQ);

//setTU0;
// Set the TexGen planes:
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glEnable(GL_TEXTURE_GEN_Q);
// Draw the shadow receivers using the projected shadow texture:
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, shadow);


glMatrixMode(GL_TEXTURE);
glLoadMatrixf(Shadow_Matrix);

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(Camera_Matrix);

}










/// To make the projection on the terrain

void Level::Render_Projected_Trees(Camera pos)
{


glGetFloatv(GL_PROJECTION_MATRIX, Proj_MAT2);
glActiveTextureARB(GL_TEXTURE0_ARB);
glGetFloatv(GL_TEXTURE_MATRIX, Tex_MAT);

Setup_Shadow_Receivers();

glMatrixMode(GL_TEXTURE);
glActiveTextureARB(GL_TEXTURE0_ARB);
glLoadIdentity();

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-512,512,-512,512,-100,10000);
glMatrixMode(GL_MODELVIEW);

glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);

glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

glDisable(GL_CULL_FACE);
glEnable(GL_ALPHA_TEST);

glAlphaFunc( GL_NOTEQUAL, 1);

glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT);
glBlendFunc(0,0x0303);

glColor4f(0.2, 0.2,0.2,0.5);

glEnable(GL_BLEND);


glGetFloatv(GL_PROJECTION_MATRIX, Proj_MAT);


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-512,512,-512,512,-100,10000);

glMatrixMode(GL_MODELVIEW);
glGetFloatv(GL_MODELVIEW_MATRIX,Cam_Matrix);



glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glEnable(GL_TEXTURE_GEN_Q);
lscape->Enable_RS();
lscape->Position_In_World = Position_In_World;
myFog.OriginalFog();
glEnable(GL_FOG);
glDepthMask(0);

glPushMatrix();

if(nShadow_far > 0) glBindTexture(GL_TEXTURE_2D,Big_Shadow);


glTranslatef(-Position_In_World[0],-Position_In_World[1],-Position_In_World[2]);



glMatrixMode(GL_TEXTURE);
glGetFloatv(GL_TEXTURE_MATRIX,Texture1_Matrix);
glLoadIdentity();

glTranslatef(0.5,0.5,0);

glScalef(0.5, 0.5, 1);


glOrtho(-512,512,-512,512,-100,10000);

gluLookAt(CameraP[0]+2,
CameraP[1] + 100,
CameraP[2],
CameraP[0],
CameraP[1],
CameraP[2],
0,1,0);

glMatrixMode(GL_MODELVIEW);

lscape->RenderS_terrain();

glActiveTextureARB(GL_TEXTURE0_ARB);
glMatrixMode(GL_TEXTURE);


}

Komat
08-30-2006, 12:47 PM
You replaced too many gluPerspective calls in the ortho version. You replaced calls that are used to setup the normal camera with which you are looking at the scene.

Bruno
08-31-2006, 04:36 AM
Thanks, that was the problem,
fixed it :)