1. #include <GL/glew.h>
  2. #include "SDL.h"
  3. #include <math.h>
  4.  
  5. #define start_width 800
  6. #define start_height 600
  7.  
  8. volatile int done = 0;
  9. volatile bool test = false;
  10. volatile bool blur = false;
  11.  
  12. int current_time;
  13. int last_time;
  14.  
  15. int charxvel = 0, charyvel = 0;
  16.  
  17. float light_pos[4] = { 5.0f, 6.0f, -1.0f , 1.0f };
  18. float light_intensity[4] = { 1.0f, 1.0f, 1.0f , 1.0f };
  19.  
  20. GLfloat light_modelview_matrix[16];
  21. GLfloat light_projection_matrix[16];
  22.  
  23. #define tex_count 5
  24.  
  25. GLuint textures[tex_count];
  26. GLuint fbo[tex_count];
  27.  
  28. #define tex_size 512
  29. #define blur_coeff 0.25
  30.  
  31. struct ShaderProgram
  32. {
  33.     GLuint vertex;
  34.     GLuint fragment;
  35.     GLuint program;
  36. } ShadowShader, ShadowRenderShader, BlurShader;
  37.  
  38. const char *shadow_shader_vertex =
  39. "void main(void)\n"
  40. "{\n"
  41. "   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
  42. "}\n"
  43. ;
  44.  
  45. const char *shadow_shader_fragment =
  46. "void main(void)\n"
  47. "{\n"
  48. "   float dx = dFdx(gl_FragCoord.z);\n"
  49. "   float dy = dFdy(gl_FragCoord.z);\n"
  50. "   gl_FragDepth = gl_FragCoord.z + 0.25*(dx*dx+dy*dy);\n"
  51. "   gl_FragDepth = gl_FragCoord.z * gl_FragCoord.z;\n"
  52. "}\n"
  53. ;
  54.  
  55. const char *shadow_render_shader_vertex =
  56. "uniform sampler2D depth_map;\n"
  57. "uniform sampler2D depth_map_square;\n"
  58. "uniform mat4 light_modelview_matrix;\n"
  59. "uniform mat4 light_projection_matrix;\n"
  60. "uniform vec4 light_pos;\n"
  61. "uniform vec4 light_intensity;\n"
  62. "\n"
  63. "varying vec4 dt_color;\n"
  64. "varying vec4 light_coord;\n"
  65. "\n"
  66. "void main(void)\n"
  67. "{\n"
  68. "   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
  69. "   dt_color = gl_Color;\n"
  70. "   light_coord = light_projection_matrix * light_modelview_matrix * gl_Vertex;\n"
  71. "}\n"
  72. ;
  73.  
  74. const char *shadow_render_shader_fragment =
  75. "uniform sampler2D depth_map;\n"
  76. "uniform sampler2D depth_map_square;\n"
  77. "uniform mat4 light_modelview_matrix;\n"
  78. "uniform mat4 light_projection_matrix;\n"
  79. "uniform vec4 light_pos;\n"
  80. "uniform vec4 light_intensity;\n"
  81. "\n"
  82. "varying vec4 dt_color;\n"
  83. "varying vec4 light_coord;\n"
  84. "\n"
  85. "void main(void)\n"
  86. "{\n"
  87. "   light_coord.xyz = light_coord.xyz/light_coord.w;\n"
  88. "   light_coord.w = 1.0/light_coord.w;\n"
  89. "   light_coord.xyz = (light_coord.xyz + 1.0) / 2.0;\n"
  90.  
  91. "   float depth = texture2D(depth_map, light_coord).r;"
  92. "   float depth_square = texture2D(depth_map_square, light_coord).r;"
  93.  
  94. "   vec4 color = dt_color;\n"
  95. "   if ((light_coord.x >= 0.0) && (light_coord.x <= 1.0) && (light_coord.y >= 0.0) && (light_coord.y <= 1.0))\n"
  96. "   {\n"
  97. "       if (light_coord.z > depth)\n"
  98. "       {\n"
  99. "           float b = depth_square - depth*depth;\n"
  100. "           b = max(b,0.00002);\n"
  101. "           float p = b / (b + (light_coord.z - depth) * (light_coord.z - depth));\n"
  102. "           color.rgb *= p;\n"
  103. "       }\n"
  104. "   }\n"
  105. //" else\n"
  106. //" {\n"
  107. //"     color = vec4(0.5, 0.5, 0.5, 1.0);\n"
  108. //" }\n"
  109. "   gl_FragColor = color;\n"
  110. "}\n"
  111. ;
  112.  
  113. const char *blur_shader_vertex =
  114. "void main(void)\n"
  115. "{\n"
  116. "   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
  117. "   gl_TexCoord[0] =  gl_MultiTexCoord0;\n"
  118. "}\n"
  119. ;
  120.  
  121. const char *blur_shader_fragment =
  122. "uniform vec2 ScaleU;\n"
  123. "uniform sampler2D textureSource;\n"
  124. "\n"
  125. "// Portability prevented us from using a const array of vec2\n"
  126. "// Mac shader compiler don't support it.\n"
  127. "/*\n"
  128. "const vec2 gaussFilter[7] = \n"
  129. "{ \n"
  130. "   -3.0,   0.015625,\n"
  131. "   -2.0,   0.09375,\n"
  132. "   -1.0,   0.234375,\n"
  133. "   0.0,    0.3125,\n"
  134. "   1.0,    0.234375,\n"
  135. "   2.0,    0.09375,\n"
  136. "   3.0,    0.015625\n"
  137. "};\n"
  138. "*/\n"
  139. "\n"
  140. "void main(void)\n"
  141. "{\n"
  142. "   vec4 color = vec4(0.0);\n"
  143. "   //for( int i = 0; i < 9; i++ )\n"
  144. "   //{\n"
  145. "   //  color += texture2D( textureSource, gl_TexCoord[0].st + vec2( gaussFilter[i].x*ScaleU.x, gaussFilter[i].x*ScaleU.y ) )*gaussFilter[i].y;\n"
  146. "   //}\n"
  147. "   color += texture2D( textureSource, gl_TexCoord[0].st + vec2( -3.0*ScaleU.x, -3.0*ScaleU.y ) ) * 0.015625;\n"
  148. "   color += texture2D( textureSource, gl_TexCoord[0].st + vec2( -2.0*ScaleU.x, -2.0*ScaleU.y ) )*0.09375;\n"
  149. "   color += texture2D( textureSource, gl_TexCoord[0].st + vec2( -1.0*ScaleU.x, -1.0*ScaleU.y ) )*0.234375;\n"
  150. "   color += texture2D( textureSource, gl_TexCoord[0].st + vec2( 0.0 , 0.0) )*0.3125;\n"
  151. "   color += texture2D( textureSource, gl_TexCoord[0].st + vec2( 1.0*ScaleU.x,  1.0*ScaleU.y ) )*0.234375;\n"
  152. "   color += texture2D( textureSource, gl_TexCoord[0].st + vec2( 2.0*ScaleU.x,  2.0*ScaleU.y ) )*0.09375;\n"
  153. "   color += texture2D( textureSource, gl_TexCoord[0].st + vec2( 3.0*ScaleU.x, -3.0*ScaleU.y ) ) * 0.015625;\n"
  154. "\n"
  155. "   gl_FragDepth = color;\n"
  156. "}\n"
  157. ;
  158.  
  159. GLint shader_depth_map;
  160. GLint shader_depth_map_square;
  161. GLint shader_modelview_matrix;
  162. GLint shader_projection_matrix;
  163. GLint shader_light_pos;
  164. GLint shader_light_intensity;
  165.  
  166. GLint shader_blur_source;
  167. GLint shader_blur_scale;
  168.  
  169. void loadShader(const char *vertex, const char *fragment, struct ShaderProgram *shader)
  170. {
  171.     shader->vertex = glCreateShader(GL_VERTEX_SHADER);
  172.     if (shader->vertex == 0)
  173.     {
  174.         printf("Shader Error: couldn't create vertex shader\n");
  175.         done = 1;
  176.         return;
  177.     }
  178.    
  179.     shader->fragment = glCreateShader(GL_FRAGMENT_SHADER);
  180.     if (shader->fragment == 0)
  181.     {
  182.         printf("Shader Error: couldn't create fragment shader\n");
  183.         done = 1;
  184.         return;
  185.     }
  186.  
  187.     glShaderSource(shader->vertex, 1, (const GLcharARB**) &vertex, NULL);
  188.     glCompileShader(shader->vertex);
  189.  
  190.     GLint request_value;
  191.  
  192.     glGetShaderiv(shader->vertex, GL_COMPILE_STATUS, &request_value);
  193.     if (request_value == GL_TRUE)
  194.     {
  195.         printf("Vertex shader: ok\n");
  196.     }
  197.     else
  198.     {
  199.         glGetShaderiv(shader->vertex, GL_INFO_LOG_LENGTH, &request_value);
  200.        
  201.         GLchar log[request_value+1];
  202.         log[request_value] = 0;
  203.            
  204.         glGetShaderInfoLog(shader->vertex, request_value, NULL, log);
  205.         printf("Vertex shader log:\n%s\n",log);
  206.     }
  207.    
  208.     glShaderSource(shader->fragment, 1, (const GLcharARB**) &fragment, NULL);
  209.     glCompileShader(shader->fragment);
  210.  
  211.     glGetShaderiv(shader->fragment, GL_COMPILE_STATUS, &request_value);
  212.     if (request_value == GL_TRUE)
  213.     {
  214.         printf("Fragment shader: ok\n");
  215.     }
  216.     else
  217.     {
  218.         glGetShaderiv(shader->fragment, GL_INFO_LOG_LENGTH, &request_value);
  219.        
  220.         GLchar log[request_value+1];
  221.         log[request_value] = 0;
  222.            
  223.         glGetShaderInfoLog(shader->fragment, request_value, NULL, log);
  224.         printf("Fragment shader log:\n%s\n",log);
  225.     }
  226.  
  227.     shader->program = glCreateProgram();
  228.     if (shader->program == 0)
  229.     {
  230.         printf("Shader Error: couldn't create shader program\n");
  231.         done = 1;
  232.         return;
  233.     }
  234.  
  235.     glAttachShader(shader->program, shader->vertex);
  236.     glAttachShader(shader->program, shader->fragment);
  237.     glLinkProgram(shader->program);
  238.  
  239.     glGetProgramiv(shader->program, GL_LINK_STATUS, &request_value);
  240.     if (request_value == GL_TRUE)
  241.     {
  242.         printf("Shader program: ok\n");
  243.     }
  244.     else
  245.     {
  246.         glGetProgramiv(shader->program, GL_INFO_LOG_LENGTH, &request_value);
  247.        
  248.         GLchar log[request_value+1];
  249.         log[request_value] = 0;
  250.            
  251.         glGetProgramInfoLog(shader->program, request_value, NULL, log);
  252.         printf("Shader program log:\n%s\n",log);
  253.     }
  254. }
  255.  
  256. /* A general OpenGL initialization function.  Sets all of the initial parameters. */
  257. void InitGL(int Width, int Height)          // We call this right after our OpenGL window is created.
  258. {
  259.     if (Height == 0)
  260.     {
  261.         Height = 1;
  262.     }
  263.  
  264.     glViewport(0, 0, Width, Height);
  265.     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);       // This Will Clear The Background Color To Black
  266.     glClearDepth(1.0);              // Enables Clearing Of The Depth Buffer
  267.     glDepthFunc(GL_LESS);               // The Type Of Depth Test To Do
  268.     glEnable(GL_DEPTH_TEST);            // Enables Depth Testing
  269.     glShadeModel(GL_SMOOTH);            // Enables Smooth Color Shading
  270.  
  271.     glMatrixMode(GL_PROJECTION);
  272.     glLoadIdentity();               // Reset The Projection Matrix
  273.  
  274.     gluPerspective(45.0f, (GLfloat)Width/(GLfloat)Height, 0.1f, 100.0f);    // Calculate The Aspect Ratio Of The Window
  275.  
  276.     glMatrixMode(GL_MODELVIEW);
  277.    
  278.     // Init depth textures
  279.     glGenTextures(tex_count, textures);
  280.    
  281.     for (int i = 0; i < tex_count; ++i)
  282.     {
  283.         glBindTexture(GL_TEXTURE_2D, textures[i]);
  284.         glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, tex_size, tex_size, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
  285.         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  286.         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  287.         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
  288.         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
  289.     }
  290.  
  291.     // Init framebuffer
  292.     glGenFramebuffers(tex_count, fbo);
  293.  
  294.     for (int i = 0; i < tex_count; ++i)
  295.     {
  296.         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[i]);
  297.         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, textures[i], 0);
  298.  
  299.         glDrawBuffer(GL_NONE);
  300.    
  301.         GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  302.  
  303.         if (Status != GL_FRAMEBUFFER_COMPLETE)
  304.         {
  305.             printf("FB error, status: 0x%x\n", Status);
  306.             done = 1;
  307.             return;
  308.         }
  309.     }
  310.  
  311.     glBindFramebuffer(GL_FRAMEBUFFER, 0);
  312.    
  313.     // Init shaders
  314.    
  315.     // Shadow Pass shader
  316.     loadShader(shadow_shader_vertex, shadow_shader_fragment, &ShadowShader);
  317.     loadShader(shadow_render_shader_vertex, shadow_render_shader_fragment, &ShadowRenderShader);
  318.     loadShader(blur_shader_vertex, blur_shader_fragment, &BlurShader);
  319.  
  320.     shader_depth_map         = glGetUniformLocation(ShadowRenderShader.program, "depth_map");
  321.     shader_depth_map_square  = glGetUniformLocation(ShadowRenderShader.program, "depth_map_square");
  322.     shader_modelview_matrix  = glGetUniformLocation(ShadowRenderShader.program, "light_modelview_matrix");
  323.     shader_projection_matrix = glGetUniformLocation(ShadowRenderShader.program, "light_projection_matrix");
  324.     shader_light_pos         = glGetUniformLocation(ShadowRenderShader.program, "light_pos");
  325.     shader_light_intensity   = glGetUniformLocation(ShadowRenderShader.program, "light_intensity");
  326.  
  327.     shader_blur_scale        = glGetUniformLocation(BlurShader.program,         "ScaleU");
  328.     shader_blur_source       = glGetUniformLocation(BlurShader.program,         "textureSource");
  329.  
  330.     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);
  331.     printf("%d %d\n", shader_blur_scale, shader_blur_source);
  332.  
  333.     glUseProgram(ShadowRenderShader.program);
  334.  
  335.     glUniform1i(shader_depth_map, 0);
  336.     glUniform1i(shader_depth_map_square, 1);
  337.  
  338.     glUseProgram(BlurShader.program);
  339.     glUniform1i(shader_blur_source, 0);
  340.  
  341.     glUseProgram(0);
  342.  
  343.     GLenum error;
  344.     while ((error = glGetError()) != GL_NO_ERROR)
  345.     {
  346.         printf("Error %x\n",error);
  347.     }
  348. }
  349.  
  350. void DeinitGL(void)
  351. {
  352.     glDeleteTextures(tex_count, textures);
  353.    
  354.         glDeleteFramebuffers(tex_count, fbo);
  355.  
  356.     glDeleteShader(ShadowShader.vertex);
  357.     glDeleteShader(ShadowShader.fragment);
  358.     glDeleteProgram(ShadowShader.program);
  359.  
  360.     glDeleteShader(ShadowRenderShader.vertex);
  361.     glDeleteShader(ShadowRenderShader.fragment);
  362.     glDeleteProgram(ShadowRenderShader.program);
  363.  
  364.     glDeleteShader(BlurShader.vertex);
  365.     glDeleteShader(BlurShader.fragment);
  366.     glDeleteProgram(BlurShader.program);
  367. }
  368.  
  369. void DrawGeometry(void)
  370. {
  371.     // draw floor
  372.     glColor3f(1.0f, 1.0f, 1.0f);
  373.     glBegin(GL_QUADS);
  374.         glNormal3f( 0.0f, 1.0f, 0.0f);
  375.  
  376.         glVertex3f( -10.0f, 0.0f, -10.0f);
  377.         glVertex3f( -10.0f, 0.0f,  10.0f);
  378.         glVertex3f(  10.0f, 0.0f,  10.0f);
  379.         glVertex3f(  10.0f, 0.0f, -10.0f);
  380.     glEnd();
  381.  
  382.     // draw cube
  383.     glColor3f(0.0f, 1.0f, 0.0f);
  384.  
  385.     glBegin(GL_QUADS);
  386.         glNormal3f( 0.0f, 1.0f, 0.0f);
  387.         glVertex3f( 1.0f, 2.5f,-1.0f);
  388.         glVertex3f(-1.0f, 2.5f,-1.0f);
  389.         glVertex3f(-1.0f, 2.5f, 1.0f);
  390.         glVertex3f( 1.0f, 2.5f, 1.0f);
  391.  
  392.         glNormal3f( 0.0f,-1.0f, 0.0f);
  393.         glVertex3f( 1.0f, 0.5f, 1.0f);
  394.         glVertex3f(-1.0f, 0.5f, 1.0f);
  395.         glVertex3f(-1.0f, 0.5f,-1.0f);
  396.         glVertex3f( 1.0f, 0.5f,-1.0f);
  397.  
  398.         glNormal3f( 0.0f, 0.0f, 1.0f);
  399.         glVertex3f( 1.0f, 2.5f, 1.0f);
  400.         glVertex3f(-1.0f, 2.5f, 1.0f);
  401.         glVertex3f(-1.0f, 0.5f, 1.0f);
  402.         glVertex3f( 1.0f, 0.5f, 1.0f);
  403.  
  404.         glNormal3f( 0.0f, 0.0f,-1.0f);
  405.         glVertex3f( 1.0f, 0.5f,-1.0f);
  406.         glVertex3f(-1.0f, 0.5f,-1.0f);
  407.         glVertex3f(-1.0f, 2.5f,-1.0f);
  408.         glVertex3f( 1.0f, 2.5f,-1.0f);
  409.  
  410.         glNormal3f(-1.0f, 0.0f, 0.0f);
  411.         glVertex3f(-1.0f, 2.5f, 1.0f);
  412.         glVertex3f(-1.0f, 2.5f,-1.0f);
  413.         glVertex3f(-1.0f, 0.5f,-1.0f);
  414.         glVertex3f(-1.0f, 0.5f, 1.0f);
  415.  
  416.         glNormal3f( 1.0f, 0.0f, 0.0f);
  417.         glVertex3f( 1.0f, 2.5f,-1.0f);
  418.         glVertex3f( 1.0f, 2.5f, 1.0f);
  419.         glVertex3f( 1.0f, 0.5f, 1.0f);
  420.         glVertex3f( 1.0f, 0.5f,-1.0f);
  421.     glEnd();
  422. }
  423.  
  424. void ShadowPass()
  425. {
  426.     glLoadIdentity();
  427.  
  428.     gluLookAt(
  429.         light_pos[0], light_pos[1], light_pos[2],
  430.         0.0f, 0.0f, 0.0f,
  431.         0.0f, 1.0f, 0.0f
  432.     );
  433.  
  434.     glGetFloatv(GL_MODELVIEW_MATRIX, light_modelview_matrix);
  435.     glGetFloatv(GL_PROJECTION_MATRIX, light_projection_matrix);
  436.  
  437.     /*static int first = 1;
  438.     if (first)
  439.     {
  440.         first = 0;
  441.         printf("modelview matrix:\n");
  442.         for (int i = 0; i < 4; ++i)
  443.             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]);
  444.        
  445.         printf("\nprojection matrix:\n");
  446.         for (int i = 0; i < 4; ++i)
  447.             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]);
  448.     }*/
  449.  
  450.     glViewport(0,0,tex_size,tex_size);
  451.  
  452.     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[0]);
  453.     glClear(GL_DEPTH_BUFFER_BIT);
  454.     DrawGeometry();
  455.  
  456.     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[1]);
  457.     glClear(GL_DEPTH_BUFFER_BIT);
  458.     glUseProgram(ShadowShader.program);
  459.     DrawGeometry();
  460.     glUseProgram(0);
  461.     glBindFramebuffer(GL_FRAMEBUFFER, 0);
  462.  
  463.     SDL_Surface *surface = SDL_GetVideoSurface();
  464.     glViewport(0,0,surface->w,surface->h);
  465.    
  466. }
  467.  
  468. void GaussianBlurPass()
  469. {
  470.     // set view to ortho, texture-sized
  471.     glMatrixMode(GL_PROJECTION);
  472.     glLoadIdentity();
  473.  
  474.     glOrtho(0.0f,tex_size,tex_size,0.0f,-1.0f,1.0f);
  475.  
  476.     glMatrixMode(GL_MODELVIEW);
  477.     glLoadIdentity();
  478.  
  479.     glViewport(0,0,tex_size,tex_size);
  480.  
  481.     glUseProgram(BlurShader.program);
  482.  
  483.     // 2 blur passes for depth texture
  484.  
  485.     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[4]);
  486.     glBindTexture(GL_TEXTURE_2D, textures[0]);
  487.     glClear(GL_DEPTH_BUFFER_BIT);
  488.    
  489.     glUniform2f(shader_blur_scale, 1.0/((float)tex_size * blur_coeff), 0.0);
  490.  
  491.     glBegin(GL_QUADS);
  492.         glTexCoord2d(0,1); glVertex3f(0,        0,        0);
  493.         glTexCoord2d(1,1); glVertex3f(tex_size, 0,        0);
  494.         glTexCoord2d(1,0); glVertex3f(tex_size, tex_size, 0);
  495.         glTexCoord2d(0,0); glVertex3f(0,        tex_size, 0);
  496.     glEnd();
  497.  
  498.     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[2]);
  499.     glBindTexture(GL_TEXTURE_2D, textures[4]);
  500.     glClear(GL_DEPTH_BUFFER_BIT);
  501.  
  502.     glUniform2f(shader_blur_scale, 0.0, 1.0/((float)tex_size * blur_coeff));
  503.  
  504.     glBegin(GL_QUADS);
  505.         glTexCoord2d(0,1); glVertex3f(0,        0,        0);
  506.         glTexCoord2d(1,1); glVertex3f(tex_size, 0,        0);
  507.         glTexCoord2d(1,0); glVertex3f(tex_size, tex_size, 0);
  508.         glTexCoord2d(0,0); glVertex3f(0,        tex_size, 0);
  509.     glEnd();
  510.  
  511.  
  512.     // 2 blur passes for depth-square texture
  513.  
  514.     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[4]);
  515.     glBindTexture(GL_TEXTURE_2D, textures[1]);
  516.     glClear(GL_DEPTH_BUFFER_BIT);
  517.  
  518.     glUniform2f(shader_blur_scale, 1.0/((float)tex_size * blur_coeff), 0.0);
  519.  
  520.     glBegin(GL_QUADS);
  521.         glTexCoord2d(0,1); glVertex3f(0,        0,        0);
  522.         glTexCoord2d(1,1); glVertex3f(tex_size, 0,        0);
  523.         glTexCoord2d(1,0); glVertex3f(tex_size, tex_size, 0);
  524.         glTexCoord2d(0,0); glVertex3f(0,        tex_size, 0);
  525.     glEnd();
  526.  
  527.     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[3]);
  528.     glBindTexture(GL_TEXTURE_2D, textures[4]);
  529.     glClear(GL_DEPTH_BUFFER_BIT);
  530.  
  531.     glUniform2f(shader_blur_scale, 0.0, 1.0/((float)tex_size * blur_coeff));
  532.  
  533.     glBegin(GL_QUADS);
  534.         glTexCoord2d(0,1); glVertex3f(0,        0,        0);
  535.         glTexCoord2d(1,1); glVertex3f(tex_size, 0,        0);
  536.         glTexCoord2d(1,0); glVertex3f(tex_size, tex_size, 0);
  537.         glTexCoord2d(0,0); glVertex3f(0,        tex_size, 0);
  538.     glEnd();
  539.  
  540.     glUseProgram(0);
  541.     glBindFramebuffer(GL_FRAMEBUFFER, 0);
  542.  
  543.     // restore view
  544.     glMatrixMode(GL_PROJECTION);
  545.     glLoadIdentity();
  546.  
  547.     SDL_Surface *surface = SDL_GetVideoSurface();
  548.     float height = surface->h;
  549.     if (height == 0)
  550.     {
  551.         height = 1;
  552.     }
  553.  
  554.     gluPerspective(45.0f, (GLfloat)surface->w/(GLfloat)height, 0.1f, 100.0f);
  555.  
  556.     glMatrixMode(GL_MODELVIEW);
  557.     glLoadIdentity();
  558.     glViewport(0,0,surface->w,surface->h);
  559. }
  560.  
  561. void TestPass()
  562. {
  563.     glMatrixMode(GL_PROJECTION);
  564.     glLoadIdentity();
  565.  
  566.     SDL_Surface *surface = SDL_GetVideoSurface();
  567.     glOrtho(0.0f,surface->w,surface->h,0.0f,-1.0f,1.0f);
  568.  
  569.     glMatrixMode(GL_MODELVIEW);
  570.     glLoadIdentity();
  571.  
  572.     glColor3f(1.0f, 1.0f, 1.0f);
  573.    
  574.     glEnable(GL_TEXTURE_2D);
  575.  
  576.     if (blur)
  577.     {
  578.         glBindTexture(GL_TEXTURE_2D, textures[2]);
  579.     }
  580.     else
  581.     {
  582.         glBindTexture(GL_TEXTURE_2D, textures[0]);
  583.     }
  584.  
  585.     glBegin(GL_QUADS);
  586.         glTexCoord2f(0.0f, 1.0f); glVertex3f( 0.0f, 0.0f,  0.0f);
  587.         glTexCoord2f(1.0f, 1.0f); glVertex3f( surface->w/2, 0.0f,  0.0f);
  588.         glTexCoord2f(1.0f, 0.0f); glVertex3f( surface->w/2, surface->h,  0.0f);
  589.         glTexCoord2f(0.0f, 0.0f); glVertex3f( 0.0f, surface->h,  0.0f);
  590.     glEnd();
  591.  
  592.     if (blur)
  593.     {
  594.         glBindTexture(GL_TEXTURE_2D, textures[4]);
  595.     }
  596.     else
  597.     {
  598.         glBindTexture(GL_TEXTURE_2D, textures[1]);
  599.     }
  600.  
  601.     glBegin(GL_QUADS);
  602.         glTexCoord2f(0.0f, 1.0f); glVertex3f( surface->w/2, 0.0f,  0.0f);
  603.         glTexCoord2f(1.0f, 1.0f); glVertex3f( surface->w, 0.0f,  0.0f);
  604.         glTexCoord2f(1.0f, 0.0f); glVertex3f( surface->w, surface->h,  0.0f);
  605.         glTexCoord2f(0.0f, 0.0f); glVertex3f( surface->w/2, surface->h,  0.0f);
  606.     glEnd();
  607.  
  608.     glDisable(GL_TEXTURE_2D);
  609.  
  610.     glMatrixMode(GL_PROJECTION);
  611.     glLoadIdentity();
  612.  
  613.     float height = surface->h;
  614.     if (height == 0)
  615.     {
  616.         height = 1;
  617.     }
  618.  
  619.     gluPerspective(45.0f, (GLfloat)surface->w/(GLfloat)height, 0.1f, 100.0f);
  620.  
  621.     glMatrixMode(GL_MODELVIEW);
  622.     glLoadIdentity();
  623. }
  624.  
  625. void RenderPass()
  626. {
  627.     glLoadIdentity();
  628.  
  629.     gluLookAt(
  630.         5.0f, 5.0f, 5.0f,
  631.         0.0f, 0.0f, 0.0f,
  632.         0.0f, 1.0f, 0.0f
  633.     );
  634.  
  635.     glUseProgram(ShadowRenderShader.program);
  636.  
  637.     glActiveTexture(GL_TEXTURE0);
  638.     if (blur)
  639.     {
  640.         glBindTexture(GL_TEXTURE_2D, textures[2]);
  641.     }
  642.     else
  643.     {
  644.         glBindTexture(GL_TEXTURE_2D, textures[0]);
  645.     }
  646.    
  647.     glActiveTexture(GL_TEXTURE1);
  648.     if (blur)
  649.     {
  650.         glBindTexture(GL_TEXTURE_2D, textures[3]);
  651.     }
  652.     else
  653.     {
  654.         glBindTexture(GL_TEXTURE_2D, textures[1]);
  655.     }
  656.  
  657.     glActiveTexture(GL_TEXTURE0);
  658.  
  659.     glUniformMatrix4fv(shader_modelview_matrix, 1, GL_FALSE, light_modelview_matrix);
  660.     glUniformMatrix4fv(shader_projection_matrix, 1, GL_FALSE, light_projection_matrix);
  661.  
  662.     glUniform4fv(shader_light_pos, 1, light_pos);
  663.     glUniform4fv(shader_light_intensity, 1, light_intensity);
  664.    
  665.     DrawGeometry();
  666.  
  667.     glUseProgram(0);
  668. }
  669.  
  670. /* The main drawing function. */
  671. void DrawGLScene()
  672. {
  673.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  674.     glLoadIdentity();
  675.  
  676.     ShadowPass();
  677.  
  678.     if (blur)
  679.     {
  680.         GaussianBlurPass();
  681.     }
  682.    
  683.     if (test)
  684.     {
  685.         TestPass();
  686.     }
  687.     else
  688.     {
  689.         RenderPass();
  690.     }
  691.    
  692.     // swap buffers to display, since we're double buffered.
  693.     SDL_GL_SwapBuffers();
  694. }
  695.  
  696. void ResizeScene(int width, int height)
  697. {
  698.     if (height == 0)
  699.     {
  700.         height = 1;
  701.     }
  702.  
  703.     glViewport(0, 0, width, height);
  704.  
  705.     glMatrixMode(GL_PROJECTION);
  706.     glLoadIdentity();
  707.  
  708.     gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 100.0f);
  709.  
  710.     glMatrixMode(GL_MODELVIEW);
  711.     glLoadIdentity();
  712.    
  713.     SDL_SetVideoMode(width, height, 0, SDL_GL_DOUBLEBUFFER | SDL_RESIZABLE | SDL_OPENGL);
  714. }
  715.  
  716. void UpdateScene(void)
  717. {
  718.     last_time = current_time;
  719.     current_time = SDL_GetTicks();
  720.     float delta_time = (current_time - delta_time) / 1000.0f;
  721.        
  722.     delta_time /= 1000.0f;
  723.  
  724.     light_pos[0] -= charyvel * delta_time;
  725.     light_pos[2] += charxvel * delta_time;
  726. }
  727.  
  728. void ProcessEvents(void)
  729. {
  730.     SDL_Event event;
  731.  
  732.     while ( SDL_PollEvent(&event) )
  733.     {
  734.         if ( event.type == SDL_QUIT )
  735.         {
  736.             done = 1;
  737.         }
  738.        
  739.         if (event.type == SDL_VIDEORESIZE)
  740.         {
  741.             ResizeScene(event.resize.w, event.resize.h);
  742.         }
  743.  
  744.         if ( event.type == SDL_KEYDOWN )
  745.         {
  746.             switch (event.key.keysym.sym)
  747.             {
  748.             case SDLK_ESCAPE:
  749.                 done = 1;
  750.                 break;
  751.             case SDLK_F1:
  752.                 blur = !blur;
  753.                 break;
  754.             case SDLK_F2:
  755.                 test = !test;
  756.                 break;
  757.            
  758.             case SDLK_LEFT:
  759.                 charxvel = -1;
  760.                 break;
  761.             case SDLK_RIGHT:
  762.                 charxvel = 1;
  763.                 break;
  764.             case SDLK_UP:
  765.                 charyvel = -1;
  766.                 break;
  767.             case SDLK_DOWN:
  768.                 charyvel = 1;
  769.                 break;
  770.             break;
  771.             }
  772.         }
  773.  
  774.         if ( event.type == SDL_KEYUP )
  775.         {
  776.            
  777.             switch (event.key.keysym.sym)
  778.             {
  779.             case SDLK_LEFT:
  780.             case SDLK_RIGHT:
  781.                 charxvel = 0;
  782.                 break;
  783.             case SDLK_UP:
  784.             case SDLK_DOWN:
  785.                 charyvel = 0;
  786.                 break;
  787.             break;
  788.             }
  789.         }
  790.     }
  791. }
  792.  
  793. int main(int argc, char **argv)
  794. {
  795.     /* Initialize SDL for video output */
  796.     if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
  797.     {
  798.         fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
  799.         exit(1);
  800.     }
  801.  
  802.     SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
  803.     SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
  804.     SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
  805.     SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
  806.     SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
  807.  
  808.     /* Create a 640x480 OpenGL screen */
  809.     if ( SDL_SetVideoMode(start_width, start_height, 0, SDL_GL_DOUBLEBUFFER | SDL_RESIZABLE | SDL_OPENGL) == NULL )
  810.     {
  811.         fprintf(stderr, "Unable to create OpenGL screen: %s\n", SDL_GetError());
  812.         SDL_Quit();
  813.         exit(2);
  814.     }
  815.  
  816.     /* Set the title bar in environments that support it */
  817.     SDL_WM_SetCaption("DT's Variance Shadow Map tutorial", NULL);
  818.  
  819.     GLenum err = glewInit();
  820.     if (GLEW_OK != err)
  821.     {
  822.         /* Problem: glewInit failed, something is seriously wrong. */
  823.         fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
  824.         SDL_Quit();
  825.         exit(3);
  826.     }
  827.  
  828.     if (!GLEW_VERSION_2_0)
  829.     {
  830.         fprintf(stderr, "Error: OpenGL 2.0 isn't supported\n");
  831.         SDL_Quit();
  832.         exit(4);
  833.     }
  834.    
  835.     if (!GLEW_EXT_framebuffer_object)
  836.     {
  837.         fprintf(stderr, "Error: OpenGL GL_EXT_framebuffer_object extension isn't supported\n");
  838.         SDL_Quit();
  839.         exit(5);
  840.     }
  841.  
  842.     SDL_Surface *surface = SDL_GetVideoSurface();
  843.     InitGL(surface->w, surface->h);
  844.  
  845.     current_time = SDL_GetTicks();
  846.    
  847.     /* Loop, drawing and checking events */
  848.     while (!done)
  849.     {
  850.         UpdateScene();
  851.         DrawGLScene();
  852.         ProcessEvents();
  853.     }
  854.    
  855.     DeinitGL();
  856.     SDL_Quit();
  857.  
  858.     return 0;
  859. }