2
0

Is.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. #include "Renderer.hpp"
  2. #include "Camera.h"
  3. #include "Light.h"
  4. #include "LightProps.h"
  5. #include "App.h"
  6. #include "Scene.h"
  7. //=====================================================================================================================================
  8. // STATICS =
  9. //=====================================================================================================================================
  10. float Renderer::Is::sMOUvSCoords[] = { -0.000000, 0.000000, -1.000000, 0.500000, 0.500000, -0.707107, 0.707107, 0.000000, -0.707107, 0.500000, 0.500000, 0.707107, 0.000000, 0.000000, 1.000000, 0.707107, 0.000000, 0.707107, -0.000000, 0.707107, 0.707107, 0.000000, 0.000000, 1.000000, 0.500000, 0.500000, 0.707107, -0.000000, 0.000000, -1.000000, -0.000000, 0.707107, -0.707107, 0.500000, 0.500000, -0.707107, -0.000000, 0.000000, -1.000000, -0.500000, 0.500000, -0.707107, -0.000000, 0.707107, -0.707107, -0.500000, 0.500000, 0.707107, 0.000000, 0.000000, 1.000000, -0.000000, 0.707107, 0.707107, -0.707107, -0.000000, 0.707107, 0.000000, 0.000000, 1.000000, -0.500000, 0.500000, 0.707107, -0.000000, 0.000000, -1.000000, -0.707107, -0.000000, -0.707107, -0.500000, 0.500000, -0.707107, -0.000000, 0.000000, -1.000000, -0.500000, -0.500000, -0.707107, -0.707107, -0.000000, -0.707107, -0.500000, -0.500000, 0.707107, 0.000000, 0.000000, 1.000000, -0.707107, -0.000000, 0.707107, 0.000000, -0.707107, 0.707107, 0.000000, 0.000000, 1.000000, -0.500000, -0.500000, 0.707107, -0.000000, 0.000000, -1.000000, 0.000000, -0.707107, -0.707107, -0.500000, -0.500000, -0.707107, -0.000000, 0.000000, -1.000000, 0.500000, -0.500000, -0.707107, 0.000000, -0.707107, -0.707107, 0.500000, -0.500000, 0.707107, 0.000000, 0.000000, 1.000000, 0.000000, -0.707107, 0.707107, 0.707107, 0.000000, 0.707107, 0.000000, 0.000000, 1.000000, 0.500000, -0.500000, 0.707107, -0.000000, 0.000000, -1.000000, 0.707107, 0.000000, -0.707107, 0.500000, -0.500000, -0.707107, 0.500000, -0.500000, -0.707107, 0.707107, 0.000000, -0.707107, 1.000000, 0.000000, -0.000000, 0.500000, -0.500000, -0.707107, 1.000000, 0.000000, -0.000000, 0.707107, -0.707107, 0.000000, 0.707107, -0.707107, 0.000000, 1.000000, 0.000000, -0.000000, 0.707107, 0.000000, 0.707107, 0.707107, -0.707107, 0.000000, 0.707107, 0.000000, 0.707107, 0.500000, -0.500000, 0.707107, 0.000000, -1.000000, 0.000000, 0.707107, -0.707107, 0.000000, 0.500000, -0.500000, 0.707107, 0.000000, -1.000000, 0.000000, 0.500000, -0.500000, 0.707107, 0.000000, -0.707107, 0.707107, 0.000000, -0.707107, -0.707107, 0.500000, -0.500000, -0.707107, 0.707107, -0.707107, 0.000000, 0.000000, -0.707107, -0.707107, 0.707107, -0.707107, 0.000000, 0.000000, -1.000000, 0.000000, -0.500000, -0.500000, -0.707107, 0.000000, -0.707107, -0.707107, -0.707107, -0.707107, 0.000000, 0.000000, -0.707107, -0.707107, 0.000000, -1.000000, 0.000000, -0.707107, -0.707107, 0.000000, -0.707107, -0.707107, 0.000000, 0.000000, -1.000000, 0.000000, 0.000000, -0.707107, 0.707107, -0.707107, -0.707107, 0.000000, 0.000000, -0.707107, 0.707107, -0.500000, -0.500000, 0.707107, -1.000000, -0.000000, 0.000000, -0.707107, -0.707107, 0.000000, -0.500000, -0.500000, 0.707107, -1.000000, -0.000000, 0.000000, -0.500000, -0.500000, 0.707107, -0.707107, -0.000000, 0.707107, -0.707107, -0.000000, -0.707107, -0.500000, -0.500000, -0.707107, -0.707107, -0.707107, 0.000000, -0.707107, -0.000000, -0.707107, -0.707107, -0.707107, 0.000000, -1.000000, -0.000000, 0.000000, -0.500000, 0.500000, -0.707107, -0.707107, -0.000000, -0.707107, -1.000000, -0.000000, 0.000000, -0.500000, 0.500000, -0.707107, -1.000000, -0.000000, 0.000000, -0.707107, 0.707107, 0.000000, -0.707107, 0.707107, 0.000000, -1.000000, -0.000000, 0.000000, -0.707107, -0.000000, 0.707107, -0.707107, 0.707107, 0.000000, -0.707107, -0.000000, 0.707107, -0.500000, 0.500000, 0.707107, -0.000000, 1.000000, 0.000000, -0.707107, 0.707107, 0.000000, -0.500000, 0.500000, 0.707107, -0.000000, 1.000000, 0.000000, -0.500000, 0.500000, 0.707107, -0.000000, 0.707107, 0.707107, -0.000000, 0.707107, -0.707107, -0.500000, 0.500000, -0.707107, -0.707107, 0.707107, 0.000000, -0.000000, 0.707107, -0.707107, -0.707107, 0.707107, 0.000000, -0.000000, 1.000000, 0.000000, 0.500000, 0.500000, -0.707107, -0.000000, 0.707107, -0.707107, -0.000000, 1.000000, 0.000000, 0.500000, 0.500000, -0.707107, -0.000000, 1.000000, 0.000000, 0.707107, 0.707107, 0.000000, 0.707107, 0.707107, 0.000000, -0.000000, 1.000000, 0.000000, -0.000000, 0.707107, 0.707107, 0.707107, 0.707107, 0.000000, -0.000000, 0.707107, 0.707107, 0.500000, 0.500000, 0.707107, 1.000000, 0.000000, -0.000000, 0.707107, 0.707107, 0.000000, 0.500000, 0.500000, 0.707107, 1.000000, 0.000000, -0.000000, 0.500000, 0.500000, 0.707107, 0.707107, 0.000000, 0.707107, 0.707107, 0.000000, -0.707107, 0.500000, 0.500000, -0.707107, 0.707107, 0.707107, 0.000000, 0.707107, 0.000000, -0.707107, 0.707107, 0.707107, 0.000000, 1.000000, 0.000000, -0.000000 };
  11. uint Renderer::Is::sMOUvSVboId = 0;
  12. //=====================================================================================================================================
  13. // initSMOUvS =
  14. //=====================================================================================================================================
  15. void Renderer::Is::initSMOUvS()
  16. {
  17. DEBUG_ERR( sMOUvSVboId != 0 );
  18. glGenBuffers( 1, &sMOUvSVboId );
  19. glBindBuffer( GL_ARRAY_BUFFER, sMOUvSVboId );
  20. glBufferData( GL_ARRAY_BUFFER, sizeof(sMOUvSVboId), sMOUvSCoords, GL_STATIC_DRAW );
  21. glBindBuffer( GL_ARRAY_BUFFER, 0 );
  22. }
  23. //=====================================================================================================================================
  24. // renderSMOUvS =
  25. //=====================================================================================================================================
  26. void Renderer::Is::renderSMOUvS( const PointLight& light )
  27. {
  28. const float scale = 1.2;
  29. /// @todo Replace the rendering code. Use shader prog
  30. /// @todo correct the bellow
  31. /*R::multMatrix( Mat4( light.getWorldTransform().getOrigin(), Mat3::getIdentity(), light.radius*scale ) );
  32. R::noShaders();*/
  33. glBindBuffer( GL_ARRAY_BUFFER, sMOUvSVboId );
  34. glEnableClientState( GL_VERTEX_ARRAY );
  35. glVertexPointer( 3, GL_FLOAT, 0, 0 );
  36. glDrawArrays( GL_TRIANGLES, 0, sizeof(sMOUvSCoords)/sizeof(float)/3 );
  37. glDisableClientState( GL_VERTEX_ARRAY );
  38. glBindBuffer( GL_ARRAY_BUFFER, 0 );
  39. }
  40. //=====================================================================================================================================
  41. // CalcViewVector =
  42. //=====================================================================================================================================
  43. void Renderer::Is::calcViewVector()
  44. {
  45. const Camera& cam = *r.cam;
  46. int w = r.width;
  47. int h = r.height;
  48. int pixels[4][2]={ {w,h}, {0,h}, { 0,0 }, {w,0} }; // from righ up and CC wise to right down, Just like we render the quad
  49. int viewport[4]={ 0, 0, w, h };
  50. for( int i=0; i<4; i++ )
  51. {
  52. /* Original Code:
  53. R::UnProject( pixels[i][0], pixels[i][1], 10, cam.getViewMatrix(), cam.getProjectionMatrix(), viewport,
  54. view_vectors[i].x, view_vectors[i].y, view_vectors[i].z );
  55. view_vectors[i] = cam.getViewMatrix() * view_vectors[i];
  56. The original code is the above 3 lines. The optimized follows:*/
  57. Vec3 vec;
  58. vec.x = (2.0*(pixels[i][0]-viewport[0]))/viewport[2] - 1.0;
  59. vec.y = (2.0*(pixels[i][1]-viewport[1]))/viewport[3] - 1.0;
  60. vec.z = 1.0;
  61. viewVectors[i] = vec.getTransformed( cam.getInvProjectionMatrix() );
  62. // end of optimized code
  63. }
  64. }
  65. //=====================================================================================================================================
  66. // calcPlanes =
  67. //=====================================================================================================================================
  68. void Renderer::Is::calcPlanes()
  69. {
  70. const Camera& cam = *r.cam;
  71. planes.x = -cam.getZFar() / (cam.getZFar() - cam.getZNear());
  72. planes.y = -cam.getZFar() * cam.getZNear() / (cam.getZFar() - cam.getZNear());
  73. }
  74. //=====================================================================================================================================
  75. // initFbo =
  76. //=====================================================================================================================================
  77. void Renderer::Is::initFbo()
  78. {
  79. // create FBO
  80. fbo.create();
  81. fbo.bind();
  82. // init the stencil render buffer
  83. glGenRenderbuffers( 1, &stencilRb );
  84. glBindRenderbuffer( GL_RENDERBUFFER, stencilRb );
  85. glRenderbufferStorage( GL_RENDERBUFFER, GL_STENCIL_INDEX, r.width, r.height );
  86. glFramebufferRenderbufferEXT( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencilRb );
  87. // inform in what buffers we draw
  88. fbo.setNumOfColorAttachements( 1 );
  89. // create the txtrs
  90. if( !fai.createEmpty2D( r.width, r.height, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE ) )
  91. FATAL( "Cannot create deferred shading illumination stage FAI" );
  92. // attach
  93. glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fai.getGlId(), 0 );
  94. // test if success
  95. if( !fbo.isGood() )
  96. FATAL( "Cannot create deferred shading illumination stage FBO" );
  97. // unbind
  98. fbo.unbind();
  99. }
  100. //=====================================================================================================================================
  101. // init =
  102. //=====================================================================================================================================
  103. void Renderer::Is::init()
  104. {
  105. /// @todo see what to do with the commented code
  106. // load the shaders
  107. ambientPassSProg.customLoad( "shaders/is_ap.glsl" );
  108. ambientPassSProg.uniLocs.ambientCol = ambientPassSProg.getUniVar("ambientCol")->getLoc();
  109. ambientPassSProg.uniLocs.sceneColMap = ambientPassSProg.getUniVar("sceneColMap")->getLoc();
  110. pointLightSProg.customLoad( "shaders/is_lp_generic.glsl", "#define _POINT_LIGHT_\n" );
  111. pointLightSProg.uniLocs.msNormalFai = pointLightSProg.getUniVar("msNormalFai")->getLoc();
  112. pointLightSProg.uniLocs.msDiffuseFai = pointLightSProg.getUniVar("msDiffuseFai")->getLoc();
  113. pointLightSProg.uniLocs.msSpecularFai = pointLightSProg.getUniVar("msSpecularFai")->getLoc();
  114. pointLightSProg.uniLocs.msDepthFai = pointLightSProg.getUniVar("msDepthFai")->getLoc();
  115. pointLightSProg.uniLocs.planes = pointLightSProg.getUniVar("planes")->getLoc();
  116. pointLightSProg.uniLocs.lightPos = pointLightSProg.getUniVar("lightPos")->getLoc();
  117. pointLightSProg.uniLocs.lightInvRadius = pointLightSProg.getUniVar("lightInvRadius")->getLoc();
  118. pointLightSProg.uniLocs.lightDiffuseCol = pointLightSProg.getUniVar("lightDiffuseCol")->getLoc();
  119. pointLightSProg.uniLocs.lightSpecularCol = pointLightSProg.getUniVar("lightSpecularCol")->getLoc();
  120. spotLightNoShadowSProg.customLoad( "shaders/is_lp_generic.glsl", "#define _SPOT_LIGHT_\n" );
  121. spotLightNoShadowSProg.uniLocs.msNormalFai = spotLightNoShadowSProg.getUniVar("msNormalFai")->getLoc();
  122. spotLightNoShadowSProg.uniLocs.msDiffuseFai = spotLightNoShadowSProg.getUniVar("msDiffuseFai")->getLoc();
  123. spotLightNoShadowSProg.uniLocs.msSpecularFai = spotLightNoShadowSProg.getUniVar("msSpecularFai")->getLoc();
  124. spotLightNoShadowSProg.uniLocs.msDepthFai = spotLightNoShadowSProg.getUniVar("msDepthFai")->getLoc();
  125. spotLightNoShadowSProg.uniLocs.planes = spotLightNoShadowSProg.getUniVar("planes")->getLoc();
  126. spotLightNoShadowSProg.uniLocs.lightPos = spotLightNoShadowSProg.getUniVar("lightPos")->getLoc();
  127. spotLightNoShadowSProg.uniLocs.lightInvRadius = spotLightNoShadowSProg.getUniVar("lightInvRadius")->getLoc();
  128. spotLightNoShadowSProg.uniLocs.lightDiffuseCol = spotLightNoShadowSProg.getUniVar("lightDiffuseCol")->getLoc();
  129. spotLightNoShadowSProg.uniLocs.lightSpecularCol = spotLightNoShadowSProg.getUniVar("lightSpecularCol")->getLoc();
  130. spotLightNoShadowSProg.uniLocs.lightTex = spotLightNoShadowSProg.getUniVar("lightTex")->getLoc();
  131. spotLightNoShadowSProg.uniLocs.texProjectionMat = spotLightNoShadowSProg.getUniVar("texProjectionMat")->getLoc();
  132. spotLightShadowSProg.customLoad( "shaders/is_lp_generic.glsl", "#define _SPOT_LIGHT_\n#define _SHADOW_\n" );
  133. spotLightShadowSProg.uniLocs.msNormalFai = spotLightShadowSProg.getUniVar("msNormalFai")->getLoc();
  134. spotLightShadowSProg.uniLocs.msDiffuseFai = spotLightShadowSProg.getUniVar("msDiffuseFai")->getLoc();
  135. spotLightShadowSProg.uniLocs.msSpecularFai = spotLightShadowSProg.getUniVar("msSpecularFai")->getLoc();
  136. spotLightShadowSProg.uniLocs.msDepthFai = spotLightShadowSProg.getUniVar("msDepthFai")->getLoc();
  137. spotLightShadowSProg.uniLocs.planes = spotLightShadowSProg.getUniVar("planes")->getLoc();
  138. spotLightShadowSProg.uniLocs.lightPos = spotLightShadowSProg.getUniVar("lightPos")->getLoc();
  139. spotLightShadowSProg.uniLocs.lightInvRadius = spotLightShadowSProg.getUniVar("lightInvRadius")->getLoc();
  140. spotLightShadowSProg.uniLocs.lightDiffuseCol = spotLightShadowSProg.getUniVar("lightDiffuseCol")->getLoc();
  141. spotLightShadowSProg.uniLocs.lightSpecularCol = spotLightShadowSProg.getUniVar("lightSpecularCol")->getLoc();
  142. spotLightShadowSProg.uniLocs.lightTex = spotLightShadowSProg.getUniVar("lightTex")->getLoc();
  143. spotLightShadowSProg.uniLocs.texProjectionMat = spotLightShadowSProg.getUniVar("texProjectionMat")->getLoc();
  144. spotLightShadowSProg.uniLocs.shadowMap = spotLightShadowSProg.getUniVar("shadowMap")->getLoc();
  145. // init the rest
  146. initFbo();
  147. if( sMOUvSVboId == 0 ) initSMOUvS();
  148. sm.init();
  149. }
  150. //=====================================================================================================================================
  151. // ambientPass =
  152. //=====================================================================================================================================
  153. void Renderer::Is::ambientPass( const Vec3& color )
  154. {
  155. glDisable( GL_BLEND );
  156. // set the shader
  157. ambientPassSProg.bind();
  158. // set the uniforms
  159. glUniform3fv( ambientPassSProg.uniLocs.ambientCol, 1, &(const_cast<Vec3&>(color)[0]) );
  160. ambientPassSProg.locTexUnit( ambientPassSProg.uniLocs.sceneColMap, r.ms.diffuseFai, 0 );
  161. // Draw quad
  162. r.drawQuad( 0 );
  163. }
  164. //=====================================================================================================================================
  165. // setStencilMask [point light] =
  166. //=====================================================================================================================================
  167. void Renderer::Is::setStencilMask( const PointLight& light )
  168. {
  169. glEnable( GL_STENCIL_TEST );
  170. glClear( GL_STENCIL_BUFFER_BIT );
  171. glColorMask( false, false, false, false );
  172. glStencilFunc( GL_ALWAYS, 0x1, 0x1 );
  173. glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
  174. glDisable( GL_CULL_FACE );
  175. // set matrices
  176. /// @todo opegnl 3.x
  177. glMatrixMode( GL_MODELVIEW );
  178. glPushMatrix();
  179. glMatrixMode( GL_PROJECTION );
  180. glPushMatrix();
  181. r.setProjectionViewMatrices( *r.cam );
  182. // render sphere to stencil buffer
  183. renderSMOUvS( light );
  184. // restore matrices
  185. glMatrixMode( GL_PROJECTION );
  186. glPopMatrix();
  187. glMatrixMode( GL_MODELVIEW );
  188. glPopMatrix();
  189. glEnable( GL_CULL_FACE );
  190. glColorMask( true, true, true, true );
  191. // change the stencil func so that the light pass will only write in the masked area
  192. glStencilFunc( GL_EQUAL, 0x1, 0x1 );
  193. glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  194. }
  195. //=====================================================================================================================================
  196. // setStencilMask [spot light] =
  197. //=====================================================================================================================================
  198. void Renderer::Is::setStencilMask( const SpotLight& light )
  199. {
  200. glEnable( GL_STENCIL_TEST );
  201. glClear( GL_STENCIL_BUFFER_BIT );
  202. glColorMask( false, false, false, false );
  203. glStencilFunc( GL_ALWAYS, 0x1, 0x1 );
  204. glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
  205. glDisable( GL_CULL_FACE );
  206. // set matrices
  207. /// @todo opengl 3.x
  208. glMatrixMode( GL_MODELVIEW );
  209. glPushMatrix();
  210. glMatrixMode( GL_PROJECTION );
  211. glPushMatrix();
  212. r.setProjectionViewMatrices( *r.cam );
  213. // render camera's shape to stencil buffer
  214. r.noShaders();
  215. const Camera& lcam = light.camera;
  216. float x = lcam.getZFar() / tan( (PI-lcam.getFovX())/2 );
  217. float y = tan( lcam.getFovY()/2 ) * lcam.getZFar();
  218. float z = -lcam.getZFar();
  219. const int tris_num = 6;
  220. float verts[tris_num][3][3] = {
  221. { { 0.0, 0.0, 0.0 }, { x, -y, z }, { x, y, z } }, // right triangle
  222. { { 0.0, 0.0, 0.0 }, { x, y, z }, {-x, y, z } }, // top
  223. { { 0.0, 0.0, 0.0 }, {-x, y, z }, {-x, -y, z } }, // left
  224. { { 0.0, 0.0, 0.0 }, {-x, -y, z }, { x, -y, z } }, // bottom
  225. { { x, -y, z }, {-x, y, z }, { x, y, z } }, // front up right
  226. { { x, -y, z }, {-x, -y, z }, {-x, y, z } }, // front bottom left
  227. };
  228. r.multMatrix( Mat4(lcam.getWorldTransform()) );
  229. glEnableClientState( GL_VERTEX_ARRAY );
  230. glVertexPointer( 3, GL_FLOAT, 0, verts );
  231. glDrawArrays( GL_TRIANGLES, 0, tris_num*3 );
  232. glDisableClientState( GL_VERTEX_ARRAY );
  233. // restore matrices
  234. glMatrixMode( GL_PROJECTION );
  235. glPopMatrix();
  236. glMatrixMode( GL_MODELVIEW );
  237. glPopMatrix();
  238. glEnable( GL_CULL_FACE );
  239. glColorMask( true, true, true, true );
  240. // change the stencil func so that the light pass will only write in the masked area
  241. glStencilFunc( GL_EQUAL, 0x1, 0x1 );
  242. glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  243. }
  244. //=====================================================================================================================================
  245. // pointLightPass =
  246. //=====================================================================================================================================
  247. void Renderer::Is::pointLightPass( const PointLight& light )
  248. {
  249. const Camera& cam = *r.cam;
  250. // make a check weather the point light passes the frustum test
  251. bsphere_t sphere( light.getWorldTransform().getOrigin(), light.radius );
  252. if( !cam.insideFrustum( sphere ) ) return;
  253. // stencil optimization
  254. setStencilMask( light );
  255. // bind the shader
  256. const LightShaderProg& shader = pointLightSProg; // I dont want to type
  257. shader.bind();
  258. // bind the material stage framebuffer attachable images
  259. shader.locTexUnit( shader.uniLocs.msDepthFai, r.ms.normalFai, 0 );
  260. shader.locTexUnit( shader.uniLocs.msDiffuseFai, r.ms.diffuseFai, 1 );
  261. shader.locTexUnit( shader.uniLocs.msSpecularFai, r.ms.specularFai, 2 );
  262. shader.locTexUnit( shader.uniLocs.msDepthFai, r.ms.depthFai, 3 );
  263. glUniform2fv( shader.uniLocs.planes, 1, &planes[0] );
  264. Vec3 lightPosEyeSpace = light.getWorldTransform().getOrigin().getTransformed( cam.getViewMatrix() );
  265. glUniform3fv( shader.uniLocs.lightPos, 1, &lightPosEyeSpace[0] );
  266. glUniform1f( shader.uniLocs.lightInvRadius, 1.0/light.radius );
  267. glUniform3fv( shader.uniLocs.lightDiffuseCol, 1, &Vec3(light.lightProps->getDiffuseColor())[0] );
  268. glUniform3fv( shader.uniLocs.lightSpecularCol, 1, &Vec3(light.lightProps->getSpecularColor())[0] );
  269. // render quad
  270. glEnableVertexAttribArray( 0 );
  271. glEnableVertexAttribArray( 1 );
  272. glVertexAttribPointer( 0, 2, GL_FLOAT, false, 0, &Renderer::quadVertCoords[0] );
  273. glVertexAttribPointer( 1, 3, GL_FLOAT, false, 0, &viewVectors[0] );
  274. glDrawArrays( GL_QUADS, 0, 4 );
  275. glDisableVertexAttribArray( 0 );
  276. glDisableVertexAttribArray( 1 );
  277. // cleanup
  278. glDisable( GL_STENCIL_TEST );
  279. }
  280. //=====================================================================================================================================
  281. // spotLightPass =
  282. //=====================================================================================================================================
  283. void Renderer::Is::spotLightPass( const SpotLight& light )
  284. {
  285. const Camera& cam = *r.cam;
  286. //
  287. // first of all check if the light's camera is inside the frustum
  288. //
  289. if( !cam.insideFrustum( light.camera ) ) return;
  290. //
  291. // stencil optimization
  292. //
  293. setStencilMask( light );
  294. //
  295. // generate the shadow map (if needed)
  296. //
  297. if( light.castsShadow )
  298. {
  299. sm.run( light.camera );
  300. // restore the IS FBO
  301. fbo.bind();
  302. // and restore blending and depth test
  303. glEnable( GL_BLEND );
  304. glBlendFunc( GL_ONE, GL_ONE );
  305. glDisable( GL_DEPTH_TEST );
  306. }
  307. //
  308. // set the shader and uniforms
  309. //
  310. const LightShaderProg* shdr; // because of the huge name
  311. if( light.castsShadow ) shdr = &spotLightShadowSProg;
  312. else shdr = &spotLightNoShadowSProg;
  313. shdr->bind();
  314. // bind the framebuffer attachable images
  315. shdr->locTexUnit( shdr->uniLocs.msNormalFai, r.ms.normalFai, 0 );
  316. shdr->locTexUnit( shdr->uniLocs.msDiffuseFai, r.ms.diffuseFai, 1 );
  317. shdr->locTexUnit( shdr->uniLocs.msSpecularFai, r.ms.specularFai, 2 );
  318. shdr->locTexUnit( shdr->uniLocs.msDepthFai, r.ms.depthFai, 3 );
  319. if( light.lightProps->getTexture() == NULL )
  320. ERROR( "No texture is attached to the light. lightProps name: " << light.lightProps->getRsrcName() );
  321. // the planes
  322. //glUniform2fv( shdr->getUniLoc("planes"), 1, &planes[0] );
  323. glUniform2fv( shdr->uniLocs.planes, 1, &planes[0] );
  324. // the light params
  325. Vec3 light_pos_eye_space = light.getWorldTransform().getOrigin().getTransformed( cam.getViewMatrix() );
  326. glUniform3fv( shdr->uniLocs.lightPos, 1, &light_pos_eye_space[0] );
  327. glUniform1f( shdr->uniLocs.lightInvRadius, 1.0/light.getDistance() );
  328. glUniform3fv( shdr->uniLocs.lightDiffuseCol, 1, &Vec3(light.lightProps->getDiffuseColor())[0] );
  329. glUniform3fv( shdr->uniLocs.lightSpecularCol, 1, &Vec3(light.lightProps->getSpecularColor())[0] );
  330. // set the light texture
  331. shdr->locTexUnit( shdr->uniLocs.lightTex, *light.lightProps->getTexture(), 4 );
  332. // before we render disable anisotropic in the light.texture because it produces artefacts. ToDo: see if this is unececeary in future drivers
  333. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  334. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  335. //
  336. // set texture matrix for shadowmap projection
  337. //
  338. // Bias * P_light * V_light * inv( V_cam )
  339. static Mat4 bias_m4( 0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0 );
  340. Mat4 texProjectionMat;
  341. texProjectionMat = bias_m4 * light.camera.getProjectionMatrix() * light.camera.getViewMatrix() * Mat4(cam.getWorldTransform());
  342. glUniformMatrix4fv( shdr->uniLocs.texProjectionMat, 1, true, &texProjectionMat[0] );
  343. // the shadow stuff
  344. // render depth to texture and then bind it
  345. if( light.castsShadow )
  346. {
  347. shdr->locTexUnit( shdr->uniLocs.shadowMap, sm.shadowMap, 5 );
  348. }
  349. //
  350. // render quad
  351. //
  352. glEnableVertexAttribArray( 0 );
  353. glEnableVertexAttribArray( 1 );
  354. glVertexAttribPointer( 0, 2, GL_FLOAT, false, 0, &Renderer::quadVertCoords[0] );
  355. glVertexAttribPointer( 1, 3, GL_FLOAT, false, 0, &viewVectors[0] );
  356. glDrawArrays( GL_QUADS, 0, 4 );
  357. glDisableVertexAttribArray( 0 );
  358. glDisableVertexAttribArray( 1 );
  359. // restore texture matrix
  360. glMatrixMode( GL_TEXTURE );
  361. glLoadIdentity();
  362. glMatrixMode(GL_MODELVIEW);
  363. glDisable( GL_STENCIL_TEST );
  364. }
  365. //=====================================================================================================================================
  366. // run =
  367. //=====================================================================================================================================
  368. void Renderer::Is::run()
  369. {
  370. // FBO
  371. fbo.bind();
  372. // OGL stuff
  373. r.setViewport( 0, 0, r.width, r.height );
  374. glMatrixMode( GL_MODELVIEW );
  375. glLoadIdentity();
  376. glDisable( GL_DEPTH_TEST );
  377. // ambient pass
  378. ambientPass( app->getScene()->getAmbientCol() );
  379. // light passes
  380. glEnable( GL_BLEND );
  381. glBlendFunc( GL_ONE, GL_ONE );
  382. calcViewVector();
  383. calcPlanes();
  384. // for all lights
  385. for( uint i=0; i<app->getScene()->lights.size(); i++ )
  386. {
  387. const Light& light = *app->getScene()->lights[i];
  388. switch( light.type )
  389. {
  390. case Light::LT_POINT:
  391. {
  392. const PointLight& pointl = static_cast<const PointLight&>(light);
  393. pointLightPass( pointl );
  394. break;
  395. }
  396. case Light::LT_SPOT:
  397. {
  398. const SpotLight& projl = static_cast<const SpotLight&>(light);
  399. spotLightPass( projl );
  400. break;
  401. }
  402. default:
  403. DEBUG_ERR( 1 );
  404. }
  405. }
  406. // FBO
  407. fbo.unbind();
  408. }