#include #include "SDL.h" #include #define start_width 800 #define start_height 600 volatile int done = 0; volatile bool test = false; volatile bool blur = false; int current_time; int last_time; int charxvel = 0, charyvel = 0; float light_pos[4] = { 5.0f, 6.0f, -1.0f , 1.0f }; float light_intensity[4] = { 1.0f, 1.0f, 1.0f , 1.0f }; GLfloat light_modelview_matrix[16]; GLfloat light_projection_matrix[16]; #define tex_count 5 GLuint textures[tex_count]; GLuint fbo[tex_count]; #define tex_size 512 #define blur_coeff 0.25 struct ShaderProgram { GLuint vertex; GLuint fragment; GLuint program; } ShadowShader, ShadowRenderShader, BlurShader; const char *shadow_shader_vertex = "void main(void)\n" "{\n" " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" "}\n" ; const char *shadow_shader_fragment = "void main(void)\n" "{\n" " float dx = dFdx(gl_FragCoord.z);\n" " float dy = dFdy(gl_FragCoord.z);\n" " gl_FragDepth = gl_FragCoord.z + 0.25*(dx*dx+dy*dy);\n" " gl_FragDepth = gl_FragCoord.z * gl_FragCoord.z;\n" "}\n" ; const char *shadow_render_shader_vertex = "uniform sampler2D depth_map;\n" "uniform sampler2D depth_map_square;\n" "uniform mat4 light_modelview_matrix;\n" "uniform mat4 light_projection_matrix;\n" "uniform vec4 light_pos;\n" "uniform vec4 light_intensity;\n" "\n" "varying vec4 dt_color;\n" "varying vec4 light_coord;\n" "\n" "void main(void)\n" "{\n" " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" " dt_color = gl_Color;\n" " light_coord = light_projection_matrix * light_modelview_matrix * gl_Vertex;\n" "}\n" ; const char *shadow_render_shader_fragment = "uniform sampler2D depth_map;\n" "uniform sampler2D depth_map_square;\n" "uniform mat4 light_modelview_matrix;\n" "uniform mat4 light_projection_matrix;\n" "uniform vec4 light_pos;\n" "uniform vec4 light_intensity;\n" "\n" "varying vec4 dt_color;\n" "varying vec4 light_coord;\n" "\n" "void main(void)\n" "{\n" " light_coord.xyz = light_coord.xyz/light_coord.w;\n" " light_coord.w = 1.0/light_coord.w;\n" " light_coord.xyz = (light_coord.xyz + 1.0) / 2.0;\n" " float depth = texture2D(depth_map, light_coord).r;" " float depth_square = texture2D(depth_map_square, light_coord).r;" " vec4 color = dt_color;\n" " if ((light_coord.x >= 0.0) && (light_coord.x <= 1.0) && (light_coord.y >= 0.0) && (light_coord.y <= 1.0))\n" " {\n" " if (light_coord.z > depth)\n" " {\n" " float b = depth_square - depth*depth;\n" " b = max(b,0.00002);\n" " float p = b / (b + (light_coord.z - depth) * (light_coord.z - depth));\n" " color.rgb *= p;\n" " }\n" " }\n" //" else\n" //" {\n" //" color = vec4(0.5, 0.5, 0.5, 1.0);\n" //" }\n" " gl_FragColor = color;\n" "}\n" ; const char *blur_shader_vertex = "void main(void)\n" "{\n" " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" " gl_TexCoord[0] = gl_MultiTexCoord0;\n" "}\n" ; const char *blur_shader_fragment = "uniform vec2 ScaleU;\n" "uniform sampler2D textureSource;\n" "\n" "// Portability prevented us from using a const array of vec2\n" "// Mac shader compiler don't support it.\n" "/*\n" "const vec2 gaussFilter[7] = \n" "{ \n" " -3.0, 0.015625,\n" " -2.0, 0.09375,\n" " -1.0, 0.234375,\n" " 0.0, 0.3125,\n" " 1.0, 0.234375,\n" " 2.0, 0.09375,\n" " 3.0, 0.015625\n" "};\n" "*/\n" "\n" "void main(void)\n" "{\n" " vec4 color = vec4(0.0);\n" " //for( int i = 0; i < 9; i++ )\n" " //{\n" " // color += texture2D( textureSource, gl_TexCoord[0].st + vec2( gaussFilter[i].x*ScaleU.x, gaussFilter[i].x*ScaleU.y ) )*gaussFilter[i].y;\n" " //}\n" " color += texture2D( textureSource, gl_TexCoord[0].st + vec2( -3.0*ScaleU.x, -3.0*ScaleU.y ) ) * 0.015625;\n" " color += texture2D( textureSource, gl_TexCoord[0].st + vec2( -2.0*ScaleU.x, -2.0*ScaleU.y ) )*0.09375;\n" " color += texture2D( textureSource, gl_TexCoord[0].st + vec2( -1.0*ScaleU.x, -1.0*ScaleU.y ) )*0.234375;\n" " color += texture2D( textureSource, gl_TexCoord[0].st + vec2( 0.0 , 0.0) )*0.3125;\n" " color += texture2D( textureSource, gl_TexCoord[0].st + vec2( 1.0*ScaleU.x, 1.0*ScaleU.y ) )*0.234375;\n" " color += texture2D( textureSource, gl_TexCoord[0].st + vec2( 2.0*ScaleU.x, 2.0*ScaleU.y ) )*0.09375;\n" " color += texture2D( textureSource, gl_TexCoord[0].st + vec2( 3.0*ScaleU.x, -3.0*ScaleU.y ) ) * 0.015625;\n" "\n" " gl_FragDepth = color;\n" "}\n" ; GLint shader_depth_map; GLint shader_depth_map_square; GLint shader_modelview_matrix; GLint shader_projection_matrix; GLint shader_light_pos; GLint shader_light_intensity; GLint shader_blur_source; GLint shader_blur_scale; void loadShader(const char *vertex, const char *fragment, struct ShaderProgram *shader) { shader->vertex = glCreateShader(GL_VERTEX_SHADER); if (shader->vertex == 0) { printf("Shader Error: couldn't create vertex shader\n"); done = 1; return; } shader->fragment = glCreateShader(GL_FRAGMENT_SHADER); if (shader->fragment == 0) { printf("Shader Error: couldn't create fragment shader\n"); done = 1; return; } glShaderSource(shader->vertex, 1, (const GLcharARB**) &vertex, NULL); glCompileShader(shader->vertex); GLint request_value; glGetShaderiv(shader->vertex, GL_COMPILE_STATUS, &request_value); if (request_value == GL_TRUE) { printf("Vertex shader: ok\n"); } else { glGetShaderiv(shader->vertex, GL_INFO_LOG_LENGTH, &request_value); GLchar log[request_value+1]; log[request_value] = 0; glGetShaderInfoLog(shader->vertex, request_value, NULL, log); printf("Vertex shader log:\n%s\n",log); } glShaderSource(shader->fragment, 1, (const GLcharARB**) &fragment, NULL); glCompileShader(shader->fragment); glGetShaderiv(shader->fragment, GL_COMPILE_STATUS, &request_value); if (request_value == GL_TRUE) { printf("Fragment shader: ok\n"); } else { glGetShaderiv(shader->fragment, GL_INFO_LOG_LENGTH, &request_value); GLchar log[request_value+1]; log[request_value] = 0; glGetShaderInfoLog(shader->fragment, request_value, NULL, log); printf("Fragment shader log:\n%s\n",log); } shader->program = glCreateProgram(); if (shader->program == 0) { printf("Shader Error: couldn't create shader program\n"); done = 1; return; } glAttachShader(shader->program, shader->vertex); glAttachShader(shader->program, shader->fragment); glLinkProgram(shader->program); glGetProgramiv(shader->program, GL_LINK_STATUS, &request_value); if (request_value == GL_TRUE) { printf("Shader program: ok\n"); } else { glGetProgramiv(shader->program, GL_INFO_LOG_LENGTH, &request_value); GLchar log[request_value+1]; log[request_value] = 0; glGetProgramInfoLog(shader->program, request_value, NULL, log); printf("Shader program log:\n%s\n",log); } } /* A general OpenGL initialization function. Sets all of the initial parameters. */ void InitGL(int Width, int Height) // We call this right after our OpenGL window is created. { if (Height == 0) { Height = 1; } glViewport(0, 0, Width, Height); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black glClearDepth(1.0); // Enables Clearing Of The Depth Buffer glDepthFunc(GL_LESS); // The Type Of Depth Test To Do glEnable(GL_DEPTH_TEST); // Enables Depth Testing glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Reset The Projection Matrix gluPerspective(45.0f, (GLfloat)Width/(GLfloat)Height, 0.1f, 100.0f); // Calculate The Aspect Ratio Of The Window glMatrixMode(GL_MODELVIEW); // Init depth textures glGenTextures(tex_count, textures); for (int i = 0; i < tex_count; ++i) { glBindTexture(GL_TEXTURE_2D, textures[i]); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, tex_size, tex_size, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); 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_CLAMP); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); } // Init framebuffer glGenFramebuffers(tex_count, fbo); for (int i = 0; i < tex_count; ++i) { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[i]); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, textures[i], 0); glDrawBuffer(GL_NONE); GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (Status != GL_FRAMEBUFFER_COMPLETE) { printf("FB error, status: 0x%x\n", Status); done = 1; return; } } glBindFramebuffer(GL_FRAMEBUFFER, 0); // Init shaders // Shadow Pass shader loadShader(shadow_shader_vertex, shadow_shader_fragment, &ShadowShader); loadShader(shadow_render_shader_vertex, shadow_render_shader_fragment, &ShadowRenderShader); loadShader(blur_shader_vertex, blur_shader_fragment, &BlurShader); shader_depth_map = glGetUniformLocation(ShadowRenderShader.program, "depth_map"); shader_depth_map_square = glGetUniformLocation(ShadowRenderShader.program, "depth_map_square"); shader_modelview_matrix = glGetUniformLocation(ShadowRenderShader.program, "light_modelview_matrix"); shader_projection_matrix = glGetUniformLocation(ShadowRenderShader.program, "light_projection_matrix"); shader_light_pos = glGetUniformLocation(ShadowRenderShader.program, "light_pos"); shader_light_intensity = glGetUniformLocation(ShadowRenderShader.program, "light_intensity"); shader_blur_scale = glGetUniformLocation(BlurShader.program, "ScaleU"); shader_blur_source = glGetUniformLocation(BlurShader.program, "textureSource"); printf("%d %d %d %d %d %d\n", shader_depth_map, shader_depth_map_square, shader_modelview_matrix, shader_projection_matrix, shader_light_pos, shader_light_intensity); printf("%d %d\n", shader_blur_scale, shader_blur_source); glUseProgram(ShadowRenderShader.program); glUniform1i(shader_depth_map, 0); glUniform1i(shader_depth_map_square, 1); glUseProgram(BlurShader.program); glUniform1i(shader_blur_source, 0); glUseProgram(0); GLenum error; while ((error = glGetError()) != GL_NO_ERROR) { printf("Error %x\n",error); } } void DeinitGL(void) { glDeleteTextures(tex_count, textures); glDeleteFramebuffers(tex_count, fbo); glDeleteShader(ShadowShader.vertex); glDeleteShader(ShadowShader.fragment); glDeleteProgram(ShadowShader.program); glDeleteShader(ShadowRenderShader.vertex); glDeleteShader(ShadowRenderShader.fragment); glDeleteProgram(ShadowRenderShader.program); glDeleteShader(BlurShader.vertex); glDeleteShader(BlurShader.fragment); glDeleteProgram(BlurShader.program); } void DrawGeometry(void) { // draw floor glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_QUADS); glNormal3f( 0.0f, 1.0f, 0.0f); glVertex3f( -10.0f, 0.0f, -10.0f); glVertex3f( -10.0f, 0.0f, 10.0f); glVertex3f( 10.0f, 0.0f, 10.0f); glVertex3f( 10.0f, 0.0f, -10.0f); glEnd(); // draw cube glColor3f(0.0f, 1.0f, 0.0f); glBegin(GL_QUADS); glNormal3f( 0.0f, 1.0f, 0.0f); glVertex3f( 1.0f, 2.5f,-1.0f); glVertex3f(-1.0f, 2.5f,-1.0f); glVertex3f(-1.0f, 2.5f, 1.0f); glVertex3f( 1.0f, 2.5f, 1.0f); glNormal3f( 0.0f,-1.0f, 0.0f); glVertex3f( 1.0f, 0.5f, 1.0f); glVertex3f(-1.0f, 0.5f, 1.0f); glVertex3f(-1.0f, 0.5f,-1.0f); glVertex3f( 1.0f, 0.5f,-1.0f); glNormal3f( 0.0f, 0.0f, 1.0f); glVertex3f( 1.0f, 2.5f, 1.0f); glVertex3f(-1.0f, 2.5f, 1.0f); glVertex3f(-1.0f, 0.5f, 1.0f); glVertex3f( 1.0f, 0.5f, 1.0f); glNormal3f( 0.0f, 0.0f,-1.0f); glVertex3f( 1.0f, 0.5f,-1.0f); glVertex3f(-1.0f, 0.5f,-1.0f); glVertex3f(-1.0f, 2.5f,-1.0f); glVertex3f( 1.0f, 2.5f,-1.0f); glNormal3f(-1.0f, 0.0f, 0.0f); glVertex3f(-1.0f, 2.5f, 1.0f); glVertex3f(-1.0f, 2.5f,-1.0f); glVertex3f(-1.0f, 0.5f,-1.0f); glVertex3f(-1.0f, 0.5f, 1.0f); glNormal3f( 1.0f, 0.0f, 0.0f); glVertex3f( 1.0f, 2.5f,-1.0f); glVertex3f( 1.0f, 2.5f, 1.0f); glVertex3f( 1.0f, 0.5f, 1.0f); glVertex3f( 1.0f, 0.5f,-1.0f); glEnd(); } void ShadowPass() { glLoadIdentity(); gluLookAt( light_pos[0], light_pos[1], light_pos[2], 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f ); glGetFloatv(GL_MODELVIEW_MATRIX, light_modelview_matrix); glGetFloatv(GL_PROJECTION_MATRIX, light_projection_matrix); /*static int first = 1; if (first) { first = 0; printf("modelview matrix:\n"); for (int i = 0; i < 4; ++i) printf("%f %f %f %f\n", light_modelview_matrix[i], light_modelview_matrix[4 + i], light_modelview_matrix[8 + i], light_modelview_matrix[12 + i]); printf("\nprojection matrix:\n"); for (int i = 0; i < 4; ++i) printf("%f %f %f %f\n", light_projection_matrix[i], light_projection_matrix[4 + i], light_projection_matrix[8 + i], light_projection_matrix[12 + i]); }*/ glViewport(0,0,tex_size,tex_size); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[0]); glClear(GL_DEPTH_BUFFER_BIT); DrawGeometry(); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[1]); glClear(GL_DEPTH_BUFFER_BIT); glUseProgram(ShadowShader.program); DrawGeometry(); glUseProgram(0); glBindFramebuffer(GL_FRAMEBUFFER, 0); SDL_Surface *surface = SDL_GetVideoSurface(); glViewport(0,0,surface->w,surface->h); } void GaussianBlurPass() { // set view to ortho, texture-sized glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0f,tex_size,tex_size,0.0f,-1.0f,1.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glViewport(0,0,tex_size,tex_size); glUseProgram(BlurShader.program); // 2 blur passes for depth texture glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[4]); glBindTexture(GL_TEXTURE_2D, textures[0]); glClear(GL_DEPTH_BUFFER_BIT); glUniform2f(shader_blur_scale, 1.0/((float)tex_size * blur_coeff), 0.0); glBegin(GL_QUADS); glTexCoord2d(0,1); glVertex3f(0, 0, 0); glTexCoord2d(1,1); glVertex3f(tex_size, 0, 0); glTexCoord2d(1,0); glVertex3f(tex_size, tex_size, 0); glTexCoord2d(0,0); glVertex3f(0, tex_size, 0); glEnd(); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[2]); glBindTexture(GL_TEXTURE_2D, textures[4]); glClear(GL_DEPTH_BUFFER_BIT); glUniform2f(shader_blur_scale, 0.0, 1.0/((float)tex_size * blur_coeff)); glBegin(GL_QUADS); glTexCoord2d(0,1); glVertex3f(0, 0, 0); glTexCoord2d(1,1); glVertex3f(tex_size, 0, 0); glTexCoord2d(1,0); glVertex3f(tex_size, tex_size, 0); glTexCoord2d(0,0); glVertex3f(0, tex_size, 0); glEnd(); // 2 blur passes for depth-square texture glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[4]); glBindTexture(GL_TEXTURE_2D, textures[1]); glClear(GL_DEPTH_BUFFER_BIT); glUniform2f(shader_blur_scale, 1.0/((float)tex_size * blur_coeff), 0.0); glBegin(GL_QUADS); glTexCoord2d(0,1); glVertex3f(0, 0, 0); glTexCoord2d(1,1); glVertex3f(tex_size, 0, 0); glTexCoord2d(1,0); glVertex3f(tex_size, tex_size, 0); glTexCoord2d(0,0); glVertex3f(0, tex_size, 0); glEnd(); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[3]); glBindTexture(GL_TEXTURE_2D, textures[4]); glClear(GL_DEPTH_BUFFER_BIT); glUniform2f(shader_blur_scale, 0.0, 1.0/((float)tex_size * blur_coeff)); glBegin(GL_QUADS); glTexCoord2d(0,1); glVertex3f(0, 0, 0); glTexCoord2d(1,1); glVertex3f(tex_size, 0, 0); glTexCoord2d(1,0); glVertex3f(tex_size, tex_size, 0); glTexCoord2d(0,0); glVertex3f(0, tex_size, 0); glEnd(); glUseProgram(0); glBindFramebuffer(GL_FRAMEBUFFER, 0); // restore view glMatrixMode(GL_PROJECTION); glLoadIdentity(); SDL_Surface *surface = SDL_GetVideoSurface(); float height = surface->h; if (height == 0) { height = 1; } gluPerspective(45.0f, (GLfloat)surface->w/(GLfloat)height, 0.1f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glViewport(0,0,surface->w,surface->h); } void TestPass() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); SDL_Surface *surface = SDL_GetVideoSurface(); glOrtho(0.0f,surface->w,surface->h,0.0f,-1.0f,1.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glColor3f(1.0f, 1.0f, 1.0f); glEnable(GL_TEXTURE_2D); if (blur) { glBindTexture(GL_TEXTURE_2D, textures[2]); } else { glBindTexture(GL_TEXTURE_2D, textures[0]); } glBegin(GL_QUADS); glTexCoord2f(0.0f, 1.0f); glVertex3f( 0.0f, 0.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( surface->w/2, 0.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( surface->w/2, surface->h, 0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 0.0f, surface->h, 0.0f); glEnd(); if (blur) { glBindTexture(GL_TEXTURE_2D, textures[4]); } else { glBindTexture(GL_TEXTURE_2D, textures[1]); } glBegin(GL_QUADS); glTexCoord2f(0.0f, 1.0f); glVertex3f( surface->w/2, 0.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( surface->w, 0.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( surface->w, surface->h, 0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( surface->w/2, surface->h, 0.0f); glEnd(); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glLoadIdentity(); float height = surface->h; if (height == 0) { height = 1; } gluPerspective(45.0f, (GLfloat)surface->w/(GLfloat)height, 0.1f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void RenderPass() { glLoadIdentity(); gluLookAt( 5.0f, 5.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f ); glUseProgram(ShadowRenderShader.program); glActiveTexture(GL_TEXTURE0); if (blur) { glBindTexture(GL_TEXTURE_2D, textures[2]); } else { glBindTexture(GL_TEXTURE_2D, textures[0]); } glActiveTexture(GL_TEXTURE1); if (blur) { glBindTexture(GL_TEXTURE_2D, textures[3]); } else { glBindTexture(GL_TEXTURE_2D, textures[1]); } glActiveTexture(GL_TEXTURE0); glUniformMatrix4fv(shader_modelview_matrix, 1, GL_FALSE, light_modelview_matrix); glUniformMatrix4fv(shader_projection_matrix, 1, GL_FALSE, light_projection_matrix); glUniform4fv(shader_light_pos, 1, light_pos); glUniform4fv(shader_light_intensity, 1, light_intensity); DrawGeometry(); glUseProgram(0); } /* The main drawing function. */ void DrawGLScene() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); ShadowPass(); if (blur) { GaussianBlurPass(); } if (test) { TestPass(); } else { RenderPass(); } // swap buffers to display, since we're double buffered. SDL_GL_SwapBuffers(); } void ResizeScene(int width, int height) { if (height == 0) { height = 1; } glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); SDL_SetVideoMode(width, height, 0, SDL_GL_DOUBLEBUFFER | SDL_RESIZABLE | SDL_OPENGL); } void UpdateScene(void) { last_time = current_time; current_time = SDL_GetTicks(); float delta_time = (current_time - delta_time) / 1000.0f; delta_time /= 1000.0f; light_pos[0] -= charyvel * delta_time; light_pos[2] += charxvel * delta_time; } void ProcessEvents(void) { SDL_Event event; while ( SDL_PollEvent(&event) ) { if ( event.type == SDL_QUIT ) { done = 1; } if (event.type == SDL_VIDEORESIZE) { ResizeScene(event.resize.w, event.resize.h); } if ( event.type == SDL_KEYDOWN ) { switch (event.key.keysym.sym) { case SDLK_ESCAPE: done = 1; break; case SDLK_F1: blur = !blur; break; case SDLK_F2: test = !test; break; case SDLK_LEFT: charxvel = -1; break; case SDLK_RIGHT: charxvel = 1; break; case SDLK_UP: charyvel = -1; break; case SDLK_DOWN: charyvel = 1; break; break; } } if ( event.type == SDL_KEYUP ) { switch (event.key.keysym.sym) { case SDLK_LEFT: case SDLK_RIGHT: charxvel = 0; break; case SDLK_UP: case SDLK_DOWN: charyvel = 0; break; break; } } } } int main(int argc, char **argv) { /* Initialize SDL for video output */ if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); exit(1); } SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 ); SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); /* Create a 640x480 OpenGL screen */ if ( SDL_SetVideoMode(start_width, start_height, 0, SDL_GL_DOUBLEBUFFER | SDL_RESIZABLE | SDL_OPENGL) == NULL ) { fprintf(stderr, "Unable to create OpenGL screen: %s\n", SDL_GetError()); SDL_Quit(); exit(2); } /* Set the title bar in environments that support it */ SDL_WM_SetCaption("DT's Variance Shadow Map tutorial", NULL); GLenum err = glewInit(); if (GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); SDL_Quit(); exit(3); } if (!GLEW_VERSION_2_0) { fprintf(stderr, "Error: OpenGL 2.0 isn't supported\n"); SDL_Quit(); exit(4); } if (!GLEW_EXT_framebuffer_object) { fprintf(stderr, "Error: OpenGL GL_EXT_framebuffer_object extension isn't supported\n"); SDL_Quit(); exit(5); } SDL_Surface *surface = SDL_GetVideoSurface(); InitGL(surface->w, surface->h); current_time = SDL_GetTicks(); /* Loop, drawing and checking events */ while (!done) { UpdateScene(); DrawGLScene(); ProcessEvents(); } DeinitGL(); SDL_Quit(); return 0; }