I have a very simple code, that just draws a building, I want to add the shadow of the building. I have tried many code samples, but either they are too complicated with a lit of objects drawn. or just too vague. How can I get the shadow of my building?
#include "GLee/GLee.h" //GL header file, including extensions
#include "glut.h"
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include "tga.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
char g_SelectedColor = 'w';
int g_Width;
int g_Height;
int a=0.0 ,b=0.0, c=500, d=0.0, e=0.0, f=0.0,g=0.0,h=1.0,i=0.0;
static int rotationAngle=0;
void init();
void myMouseFunction( int button, int state, int mouseX, int mouseY );
void myKeyboardFunction( unsigned char key, int mouseX, int mouseY );
void Reshape( int width, int height );
void timer( int val );
void display();
void drawBuilding();
void menu(int);
// Assign a default value
float light_diffuse[] = { 0.8, 0.8, 0.8, 1.0 };
float light_ambient[] = { 0.1, 1.1, 0.0, 0.0 };
float light_specular[] = { 0.5, 0.5, 0.9, 1.0 };
float light_position[] = { 0.0, 10.0, 0.0, 1.0 };
void selectMessage( int val )
{
if(val==2)
{
glBegin(GL_POLYGON);
glVertex3f(0.0,0.0,0.0);
glVertex3f(0.0,200.0,0.0);
glVertex3f(200.0,200.0,0.0);
glVertex3f(200.0,0.0,0.0);
glVertex3f(0.0,0.0,0.0);
glEnd();
}
}
int main(int argc, char** argv)
{
glutCreateMenu(menu);
glutAddMenuEntry("View1", 1);
glutAddMenuEntry("View2", 2);
glutAttachMenu(GLUT_RIGHT_BUTTON);
g_Width =1200; g_Height = 600;
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
// glutInitWindowSize( g_Width, g_Height );
//glutFullScreen();
glutInitWindowPosition( 50, 50 );
glutCreateWindow( "CHECK" );
init();
glutMouseFunc( myMouseFunction );
glutKeyboardFunc( myKeyboardFunction );
glutReshapeFunc( Reshape );
glutDisplayFunc( display );
glutMainLoop();
return 0;
}
void init(void)
{
glutAttachMenu(GLUT_RIGHT_BUTTON);
glClearColor( 1.0, 1.0, 1.0, 1.0 );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 50.0, 1.0, 200, 1000 );
//glOrtho( -5.0, +5.0, -5.0, +5.0, +5.0, -5.0 );
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient );
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular );
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glShadeModel(GL_SMOOTH);
//glShadeModel(GL_FLAT);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
//glCullFace(GL_FRONT_AND_BACK );
glDisable(GL_CULL_FACE );
glMatrixMode( GL_MODELVIEW );
if ( loadTGA ("im1.tga", 10 ) == false )
printf ("\nError: File myQuakeTexture.tga not found!");
if ( loadTGA ("im2.tga", 11 ) == false )
printf ("\nError: File myQuakeTexture.tga not found!");
}
void myMouseFunction( int button, int state, int mouseX, int mouseY )
{
}
void myKeyboardFunction( unsigned char key, int mouseX, int mouseY )
{
switch( key )
{
case 'r':
{
glClearColor( 0.0, 0.0, 1.0, 1.0 );
glRotatef( rotationAngle++, 0.0, 1.0, 0.0 );
// drawBuilding();
//display();
}
case 'R':
case 'g':
case 'G':
case 'b':
case 'B':
case 'w':
case 'W':
g_SelectedColor = key;
break;
case '1':
case '2':
case '3':
case '4':
case '5':
break;
case 27: // Esc key
exit(0);
break; // redundant
default:
break;
}
}
void Reshape( int width, int height )
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
g_Width = width;
g_Height = height;
glViewport (0, 0, g_Width, g_Height);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective( 50.0, 1.0, 200, 1000 );
//glOrtho( -5.0, +5.0, -5.0, +5.0, +5.0, -5.0 );;
}
void timer( int val )
{
display();
}
static float firstAngle=0;
void drawBuilding()
{
float DoorMaterial[4] = { 0.5, 0.2, 1.3, 1.0 };
//
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D ,10);
glTranslatef(30,-180,0);
//Building 1
//Front
glBegin(GL_POLYGON);
glVertex3f(0.0,0.0,0.0);
glTexCoord2d(1,1);
glVertex3f(0.0,400.0,0.0);
glTexCoord2d(0,1);
glVertex3f(70.0,400.0,0.0);
glTexCoord2d(0,0);
glVertex3f(70.0,0.0,0.0);
glTexCoord2d(1,0);
glVertex3f(0.0,0.0,0.0);
glEnd();
//Back
glBegin(GL_POLYGON);
glVertex3f(0.0,0.0,-50.0);
glTexCoord2d(1,1);
glVertex3f(0.0,400.0,-50.0);
glTexCoord2d(0,1);
glVertex3f(70.0,400.0,-50.0);
glTexCoord2d(0,0);
glVertex3f(70.0,0.0,-50.0);
glTexCoord2d(1,0);
glVertex3f(0.0,0.0,-50.0);
glEnd();
//Left
glBegin(GL_POLYGON);
glVertex3f(0.0,0.0,0.0);
glTexCoord2d(1,1);
glVertex3f(0.0,400.0,0.0);
glTexCoord2d(0,1);
glVertex3f(0.0,400.0,-50.0);
glTexCoord2d(0,0);
glVertex3f(0.0,0.0,-50.0);
glTexCoord2d(1,0);
glVertex3f(0.0,0.0,0.0);
glEnd();
//Right
glBegin(GL_POLYGON);
glVertex3f(70.0,0.0,0.0);
glTexCoord2d(1,1);
glVertex3f(70.0,400.0,0.0);
glTexCoord2d(0,1);
glVertex3f(70.0,400.0,-50.0);
glTexCoord2d(0,0);
glVertex3f(70.0,0.0,-50.0);
glTexCoord2d(1,0);
glVertex3f(70.0,0.0,0.0);
glEnd();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D ,11);
}
void menu(int item)
{
switch (item)
{
case 1:
{
a=-500, b=0, c=300,d=0,e=0,f=0,g=0,h=1,i=0;
}
break;
case 2:
{
a=0, b=300, c=500,d=0,e=0,f=0,g=0,h=1,i=0;
drawBuilding();
}
}
}
void display()
{
glRotatef( rotationAngle++, 0.0, 1.0, 0.0 );
glutFullScreen();
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( a, b, c,
d, e, f,
g, h, i );
glRotatef( rotationAngle++, 0.0, 1.0, 0.0 );
//
drawBuilding();
glDisable(GL_TEXTURE_2D);
// this tells glut to call the 'timer' function in 33 milliseconds
// i.e. this way we will draw 1000/33 = 30 times a second
glutTimerFunc( 33, timer, 0 );
glutSwapBuffers();
printf(".");
}
Having shadows in a OpenGL rendered scene is not a matter of simply enabling some feature. OpenGL by itself just draws points, lines and triangles. One at a time and without any context between them. It’s up to the user to provide the context.
Drawing shadows can be implemented in several ways, but the most used are
and
Explaining them here would largely surpass the limits of a StackOverflow question. I hence refer you to the Wikipedia articles on them (and the resources linked by those)
http://en.wikipedia.org/wiki/Shadow_volume
http://en.wikipedia.org/wiki/Shadow_mapping