Is.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  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.findUniVar("ambientCol")->getLoc();
  109. ambientPassSProg.uniLocs.sceneColMap = ambientPassSProg.findUniVar("sceneColMap")->getLoc();
  110. pointLightSProg.customLoad( "shaders/is_lp_generic.glsl", "#define _POINT_LIGHT_\n" );
  111. pointLightSProg.uniLocs.msNormalFai = pointLightSProg.findUniVar("msNormalFai")->getLoc();
  112. pointLightSProg.uniLocs.msDiffuseFai = pointLightSProg.findUniVar("msDiffuseFai")->getLoc();
  113. pointLightSProg.uniLocs.msSpecularFai = pointLightSProg.findUniVar("msSpecularFai")->getLoc();
  114. pointLightSProg.uniLocs.msDepthFai = pointLightSProg.findUniVar("msDepthFai")->getLoc();
  115. pointLightSProg.uniLocs.planes = pointLightSProg.findUniVar("planes")->getLoc();
  116. pointLightSProg.uniLocs.lightPos = pointLightSProg.findUniVar("lightPos")->getLoc();
  117. pointLightSProg.uniLocs.lightInvRadius = pointLightSProg.findUniVar("lightInvRadius")->getLoc();
  118. pointLightSProg.uniLocs.lightDiffuseCol = pointLightSProg.findUniVar("lightDiffuseCol")->getLoc();
  119. pointLightSProg.uniLocs.lightSpecularCol = pointLightSProg.findUniVar("lightSpecularCol")->getLoc();
  120. spotLightNoShadowSProg.customLoad( "shaders/is_lp_generic.glsl", "#define _SPOT_LIGHT_\n" );
  121. spotLightNoShadowSProg.uniLocs.msNormalFai = spotLightNoShadowSProg.findUniVar("msNormalFai")->getLoc();
  122. spotLightNoShadowSProg.uniLocs.msDiffuseFai = spotLightNoShadowSProg.findUniVar("msDiffuseFai")->getLoc();
  123. spotLightNoShadowSProg.uniLocs.msSpecularFai = spotLightNoShadowSProg.findUniVar("msSpecularFai")->getLoc();
  124. spotLightNoShadowSProg.uniLocs.msDepthFai = spotLightNoShadowSProg.findUniVar("msDepthFai")->getLoc();
  125. spotLightNoShadowSProg.uniLocs.planes = spotLightNoShadowSProg.findUniVar("planes")->getLoc();
  126. spotLightNoShadowSProg.uniLocs.lightPos = spotLightNoShadowSProg.findUniVar("lightPos")->getLoc();
  127. spotLightNoShadowSProg.uniLocs.lightInvRadius = spotLightNoShadowSProg.findUniVar("lightInvRadius")->getLoc();
  128. spotLightNoShadowSProg.uniLocs.lightDiffuseCol = spotLightNoShadowSProg.findUniVar("lightDiffuseCol")->getLoc();
  129. spotLightNoShadowSProg.uniLocs.lightSpecularCol = spotLightNoShadowSProg.findUniVar("lightSpecularCol")->getLoc();
  130. spotLightNoShadowSProg.uniLocs.lightTex = spotLightNoShadowSProg.findUniVar("lightTex")->getLoc();
  131. spotLightNoShadowSProg.uniLocs.texProjectionMat = spotLightNoShadowSProg.findUniVar("texProjectionMat")->getLoc();
  132. spotLightShadowSProg.customLoad( "shaders/is_lp_generic.glsl", "#define _SPOT_LIGHT_\n#define _SHADOW_\n" );
  133. spotLightShadowSProg.uniLocs.msNormalFai = spotLightShadowSProg.findUniVar("msNormalFai")->getLoc();
  134. spotLightShadowSProg.uniLocs.msDiffuseFai = spotLightShadowSProg.findUniVar("msDiffuseFai")->getLoc();
  135. spotLightShadowSProg.uniLocs.msSpecularFai = spotLightShadowSProg.findUniVar("msSpecularFai")->getLoc();
  136. spotLightShadowSProg.uniLocs.msDepthFai = spotLightShadowSProg.findUniVar("msDepthFai")->getLoc();
  137. spotLightShadowSProg.uniLocs.planes = spotLightShadowSProg.findUniVar("planes")->getLoc();
  138. spotLightShadowSProg.uniLocs.lightPos = spotLightShadowSProg.findUniVar("lightPos")->getLoc();
  139. spotLightShadowSProg.uniLocs.lightInvRadius = spotLightShadowSProg.findUniVar("lightInvRadius")->getLoc();
  140. spotLightShadowSProg.uniLocs.lightDiffuseCol = spotLightShadowSProg.findUniVar("lightDiffuseCol")->getLoc();
  141. spotLightShadowSProg.uniLocs.lightSpecularCol = spotLightShadowSProg.findUniVar("lightSpecularCol")->getLoc();
  142. spotLightShadowSProg.uniLocs.lightTex = spotLightShadowSProg.findUniVar("lightTex")->getLoc();
  143. spotLightShadowSProg.uniLocs.texProjectionMat = spotLightShadowSProg.findUniVar("texProjectionMat")->getLoc();
  144. spotLightShadowSProg.uniLocs.shadowMap = spotLightShadowSProg.findUniVar("shadowMap")->getLoc();
  145. // init the rest
  146. initFbo();
  147. if( sMOUvSVboId == 0 )
  148. initSMOUvS();
  149. if( sm.enabled )
  150. sm.init();
  151. }
  152. //=====================================================================================================================================
  153. // ambientPass =
  154. //=====================================================================================================================================
  155. void Renderer::Is::ambientPass( const Vec3& color )
  156. {
  157. glDisable( GL_BLEND );
  158. // set the shader
  159. ambientPassSProg.bind();
  160. // set the uniforms
  161. glUniform3fv( ambientPassSProg.uniLocs.ambientCol, 1, &(const_cast<Vec3&>(color)[0]) );
  162. ambientPassSProg.locTexUnit( ambientPassSProg.uniLocs.sceneColMap, r.ms.diffuseFai, 0 );
  163. // Draw quad
  164. r.drawQuad( 0 );
  165. }
  166. //=====================================================================================================================================
  167. // setStencilMask [point light] =
  168. //=====================================================================================================================================
  169. void Renderer::Is::setStencilMask( const PointLight& light )
  170. {
  171. glEnable( GL_STENCIL_TEST );
  172. glClear( GL_STENCIL_BUFFER_BIT );
  173. glColorMask( false, false, false, false );
  174. glStencilFunc( GL_ALWAYS, 0x1, 0x1 );
  175. glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
  176. glDisable( GL_CULL_FACE );
  177. // set matrices
  178. /// @todo opegnl 3.x
  179. glMatrixMode( GL_MODELVIEW );
  180. glPushMatrix();
  181. glMatrixMode( GL_PROJECTION );
  182. glPushMatrix();
  183. r.setProjectionViewMatrices( *r.cam );
  184. // render sphere to stencil buffer
  185. renderSMOUvS( light );
  186. // restore matrices
  187. glMatrixMode( GL_PROJECTION );
  188. glPopMatrix();
  189. glMatrixMode( GL_MODELVIEW );
  190. glPopMatrix();
  191. glEnable( GL_CULL_FACE );
  192. glColorMask( true, true, true, true );
  193. // change the stencil func so that the light pass will only write in the masked area
  194. glStencilFunc( GL_EQUAL, 0x1, 0x1 );
  195. glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  196. }
  197. //=====================================================================================================================================
  198. // setStencilMask [spot light] =
  199. //=====================================================================================================================================
  200. void Renderer::Is::setStencilMask( const SpotLight& light )
  201. {
  202. glEnable( GL_STENCIL_TEST );
  203. glClear( GL_STENCIL_BUFFER_BIT );
  204. glColorMask( false, false, false, false );
  205. glStencilFunc( GL_ALWAYS, 0x1, 0x1 );
  206. glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
  207. glDisable( GL_CULL_FACE );
  208. // set matrices
  209. /// @todo opengl 3.x
  210. glMatrixMode( GL_MODELVIEW );
  211. glPushMatrix();
  212. glMatrixMode( GL_PROJECTION );
  213. glPushMatrix();
  214. r.setProjectionViewMatrices( *r.cam );
  215. // render camera's shape to stencil buffer
  216. r.noShaders();
  217. const Camera& lcam = light.camera;
  218. float x = lcam.getZFar() / tan( (PI-lcam.getFovX())/2 );
  219. float y = tan( lcam.getFovY()/2 ) * lcam.getZFar();
  220. float z = -lcam.getZFar();
  221. const int tris_num = 6;
  222. float verts[tris_num][3][3] = {
  223. { { 0.0, 0.0, 0.0 }, { x, -y, z }, { x, y, z } }, // right triangle
  224. { { 0.0, 0.0, 0.0 }, { x, y, z }, {-x, y, z } }, // top
  225. { { 0.0, 0.0, 0.0 }, {-x, y, z }, {-x, -y, z } }, // left
  226. { { 0.0, 0.0, 0.0 }, {-x, -y, z }, { x, -y, z } }, // bottom
  227. { { x, -y, z }, {-x, y, z }, { x, y, z } }, // front up right
  228. { { x, -y, z }, {-x, -y, z }, {-x, y, z } }, // front bottom left
  229. };
  230. r.multMatrix( Mat4(lcam.getWorldTransform()) );
  231. glEnableClientState( GL_VERTEX_ARRAY );
  232. glVertexPointer( 3, GL_FLOAT, 0, verts );
  233. glDrawArrays( GL_TRIANGLES, 0, tris_num*3 );
  234. glDisableClientState( GL_VERTEX_ARRAY );
  235. // restore matrices
  236. glMatrixMode( GL_PROJECTION );
  237. glPopMatrix();
  238. glMatrixMode( GL_MODELVIEW );
  239. glPopMatrix();
  240. glEnable( GL_CULL_FACE );
  241. glColorMask( true, true, true, true );
  242. // change the stencil func so that the light pass will only write in the masked area
  243. glStencilFunc( GL_EQUAL, 0x1, 0x1 );
  244. glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  245. }
  246. //=====================================================================================================================================
  247. // pointLightPass =
  248. //=====================================================================================================================================
  249. void Renderer::Is::pointLightPass( const PointLight& light )
  250. {
  251. const Camera& cam = *r.cam;
  252. // make a check weather the point light passes the frustum test
  253. bsphere_t sphere( light.getWorldTransform().getOrigin(), light.radius );
  254. if( !cam.insideFrustum( sphere ) ) return;
  255. // stencil optimization
  256. setStencilMask( light );
  257. // bind the shader
  258. const LightShaderProg& shader = pointLightSProg; // I dont want to type
  259. shader.bind();
  260. // bind the material stage framebuffer attachable images
  261. shader.locTexUnit( shader.uniLocs.msDepthFai, r.ms.normalFai, 0 );
  262. shader.locTexUnit( shader.uniLocs.msDiffuseFai, r.ms.diffuseFai, 1 );
  263. shader.locTexUnit( shader.uniLocs.msSpecularFai, r.ms.specularFai, 2 );
  264. shader.locTexUnit( shader.uniLocs.msDepthFai, r.ms.depthFai, 3 );
  265. glUniform2fv( shader.uniLocs.planes, 1, &planes[0] );
  266. Vec3 lightPosEyeSpace = light.getWorldTransform().getOrigin().getTransformed( cam.getViewMatrix() );
  267. glUniform3fv( shader.uniLocs.lightPos, 1, &lightPosEyeSpace[0] );
  268. glUniform1f( shader.uniLocs.lightInvRadius, 1.0/light.radius );
  269. glUniform3fv( shader.uniLocs.lightDiffuseCol, 1, &Vec3(light.lightProps->getDiffuseColor())[0] );
  270. glUniform3fv( shader.uniLocs.lightSpecularCol, 1, &Vec3(light.lightProps->getSpecularColor())[0] );
  271. // render quad
  272. glEnableVertexAttribArray( 0 );
  273. glEnableVertexAttribArray( 1 );
  274. glVertexAttribPointer( 0, 2, GL_FLOAT, false, 0, &Renderer::quadVertCoords[0] );
  275. glVertexAttribPointer( 1, 3, GL_FLOAT, false, 0, &viewVectors[0] );
  276. glDrawArrays( GL_QUADS, 0, 4 );
  277. glDisableVertexAttribArray( 0 );
  278. glDisableVertexAttribArray( 1 );
  279. // cleanup
  280. glDisable( GL_STENCIL_TEST );
  281. }
  282. //=====================================================================================================================================
  283. // spotLightPass =
  284. //=====================================================================================================================================
  285. void Renderer::Is::spotLightPass( const SpotLight& light )
  286. {
  287. const Camera& cam = *r.cam;
  288. //
  289. // first of all check if the light's camera is inside the frustum
  290. //
  291. if( !cam.insideFrustum( light.camera ) ) return;
  292. //
  293. // stencil optimization
  294. //
  295. setStencilMask( light );
  296. //
  297. // generate the shadow map (if needed)
  298. //
  299. if( light.castsShadow && sm.enabled )
  300. {
  301. sm.run( light.camera );
  302. // restore the IS FBO
  303. fbo.bind();
  304. // and restore blending and depth test
  305. glEnable( GL_BLEND );
  306. glBlendFunc( GL_ONE, GL_ONE );
  307. glDisable( GL_DEPTH_TEST );
  308. }
  309. //
  310. // set the shader and uniforms
  311. //
  312. const LightShaderProg* shdr; // because of the huge name
  313. if( light.castsShadow && sm.enabled )
  314. shdr = &spotLightShadowSProg;
  315. else
  316. shdr = &spotLightNoShadowSProg;
  317. shdr->bind();
  318. // bind the framebuffer attachable images
  319. shdr->locTexUnit( shdr->uniLocs.msNormalFai, r.ms.normalFai, 0 );
  320. shdr->locTexUnit( shdr->uniLocs.msDiffuseFai, r.ms.diffuseFai, 1 );
  321. shdr->locTexUnit( shdr->uniLocs.msSpecularFai, r.ms.specularFai, 2 );
  322. shdr->locTexUnit( shdr->uniLocs.msDepthFai, r.ms.depthFai, 3 );
  323. if( light.lightProps->getTexture() == NULL )
  324. ERROR( "No texture is attached to the light. lightProps name: " << light.lightProps->getRsrcName() );
  325. // the planes
  326. //glUniform2fv( shdr->getUniLoc("planes"), 1, &planes[0] );
  327. glUniform2fv( shdr->uniLocs.planes, 1, &planes[0] );
  328. // the light params
  329. Vec3 light_pos_eye_space = light.getWorldTransform().getOrigin().getTransformed( cam.getViewMatrix() );
  330. glUniform3fv( shdr->uniLocs.lightPos, 1, &light_pos_eye_space[0] );
  331. glUniform1f( shdr->uniLocs.lightInvRadius, 1.0/light.getDistance() );
  332. glUniform3fv( shdr->uniLocs.lightDiffuseCol, 1, &Vec3(light.lightProps->getDiffuseColor())[0] );
  333. glUniform3fv( shdr->uniLocs.lightSpecularCol, 1, &Vec3(light.lightProps->getSpecularColor())[0] );
  334. // set the light texture
  335. shdr->locTexUnit( shdr->uniLocs.lightTex, *light.lightProps->getTexture(), 4 );
  336. // before we render disable anisotropic in the light.texture because it produces artefacts. ToDo: see if this is unececeary in future drivers
  337. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  338. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  339. //
  340. // set texture matrix for texture & shadowmap projection
  341. //
  342. // Bias * P_light * V_light * inv( V_cam )
  343. static Mat4 biasMat4( 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 );
  344. Mat4 texProjectionMat;
  345. texProjectionMat = biasMat4 * light.camera.getProjectionMatrix() * light.camera.getViewMatrix() * Mat4(cam.getWorldTransform());
  346. glUniformMatrix4fv( shdr->uniLocs.texProjectionMat, 1, true, &texProjectionMat[0] );
  347. // the shadow stuff
  348. // render depth to texture and then bind it
  349. if( light.castsShadow && sm.enabled )
  350. {
  351. shdr->locTexUnit( shdr->uniLocs.shadowMap, sm.shadowMap, 5 );
  352. }
  353. //
  354. // render quad
  355. //
  356. glEnableVertexAttribArray( 0 );
  357. glEnableVertexAttribArray( 1 );
  358. glVertexAttribPointer( 0, 2, GL_FLOAT, false, 0, &Renderer::quadVertCoords[0] );
  359. glVertexAttribPointer( 1, 3, GL_FLOAT, false, 0, &viewVectors[0] );
  360. glDrawArrays( GL_QUADS, 0, 4 );
  361. glDisableVertexAttribArray( 0 );
  362. glDisableVertexAttribArray( 1 );
  363. // restore texture matrix
  364. glMatrixMode( GL_TEXTURE );
  365. glLoadIdentity();
  366. glMatrixMode(GL_MODELVIEW);
  367. glDisable( GL_STENCIL_TEST );
  368. }
  369. //=====================================================================================================================================
  370. // run =
  371. //=====================================================================================================================================
  372. void Renderer::Is::run()
  373. {
  374. // FBO
  375. fbo.bind();
  376. // OGL stuff
  377. r.setViewport( 0, 0, r.width, r.height );
  378. glMatrixMode( GL_MODELVIEW );
  379. glLoadIdentity();
  380. glDisable( GL_DEPTH_TEST );
  381. // ambient pass
  382. ambientPass( app->getScene()->getAmbientCol() );
  383. // light passes
  384. glEnable( GL_BLEND );
  385. glBlendFunc( GL_ONE, GL_ONE );
  386. calcViewVector();
  387. calcPlanes();
  388. // for all lights
  389. for( uint i=0; i<app->getScene()->lights.size(); i++ )
  390. {
  391. const Light& light = *app->getScene()->lights[i];
  392. switch( light.type )
  393. {
  394. case Light::LT_POINT:
  395. {
  396. const PointLight& pointl = static_cast<const PointLight&>(light);
  397. pointLightPass( pointl );
  398. break;
  399. }
  400. case Light::LT_SPOT:
  401. {
  402. const SpotLight& projl = static_cast<const SpotLight&>(light);
  403. spotLightPass( projl );
  404. break;
  405. }
  406. default:
  407. DEBUG_ERR( 1 );
  408. }
  409. }
  410. // FBO
  411. fbo.unbind();
  412. }