Messing with shadows, but all I see is junk

Started by
0 comments, last by Meganan 17 years, 12 months ago
I was following the DevMaster.net shadow tutorial from www.devmaster.net/articles/projectiveshadows/ I'm doing it in C and SDL and my screen looks really weird. Does anyone know what's wrong? The screen is all staticky and it has a weird flickering thing going on. Could I have just forgotten to set a value?

#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include <SDL/SDL_image.h>

int textureid;
float shadowmatrix[16];
float LightAmbient[] = {0.2f, 0.2f, 0.2f, 1.0f};
GLfloat light_position[] = {2.0f, 3.1f, 2.0f, 1.0f};
float LightDiffuse[] = {1.0, 1.0, 1.0, 1.0}; 
float LightSpecular[] = {1.0, 1.0, 1.0, 1.0};
float plane[]={0,1,0,0};
    
initgl(int width, int height)
{
     if(SDL_Init(SDL_INIT_VIDEO) < 0)
     {
      printf("SDL was not initialized\n");                            
     }
    SDL_SetVideoMode(width, height, 0, SDL_OPENGL | SDL_HWSURFACE | SDL_FULLSCREEN);
    glViewport(0, 0, width, height);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    
    glEnable(GL_DEPTH_TEST);
    //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 
    glLightfv(GL_LIGHT0,GL_POSITION,light_position);
    // Enable a single OpenGL light.
    glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
    	glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpecular);
        glLightfv(GL_LIGHT0,GL_AMBIENT,LightAmbient);
        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);
    glShadeModel(GL_SMOOTH);
    gluLookAt(0.0,0.0,0.0,0.0,0.0,-5.0,0.0,1.0,0.0);
    gluPerspective(45,width/height,1,1000);
    
    glMatrixMode(GL_PROJECTION);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glMatrixMode(GL_MODELVIEW);

}
void initsdl(int width, int height)
{
     if(SDL_Init(SDL_INIT_VIDEO) < 0)
     {
      printf("SDL was not initialized\n");                            
     }
    SDL_SetVideoMode(width, height, 0, SDL_OPENGL | SDL_HWSURFACE | SDL_FULLSCREEN);
    glViewport(0,0,width,height);
}

void CalcShadowMatrix(float shadowmatrix[16],float light_position[4],float plane[4])
{
   float dot;

	// dot product of plane and light position
	dot =	plane[0] * light_position[0] + 
			plane[1] * light_position[1] + 
			plane[1] * light_position[2] + 
			plane[3] * light_position[3];

	// first column
	shadowmatrix[0] = dot - light_position[0] * plane[0];
	shadowmatrix[4] = 0.0f - light_position[0] * plane[1];
	shadowmatrix[8] = 0.0f - light_position[0] * plane[2];
	shadowmatrix[12] = 0.0f - light_position[0] * plane[3];

	// second column
	shadowmatrix[1] = 0.0f - light_position[1] * plane[0];
	shadowmatrix[5] = dot - light_position[1] * plane[1];
	shadowmatrix[9] = 0.0f - light_position[1] * plane[2];
	shadowmatrix[13] = 0.0f - light_position[1] * plane[3];

	// third column
	shadowmatrix[2] = 0.0f - light_position[2] * plane[0];
	shadowmatrix[6] = 0.0f - light_position[2] * plane[1];
	shadowmatrix[10] = dot - light_position[2] * plane[2];
	shadowmatrix[14] = 0.0f - light_position[2] * plane[3];

	// fourth column
	shadowmatrix[3] = 0.0f - light_position[3] * plane[0];
	shadowmatrix[7] = 0.0f - light_position[3] * plane[1];
	shadowmatrix[11] = 0.0f - light_position[3] * plane[2];
	shadowmatrix[15] = dot - light_position[3] * plane[3];
}

