Is.cpp 11 KB

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