PDA

View Full Version : trouble casting a shadow



nellum8
05-15-2009, 12:00 PM
Hello! I have a project for my computer graphics programming class which should contain a ballon casting a shadow on the ground. I have finished the project and it meets the specifiac tions: the ballon moves, the light source moves, the background is texturesd etc, but I can't cast the shadow on the floor. I am going to show you the code for my rendering method and the code that calculates my shadow matrix. I have written some comments in english (most of them are in romanian). If more comments are needed, please let me know! I have to finish the project by next week! Any help is highly appreciated! Thank you.

rendering method:

void Proiect::DeseneazaScena()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glLoadIdentity();

//Draw Sun with light position
glTranslatef(pozitieLumina[0],pozitieLumina[1],pozitieLumina[2]);

obiecte[5]->Deseneaza();

glLoadIdentity();

//If lights are on,do the following
if(lumini)
{
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0,GL_DIFFUSE,culoareLumina);
glLightfv(GL_LIGHT0,GL_AMBIENT,culoareAmbient);
glLightfv(GL_LIGHT0,GL_SPECULAR,culoareSpecular);
glLightfv(GL_LIGHT0,GL_POSITION,pozitieLumina);
}

//Translate and rotate scene
glTranslatef(0.0,100.0,0.0);
glRotatef(rotatieCamera.X,1.0,0.0,0.0);
glRotatef(rotatieCamera.Y,0.0,1.0,0.0);
glRotatef(rotatieCamera.Z,0.0,0.0,1.0);

//Incepem cu umbra. Aici vom desena obiectul ca mai jos, numai ca vom inmulti matricea de modelare vizualizare cu
// matricea de umbra si vom folosi buffer-ul sablon pentru a desena umbra numai pe planul Lunii.

//We beign rendering the shadow
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
glDepthMask(GL_FALSE);

glEnable(GL_STENCIL_TEST);

glStencilFunc(GL_ALWAYS,1,0xFFFFFFFF);
glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);

//Luna - nu apare pe ecran. Desenam doar ca sa pregatim spatiul in care va putea fi desenata umbra
//The flat plane
glPushMatrix();

glTranslatef(0.0,-230.0,-20.0);
glRotatef(90.0,0.0,1.0,0.0);

obiecte[2]->Deseneaza();

glPopMatrix();

glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
glDepthMask(GL_TRUE);

glStencilFunc(GL_EQUAL,1,0xFFFFFFFF);
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);

glColor4f(1.0,1.0,1.0,1.0);

//Luna
//The flat plane
glPushMatrix();

glTranslatef(0.0,-230.0,-20.0);
glRotatef(90.0,0.0,1.0,0.0);

obiecte[2]->Deseneaza();

glPopMatrix();

glColor4f(1.0,0.0,0.0,1.0);

glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);

glStencilOp(GL_KEEP,GL_KEEP,GL_INCR);
CalculeazaMatriceUmbra(); //Calculate shadow matrix

//Balonul - umbra
//The shadow
glPushMatrix();

glMultMatrixf((float*)matriceUmbra); //Multiply by shaodw matrix
obiecte[0]->Muta(timer.TimpScursFrame());

glTranslatef(obiecte[0]->pozitie.X,0.0,-300.0 + obiecte[0]->pozitie.Z);
glRotatef(obiecte[0]->rotatie.X,1.0,0.0,0.0);
glRotatef(obiecte[0]->rotatie.Y,0.0,1.0,0.0);
glRotatef(obiecte[0]->rotatie.Z,0.0,0.0,1.0);
glRotatef(90.0,1.0,0.0,0.0);

obiecte[0]->Deseneaza();

//Sforile - Fata
//These are objects which have a position realtive to the previously drawn object
glPushMatrix();

glTranslatef(28.0,-18.0,0.0);
glRotatef(-10.0,0.0,1.0,0.0);
obiecte[3]->Deseneaza();

glPopMatrix();

glPushMatrix();

glTranslatef(-28.0,-18.0,0.0);
glRotatef(10.0,0.0,1.0,0.0);
obiecte[3]->Deseneaza();

glPopMatrix();

//Sforile - Spate
glPushMatrix();

glTranslatef(28.0,18.0,0.0);
glRotatef(-10.0,0.0,1.0,0.0);
glRotatef(15.0,1.0,0.0,0.0);
obiecte[3]->Deseneaza();

glPopMatrix();

glPushMatrix();

glTranslatef(-28.0,18.0,0.0);
glRotatef(10.0,0.0,1.0,0.0);
glRotatef(15.0,1.0,0.0,0.0);
obiecte[3]->Deseneaza();

glPopMatrix();

//Baza
glPushMatrix();

