Is.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. #include <boost/lexical_cast.hpp>
  2. #include <boost/foreach.hpp>
  3. #include <boost/array.hpp>
  4. #include "Is.h"
  5. #include "Renderer.h"
  6. #include "Scene/Camera.h"
  7. #include "Scene/Light.h"
  8. #include "Scene/PointLight.h"
  9. #include "Scene/SpotLight.h"
  10. #include "Resources/LightRsrc.h"
  11. #include "Core/App.h"
  12. #include "Resources/LightRsrc.h"
  13. #include "Sm.h"
  14. #include "Smo.h"
  15. #include "Scene/Scene.h"
  16. namespace R {
  17. //==============================================================================
  18. // Constructor =
  19. //==============================================================================
  20. Is::Is(Renderer& r_):
  21. RenderingPass(r_),
  22. sm(r_),
  23. smo(r_)
  24. {}
  25. //==============================================================================
  26. // initFbo =
  27. //==============================================================================
  28. void Is::initFbo()
  29. {
  30. try
  31. {
  32. // create FBO
  33. fbo.create();
  34. fbo.bind();
  35. // inform in what buffers we draw
  36. fbo.setNumOfColorAttachements(1);
  37. // create the FAI
  38. Renderer::createFai(r.getWidth(), r.getHeight(), GL_RGB, GL_RGB,
  39. GL_FLOAT, fai);
  40. // attach
  41. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
  42. GL_TEXTURE_2D, fai.getGlId(), 0);
  43. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
  44. GL_TEXTURE_2D, copyMsDepthFai.getGlId(), 0);
  45. // test if success
  46. fbo.checkIfGood();
  47. // unbind
  48. fbo.unbind();
  49. }
  50. catch(std::exception& e)
  51. {
  52. throw EXCEPTION("Cannot create deferred shading illumination "
  53. "stage FBO: " + e.what());
  54. }
  55. }
  56. //==============================================================================
  57. // initCopy =
  58. //==============================================================================
  59. void Is::initCopy()
  60. {
  61. try
  62. {
  63. // Read
  64. readFbo.create();
  65. readFbo.bind();
  66. readFbo.setNumOfColorAttachements(0);
  67. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
  68. GL_TEXTURE_2D, r.getMs().getDepthFai().getGlId(), 0);
  69. readFbo.unbind();
  70. // Write
  71. Renderer::createFai(r.getWidth(), r.getHeight(), GL_DEPTH24_STENCIL8,
  72. GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, copyMsDepthFai);
  73. writeFbo.create();
  74. writeFbo.bind();
  75. writeFbo.setNumOfColorAttachements(0);
  76. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
  77. GL_TEXTURE_2D, copyMsDepthFai.getGlId(), 0);
  78. writeFbo.unbind();
  79. }
  80. catch(std::exception& e)
  81. {
  82. throw EXCEPTION("Cannot create deferred shading illumination stage "
  83. "additional FBO: " + e.what());
  84. }
  85. }
  86. //==============================================================================
  87. // init =
  88. //==============================================================================
  89. void Is::init(const RendererInitializer& initializer)
  90. {
  91. // init passes
  92. smo.init(initializer);
  93. sm.init(initializer);
  94. // load the shaders
  95. ambientPassSProg.loadRsrc("shaders/IsAp.glsl");
  96. // point light
  97. pointLightSProg.loadRsrc(ShaderProg::createSrcCodeToCache(
  98. "shaders/IsLpGeneric.glsl", "#define POINT_LIGHT_ENABLED\n").c_str());
  99. // spot light no shadow
  100. spotLightNoShadowSProg.loadRsrc(ShaderProg::createSrcCodeToCache(
  101. "shaders/IsLpGeneric.glsl", "#define SPOT_LIGHT_ENABLED\n").c_str());
  102. // spot light w/t shadow
  103. std::string pps = std::string("#define SPOT_LIGHT_ENABLED\n"
  104. "#define SHADOW_ENABLED\n");
  105. if(sm.isPcfEnabled())
  106. {
  107. pps += "#define PCF_ENABLED\n";
  108. }
  109. spotLightShadowSProg.loadRsrc(ShaderProg::createSrcCodeToCache(
  110. "shaders/IsLpGeneric.glsl", pps.c_str()).c_str());
  111. // init the rest
  112. initCopy();
  113. initFbo();
  114. }
  115. //==============================================================================
  116. // ambientPass =
  117. //==============================================================================
  118. void Is::ambientPass(const Vec3& color)
  119. {
  120. GlStateMachineSingleton::getInstance().enable(GL_BLEND, false);
  121. // set the shader
  122. ambientPassSProg->bind();
  123. // set the uniforms
  124. ambientPassSProg->findUniVar("ambientCol")->set(&color);
  125. ambientPassSProg->findUniVar("sceneColMap")->set(r.getMs().getDiffuseFai(),
  126. 0);
  127. // Draw quad
  128. r.drawQuad();
  129. }
  130. //==============================================================================
  131. // pointLightPass =
  132. //==============================================================================
  133. void Is::pointLightPass(const PointLight& light)
  134. {
  135. const Camera& cam = r.getCamera();
  136. // stencil optimization
  137. smo.run(light);
  138. GlStateMachineSingleton::getInstance().enable(GL_DEPTH_TEST, false);
  139. // shader prog
  140. const ShaderProg& shader = *pointLightSProg; // ensure the const-ness
  141. shader.bind();
  142. shader.findUniVar("msNormalFai")->set(r.getMs().getNormalFai(), 0);
  143. shader.findUniVar("msDiffuseFai")->set(r.getMs().getDiffuseFai(), 1);
  144. shader.findUniVar("msSpecularFai")->set(r.getMs().getSpecularFai(), 2);
  145. shader.findUniVar("msDepthFai")->set(r.getMs().getDepthFai(), 3);
  146. shader.findUniVar("planes")->set(&r.getPlanes());
  147. shader.findUniVar("limitsOfNearPlane")->set(&r.getLimitsOfNearPlane());
  148. shader.findUniVar("limitsOfNearPlane2")->set(&r.getLimitsOfNearPlane2());
  149. float zNear = cam.getZNear();
  150. shader.findUniVar("zNear")->set(&zNear);
  151. const Vec3& origin = light.getWorldTransform().getOrigin();
  152. Vec3 lightPosEyeSpace = origin.getTransformed(cam.getViewMatrix());
  153. shader.findUniVar("lightPos")->set(&lightPosEyeSpace);
  154. shader.findUniVar("lightRadius")->set(&light.getRadius());
  155. shader.findUniVar("lightDiffuseCol")->set(&light.getDiffuseCol());
  156. shader.findUniVar("lightSpecularCol")->set(&light.getSpecularCol());
  157. // render quad
  158. r.drawQuad();
  159. }
  160. //==============================================================================
  161. // spotLightPass =
  162. //==============================================================================
  163. void Is::spotLightPass(const SpotLight& light)
  164. {
  165. const Camera& cam = r.getCamera();
  166. // shadow mapping
  167. if(light.castsShadow() && sm.isEnabled())
  168. {
  169. Vec3 zAxis = light.getWorldTransform().getRotation().getColumn(2);
  170. Col::LineSegment seg(light.getWorldTransform().getOrigin(),
  171. -zAxis * light.getCamera().getZFar());
  172. const Col::Plane& plane = cam.getWSpaceFrustumPlane(Camera::FP_NEAR);
  173. float dist = seg.testPlane(plane);
  174. sm.run(light, dist);
  175. // restore the IS FBO
  176. fbo.bind();
  177. // and restore blending and depth test
  178. GlStateMachineSingleton::getInstance().enable(GL_BLEND, true);
  179. glBlendFunc(GL_ONE, GL_ONE);
  180. GlStateMachineSingleton::getInstance().enable(GL_DEPTH_TEST, false);
  181. GlStateMachineSingleton::getInstance().setViewport(0, 0,
  182. r.getWidth(), r.getHeight());
  183. }
  184. // stencil optimization
  185. smo.run(light);
  186. GlStateMachineSingleton::getInstance().enable(GL_DEPTH_TEST, false);
  187. // set the texture
  188. //light.getTexture().setRepeat(false);
  189. // shader prog
  190. const ShaderProg* shdr;
  191. if(light.castsShadow() && sm.isEnabled())
  192. {
  193. shdr = spotLightShadowSProg.get();
  194. }
  195. else
  196. {
  197. shdr = spotLightNoShadowSProg.get();
  198. }
  199. shdr->bind();
  200. // bind the FAIs
  201. shdr->findUniVar("msNormalFai")->set(r.getMs().getNormalFai(), 0);
  202. shdr->findUniVar("msDiffuseFai")->set(r.getMs().getDiffuseFai(), 1);
  203. shdr->findUniVar("msSpecularFai")->set(r.getMs().getSpecularFai(), 2);
  204. shdr->findUniVar("msDepthFai")->set(r.getMs().getDepthFai(), 3);
  205. // the ???
  206. shdr->findUniVar("planes")->set(&r.getPlanes());
  207. shdr->findUniVar("limitsOfNearPlane")->set(&r.getLimitsOfNearPlane());
  208. shdr->findUniVar("limitsOfNearPlane2")->set(&r.getLimitsOfNearPlane2());
  209. float zNear = cam.getZNear();
  210. shdr->findUniVar("zNear")->set(&zNear);
  211. // the light params
  212. const Vec3& origin = light.getWorldTransform().getOrigin();
  213. Vec3 lightPosEyeSpace = origin.getTransformed(cam.getViewMatrix());
  214. shdr->findUniVar("lightPos")->set(&lightPosEyeSpace);
  215. float tmp = light.getDistance();
  216. shdr->findUniVar("lightRadius")->set(&tmp);
  217. shdr->findUniVar("lightDiffuseCol")->set(&light.getDiffuseCol());
  218. shdr->findUniVar("lightSpecularCol")->set(&light.getSpecularCol());
  219. shdr->findUniVar("lightTex")->set(light.getTexture(), 4);
  220. // set texture matrix for texture & shadowmap projection
  221. // Bias * P_light * V_light * inv(V_cam)
  222. 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,
  223. 0.5, 0.0, 0.0, 0.0, 1.0);
  224. Mat4 texProjectionMat;
  225. texProjectionMat = biasMat4 * light.getCamera().getProjectionMatrix() *
  226. Mat4::combineTransformations(light.getCamera().getViewMatrix(),
  227. Mat4(cam.getWorldTransform()));
  228. shdr->findUniVar("texProjectionMat")->set(&texProjectionMat);
  229. // the shadowmap
  230. if(light.castsShadow() && sm.isEnabled())
  231. {
  232. shdr->findUniVar("shadowMap")->set(sm.getShadowMap(), 5);
  233. float smSize = sm.getShadowMap().getWidth();
  234. shdr->findUniVar("shadowMapSize")->set(&smSize);
  235. }
  236. // render quad
  237. r.drawQuad();
  238. }
  239. //==============================================================================
  240. // copyDepth =
  241. //==============================================================================
  242. void Is::copyDepth()
  243. {
  244. readFbo.bind(GL_READ_FRAMEBUFFER);
  245. writeFbo.bind(GL_DRAW_FRAMEBUFFER);
  246. glBlitFramebuffer(0, 0, r.getWidth(), r.getHeight(), 0, 0, r.getWidth(),
  247. r.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
  248. }
  249. //==============================================================================
  250. // run =
  251. //==============================================================================
  252. void Is::run()
  253. {
  254. // OGL stuff
  255. GlStateMachineSingleton::getInstance().setViewport(0, 0,
  256. r.getWidth(), r.getHeight());
  257. // Copy
  258. if(r.getFramesNum() % 2 == 0)
  259. {
  260. copyDepth();
  261. }
  262. // FBO
  263. fbo.bind();
  264. // ambient pass
  265. GlStateMachineSingleton::getInstance().enable(GL_DEPTH_TEST, false);
  266. ambientPass(SceneSingleton::getInstance().getAmbientCol());
  267. // light passes
  268. GlStateMachineSingleton::getInstance().enable(GL_BLEND, true);
  269. glBlendFunc(GL_ONE, GL_ONE);
  270. GlStateMachineSingleton::getInstance().enable(GL_STENCIL_TEST);
  271. // for all lights
  272. BOOST_FOREACH(const PointLight* light,
  273. r.getCamera().getVisiblePointLights())
  274. {
  275. pointLightPass(*light);
  276. }
  277. BOOST_FOREACH(const SpotLight* light, r.getCamera().getVisibleSpotLights())
  278. {
  279. spotLightPass(*light);
  280. }
  281. GlStateMachineSingleton::getInstance().disable(GL_STENCIL_TEST);
  282. // FBO
  283. //fbo.unbind();
  284. ON_GL_FAIL_THROW_EXCEPTION();
  285. }
  286. } // end namespace