void InitializeForShadows()
{
     int  mode;
	// what color to clear to in color buffer
	glClearColor(0.0, 0.0, 0.0, 0.0);

	// Enable a single OpenGL light.
	glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
	glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpecular);
	glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_DEPTH_TEST);

	glEnable(GL_TEXTURE_2D);
	// forandre litt på denne, hehe
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

	//LoadTexture("marble.bmp", textureid);
	//LoadTexture("cubetexture.bmp", textureid);

    SDL_Surface *surface;
    surface = IMG_Load("Marble Texture.jpg");
    
    if(!surface)
    {
     printf("Texture not found\n");
    }
    
    
    // work out what format to tell glTexImage2D to use...
        if (surface->format->BytesPerPixel == 3) { // RGB 24bit

                mode = GL_RGB;

        } else if (surface->format->BytesPerPixel == 4) { // RGBA 32bit

                mode = GL_RGBA;

        } else {

                SDL_FreeSurface(surface);
               

        }

        // create one texture name
        glGenTextures(1, &textureid);

        // tell opengl to use the generated texture name
        glBindTexture(GL_TEXTURE_2D, textureid);

        // this reads from the sdl surface and puts it into an opengl texture
        glTexImage2D(GL_TEXTURE_2D, 0, mode, surface->w, surface->h, 0, mode, GL_UNSIGNED_BYTE, surface->pixels);

        // these affect how this texture is drawn later on...
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
        // clean up
        SDL_FreeSurface(surface);
        
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	// step 2
	CalcShadowMatrix(shadowmatrix, light_position, plane);
}






int main(int argc, char *argv[])
{
    
    int done = 0;
   
    SDL_Event event;
    
    GLUquadricObj *qobj;
     /* Create a glu quadric object */
     qobj = gluNewQuadric();
    
    initsdl(1024,768);
    InitializeForShadows();
    
    glPointSize(2);
    
    
        
    while(!done)
    {
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glLoadIdentity();
     
     
			
     
     

     
			// turning off writing to the color buffer and depth buffer so we only 
			// write to stencil buffer
			glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
			glDepthMask(GL_FALSE);

			// enable stencil buffer
			glEnable(GL_STENCIL_TEST);
			// write a one to the stencil buffer everywhere we are about to draw
			glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);
			// this is to always pass a one to the stencil buffer where we draw
			glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
			
			
      glEnable(GL_TEXTURE_2D);
      glBindTexture(GL_TEXTURE_2D,textureid);
                    
     #if 1
     glBegin(GL_QUADS);   /* floor */
                      
                        glNormal3f(0.0, 1.0, 0.0);
                       glTexCoord2f(0,0);
                       glVertex3f(-1.0f,-1.0f,0.0f);      /* Bottom left*/
                       
                       glTexCoord2f(1,0);
                       glVertex3f(-0.5f,15.0f,-20.0f);     /* Top left */
                       
                       glTexCoord2f(1,1);
                       glVertex3f(0.5f,15.0f,-20.0f);     /* Top right */
                       glTexCoord2f(1,0);
                       
                       glVertex3f(1.0f,-1.0f,0.0f);      /* Bottom right*/
     glEnd();
     #endif
    glDisable(GL_TEXTURE_2D);
    
    glDisable(GL_LIGHTING);
    glDisable(GL_DEPTH_TEST); 
    glEnable(GL_BLEND);
    // make sure that we don't draw at any raster position more than once. Using GL_INCR
    // here is smart because the value of the area in stencil buffer wich will be drawn to
	// increases to 2, and earlier we have set the stencil buffer function to only write to
	// areas with a one. This means that a shadow will not be draw 2 times on the same area!
	glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); 
    
    glMultMatrixf(shadowmatrix);    
    
    gluSphere(qobj, 0.2, 64, 64); 
    
   	glEnable(GL_TEXTURE_2D);
	glEnable(GL_DEPTH_TEST);
	glDisable(GL_BLEND);
	glEnable(GL_LIGHTING);
	
	glDisable(GL_STENCIL_TEST);
	gluQuadricNormals(qobj,GLU_SMOOTH);
    gluSphere(qobj, 0.2, 64, 64); 
	
	
    SDL_GL_SwapBuffers();
     
     
     
     while(SDL_PollEvent(&event))
     {
      switch(event.type)
      {                                
      case SDL_KEYDOWN:
           switch(event.key.keysym.sym)
           {
            case SDLK_ESCAPE:
                 done = 1;
                 break;
          }
          break;
    
      }                            
     }
    }
    SDL_Quit();
    return 0;
}


Advertisement
This might not even be worth mentioning but shouldn't:

initgl(int width, int height)

have a void or something out the front, sort of like:

void initgl(int width, int height)

probably not you're problem though so sorry i couldn't help further
<-> Rate someone badly if they say something that has absolutely nothing to do with your problem; don't rate people badly because they tried to help you with their limited knowledge. <->

This topic is closed to new replies.

Advertisement