glTranslatef(1.0,-10.0,70.0);
obiecte[4]->Deseneaza();

glPopMatrix();

glPopMatrix();

glEnable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glDisable(GL_STENCIL_TEST);

glColor4f(1.0,1.0,1.0,1.0);

//Balonul
//The solid object
glPushMatrix();

obiecte[0]->Muta(timer.TimpScursFrame());
glTranslatef(obiecte[0]->pozitie.X,obiecte[0]->pozitie.Y,-300.0 + obiecte[0]->pozitie.Z);
glRotatef(obiecte[0]->rotatie.X,1.0,0.0,0.0);
glRotatef(obiecte[0]->rotatie.Y,0.0,1.0,0.0);
glRotatef(obiecte[0]->rotatie.Z,0.0,0.0,1.0);
glRotatef(90.0,1.0,0.0,0.0);

obiecte[0]->Deseneaza();

//Sforile - Fata
glPushMatrix();

glTranslatef(28.0,-18.0,0.0);
glRotatef(-10.0,0.0,1.0,0.0);
obiecte[3]->Deseneaza();

glPopMatrix();

glPushMatrix();

glTranslatef(-28.0,-18.0,0.0);
glRotatef(10.0,0.0,1.0,0.0);
obiecte[3]->Deseneaza();

glPopMatrix();

//Sforile - Spate
glPushMatrix();

glTranslatef(28.0,18.0,0.0);
glRotatef(-10.0,0.0,1.0,0.0);
glRotatef(15.0,1.0,0.0,0.0);
obiecte[3]->Deseneaza();

glPopMatrix();

glPushMatrix();

glTranslatef(-28.0,18.0,0.0);
glRotatef(10.0,0.0,1.0,0.0);
glRotatef(15.0,1.0,0.0,0.0);
obiecte[3]->Deseneaza();

glPopMatrix();

//Baza
glPushMatrix();

glTranslatef(1.0,-10.0,70.0);
obiecte[4]->Deseneaza();

glPopMatrix();

glPopMatrix();

//Fundalul
//Background
glPushMatrix();

glTranslatef(0.0,0.0,-2500.0);
glRotatef(90.0,1.0,0.0,0.0);

obiecte[1]->Deseneaza();

glPopMatrix();

glFlush();
}

shadow calculations method:

void Proiect::CalculeazaMatriceUmbra()
{
//dot product between light position and ground plane (0.0,1.0,0.0,1.0)
float produs = plan[0] * pozitieLumina[0] + plan[1] * pozitieLumina[1] + plan[2] * pozitieLumina[2] + plan[3] * pozitieLumina[3];

//set the right values in the matrix
matriceUmbra[0][0] = produs - pozitieLumina[0] * plan[0];
matriceUmbra[1][0] = 0.f - pozitieLumina[0] * plan[1];
matriceUmbra[2][0] = 0.f - pozitieLumina[0] * plan[2];
matriceUmbra[3][0] = 0.f - pozitieLumina[0] * plan[3];

matriceUmbra[0][1] = 0.f - pozitieLumina[1] * plan[0];
matriceUmbra[1][1] = produs - pozitieLumina[1] * plan[1];
matriceUmbra[2][1] = 0.f - pozitieLumina[1] * plan[2];
matriceUmbra[3][1] = 0.f - pozitieLumina[1] * plan[3];

matriceUmbra[0][2] = 0.f - pozitieLumina[2] * plan[0];
matriceUmbra[1][2] = 0.f - pozitieLumina[2] * plan[1];
matriceUmbra[2][2] = produs - pozitieLumina[2] * plan[2];
matriceUmbra[3][2] = 0.f - pozitieLumina[2] * plan[3];

matriceUmbra[0][3] = 0.f - pozitieLumina[3] * plan[0];
matriceUmbra[1][3] = 0.f - pozitieLumina[3] * plan[1];
matriceUmbra[2][3] = 0.f - pozitieLumina[3] * plan[2];
matriceUmbra[3][3] = produs - pozitieLumina[3] * plan[3];
}

nellum8
05-15-2009, 12:07 PM
Ok, I forgot to make some specifications. When I refer to a plane in my comments, i am actually refering to the flat piece of ground on which the shadow will be cast.So i enable the stencil buffer test,set the right operations, disable writing to the color buffer and depth buffer, draw this plane, enable the color buffer and depth buffer,update stencil operations, draw the plane again, disable lighting, texturing, depth test and enable blending,draw the shadow of the objects of the ballon(which is the same piece of code as drawing the real objects except that it is preceeded by a multiplication with the shadow matrix),enbale stuff again, draw the real objects, draw background, flush. This is, in short, what the method does, in this order(I hope). Why doesn't the shadow appear?