💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1360 lines
43 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. /*
  2. * Copyright (C) 2017 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper Source Code.
  5. *
  6. * Antkeeper Source Code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper Source Code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper Source Code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "render-passes.hpp"
  20. #include "materials.hpp"
  21. #include <iostream>
  22. ShadowMapRenderPass::ShadowMapRenderPass():
  23. depthShader(nullptr)
  24. {
  25. modelViewProjectionParam = parameterSet.addParameter("modelViewProjection", ShaderParameter::Type::MATRIX_4, 1);
  26. }
  27. bool ShadowMapRenderPass::load(const RenderContext* renderContext)
  28. {
  29. depthShader = shaderLoader.load("data/shaders/depth-pass.glsl", &parameterSet);
  30. if (!depthShader)
  31. {
  32. return false;
  33. }
  34. return true;
  35. }
  36. void ShadowMapRenderPass::unload()
  37. {
  38. delete depthShader;
  39. depthShader = nullptr;
  40. }
  41. void ShadowMapRenderPass::render(const RenderContext* renderContext)
  42. {
  43. // Bind framebuffer and setup viewport
  44. glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
  45. glViewport(0, 0, renderTarget->width, renderTarget->height);
  46. // Clear the framebuffer depth
  47. glClearDepth(1.0);
  48. glClear(GL_DEPTH_BUFFER_BIT);
  49. // Enable depth testing
  50. glEnable(GL_DEPTH_TEST);
  51. glDepthMask(GL_TRUE);
  52. glDepthFunc(GL_LESS);
  53. // Enable backface culling
  54. glEnable(GL_CULL_FACE);
  55. glCullFace(GL_BACK);
  56. // Disable alpha blending
  57. glDisable(GL_BLEND);
  58. // Bind shader
  59. depthShader->bind();
  60. const Camera& camera = *(renderContext->camera);
  61. const std::list<RenderOperation>* operations = renderContext->queue->getOperations();
  62. // Render operations
  63. for (const RenderOperation& operation: *operations)
  64. {
  65. // Skip render operations with unsupported materials
  66. if (operation.material->getMaterialFormatID() != static_cast<unsigned int>(MaterialFormat::PHYSICAL))
  67. {
  68. continue;
  69. }
  70. const PhysicalMaterial* material = static_cast<const PhysicalMaterial*>(operation.material);
  71. // Skip non shadow casters
  72. if (!material->shadowCaster)
  73. {
  74. continue;
  75. }
  76. const Matrix4& modelMatrix = operation.transform;
  77. Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
  78. depthShader->setParameter(modelViewProjectionParam, modelViewProjectionMatrix);
  79. glBindVertexArray(operation.vao);
  80. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  81. }
  82. }
  83. ClippingRenderPass::ClippingRenderPass():
  84. shader(nullptr)
  85. {
  86. clippingPlanesParam = parameterSet.addParameter("clippingPlanes", ShaderParameter::Type::VECTOR_4, 1);
  87. modelParam = parameterSet.addParameter("modelMatrix", ShaderParameter::Type::MATRIX_4, 1);
  88. modelViewProjectionParam = parameterSet.addParameter("modelViewProjectionMatrix", ShaderParameter::Type::MATRIX_4, 1);
  89. }
  90. bool ClippingRenderPass::load(const RenderContext* renderContext)
  91. {
  92. shaderLoader.undefine();
  93. shaderLoader.define("CLIPPING_PLANE_COUNT", 1);
  94. shader = shaderLoader.load("data/shaders/clip.glsl", &parameterSet);
  95. if (!shader)
  96. {
  97. return false;
  98. }
  99. return true;
  100. }
  101. void ClippingRenderPass::unload()
  102. {
  103. delete shader;
  104. shader = nullptr;
  105. }
  106. void ClippingRenderPass::render(const RenderContext* renderContext)
  107. {
  108. glEnable(GL_CLIP_DISTANCE0);
  109. glEnable(GL_STENCIL_TEST);
  110. glDisable(GL_DEPTH_TEST);
  111. glDepthMask(GL_TRUE);
  112. glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  113. // Bind shader
  114. shader->bind();
  115. // Pass clipping planes to shader
  116. shader->setParameter(clippingPlanesParam, clippingPlane);
  117. // Grab render context parameters
  118. const Camera& camera = *(renderContext->camera);
  119. const std::list<RenderOperation>* operations = renderContext->queue->getOperations();
  120. // Two passes
  121. for (int i = 0; i < 2; ++i)
  122. {
  123. if (!i)
  124. {
  125. // Increment stencil for back faces
  126. glStencilFunc(GL_ALWAYS, 0, 0);
  127. glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
  128. glCullFace(GL_FRONT);
  129. }
  130. else
  131. {
  132. // Decrement stencil for front faces
  133. glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
  134. glCullFace(GL_BACK);
  135. }
  136. for (const RenderOperation& operation: *operations)
  137. {
  138. const Matrix4& modelMatrix = operation.transform;
  139. Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
  140. shader->setParameter(modelParam, modelMatrix);
  141. shader->setParameter(modelViewProjectionParam, modelViewProjectionMatrix);
  142. glBindVertexArray(operation.vao);
  143. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  144. }
  145. }
  146. glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  147. glEnable(GL_DEPTH_TEST);
  148. glDepthMask(GL_TRUE);
  149. glDepthFunc(GL_LESS);
  150. glDisable(GL_CLIP_DISTANCE0);
  151. }
  152. void ClippingRenderPass::setClippingPlane(const Plane& plane)
  153. {
  154. this->clippingPlane = Vector4(plane.getNormal(), plane.getDistance());
  155. }
  156. SoilRenderPass::SoilRenderPass():
  157. shader(nullptr)
  158. {
  159. horizonTexturesParam = parameterSet.addParameter("horizonTextures", ShaderParameter::Type::INT, 4);
  160. modelParam = parameterSet.addParameter("modelMatrix", ShaderParameter::Type::MATRIX_4, 1);
  161. modelViewProjectionParam = parameterSet.addParameter("modelViewProjectionMatrix", ShaderParameter::Type::MATRIX_4, 1);
  162. horizonOTexture = nullptr;
  163. horizonATexture = nullptr;
  164. horizonBTexture = nullptr;
  165. horizonCTexture = nullptr;
  166. }
  167. bool SoilRenderPass::load(const RenderContext* renderContext)
  168. {
  169. shaderLoader.define("VERTEX_POSITION", EMERGENT_VERTEX_POSITION);
  170. shaderLoader.define("VERTEX_TEXCOORD", EMERGENT_VERTEX_TEXCOORD);
  171. shaderLoader.define("VERTEX_NORMAL", EMERGENT_VERTEX_NORMAL);
  172. shader = shaderLoader.load("data/shaders/soil-profile.glsl", &parameterSet);
  173. if (!shader)
  174. {
  175. return false;
  176. }
  177. return true;
  178. }
  179. void SoilRenderPass::unload()
  180. {
  181. shaderLoader.undefine();
  182. delete shader;
  183. shader = nullptr;
  184. delete horizonOTexture;
  185. delete horizonATexture;
  186. delete horizonBTexture;
  187. delete horizonCTexture;
  188. horizonOTexture = nullptr;
  189. horizonATexture = nullptr;
  190. horizonBTexture = nullptr;
  191. horizonCTexture = nullptr;
  192. }
  193. void SoilRenderPass::render(const RenderContext* renderContext)
  194. {
  195. // Bind shader
  196. shader->bind();
  197. if (!horizonOTexture || !horizonATexture || !horizonBTexture || !horizonCTexture)
  198. {
  199. return;
  200. }
  201. // Bind textures
  202. glActiveTexture(GL_TEXTURE0);
  203. glBindTexture(GL_TEXTURE_2D, horizonOTexture->getTextureID());
  204. glActiveTexture(GL_TEXTURE1);
  205. glBindTexture(GL_TEXTURE_2D, horizonATexture->getTextureID());
  206. glActiveTexture(GL_TEXTURE2);
  207. glBindTexture(GL_TEXTURE_2D, horizonBTexture->getTextureID());
  208. glActiveTexture(GL_TEXTURE3);
  209. glBindTexture(GL_TEXTURE_2D, horizonCTexture->getTextureID());
  210. // Pass texture units to shader
  211. int textureUnits[] = {0, 1, 2, 3};
  212. shader->setParameter(horizonTexturesParam, 0, &textureUnits[0], 4);
  213. // Enable depth testing
  214. glEnable(GL_DEPTH_TEST);
  215. glDepthMask(GL_TRUE);
  216. glDepthFunc(GL_LEQUAL);
  217. // Enable backface culling
  218. glEnable(GL_CULL_FACE);
  219. glCullFace(GL_BACK);
  220. const Camera& camera = *(renderContext->camera);
  221. const std::list<RenderOperation>* operations = renderContext->queue->getOperations();
  222. // Render operations
  223. for (const RenderOperation& operation: *operations)
  224. {
  225. // Skip render operations with unsupported materials
  226. if (operation.material->getMaterialFormatID() != static_cast<unsigned int>(MaterialFormat::PHYSICAL))
  227. {
  228. continue;
  229. }
  230. const PhysicalMaterial* material = static_cast<const PhysicalMaterial*>(operation.material);
  231. if (!(material->flags & (unsigned int)PhysicalMaterial::Flags::SOIL))
  232. {
  233. continue;
  234. }
  235. const Matrix4& modelMatrix = operation.transform;
  236. Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
  237. shader->setParameter(modelParam, modelMatrix);
  238. shader->setParameter(modelViewProjectionParam, modelViewProjectionMatrix);
  239. glBindVertexArray(operation.vao);
  240. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  241. }
  242. }
  243. LightingRenderPass::LightingRenderPass():
  244. shadowMap(0),
  245. shadowCamera(nullptr),
  246. treeShadow(nullptr),
  247. diffuseCubemap(nullptr)
  248. {
  249. // Initialize bias matrix for calculating the model-view-projection-bias matrix (used for shadow map texture coordinate calculation)
  250. biasMatrix = Matrix4(
  251. 0.5f, 0.0f, 0.0f, 0.0f,
  252. 0.0f, 0.5f, 0.0f, 0.0f,
  253. 0.0f, 0.0f, 0.5f, 0.0f,
  254. 0.5f, 0.5f, 0.5f, 1.0f);
  255. modelParam = parameterSet.addParameter("modelMatrix", ShaderParameter::Type::MATRIX_4, 1);
  256. modelViewParam = parameterSet.addParameter("modelViewMatrix", ShaderParameter::Type::MATRIX_4, 1);
  257. modelViewProjectionParam = parameterSet.addParameter("modelViewProjectionMatrix", ShaderParameter::Type::MATRIX_4, 1);
  258. normalModelViewParam = parameterSet.addParameter("normalModelViewMatrix", ShaderParameter::Type::MATRIX_3, 1);
  259. normalModelParam = parameterSet.addParameter("normalModelMatrix", ShaderParameter::Type::MATRIX_3, 1);
  260. cameraPositionParam = parameterSet.addParameter("cameraPosition", ShaderParameter::Type::VECTOR_3, 1);
  261. directionalLightCountParam = parameterSet.addParameter("directionalLightCount", ShaderParameter::Type::INT, 1);
  262. directionalLightColorsParam = parameterSet.addParameter("directionalLightColors", ShaderParameter::Type::VECTOR_3, 1);
  263. directionalLightDirectionsParam = parameterSet.addParameter("directionalLightDirections", ShaderParameter::Type::VECTOR_3, 1);
  264. albedoOpacityMapParam = parameterSet.addParameter("albedoOpacityMap", ShaderParameter::Type::INT, 1);
  265. metalnessRoughnessMapParam = parameterSet.addParameter("metalnessRoughness", ShaderParameter::Type::INT, 1);
  266. normalOcclusionMapParam = parameterSet.addParameter("normalOcclusionMap", ShaderParameter::Type::INT, 1);
  267. diffuseCubemapParam = parameterSet.addParameter("diffuseCubemap", ShaderParameter::Type::INT, 1);
  268. specularCubemapParam = parameterSet.addParameter("specularCubemap", ShaderParameter::Type::INT, 1);
  269. }
  270. bool LightingRenderPass::load(const RenderContext* renderContext)
  271. {
  272. // Load tree shadow
  273. TextureLoader textureLoader;
  274. treeShadow = textureLoader.load("data/textures/tree-shadow-0.png");
  275. if (!treeShadow)
  276. {
  277. std::cerr << "Failed to load tree shadow" << std::endl;
  278. }
  279. // Load cubemap
  280. textureLoader.setCubemap(true);
  281. textureLoader.setMipmapChain(false);
  282. diffuseCubemap = textureLoader.load("data/textures/campus-diffuse.png");
  283. if (!diffuseCubemap)
  284. {
  285. std::cerr << "Failed to load cubemap" << std::endl;
  286. }
  287. textureLoader.setCubemap(true);
  288. textureLoader.setMipmapChain(true);
  289. specularCubemap = textureLoader.load("data/textures/campus-specular_m%02d.png");
  290. if (!specularCubemap)
  291. {
  292. std::cerr << "Failed to load cubemap" << std::endl;
  293. }
  294. // Load lighting shader
  295. shaderLoader.undefine();
  296. shaderLoader.define("TEXTURE_COUNT", 0);
  297. shaderLoader.define("VERTEX_POSITION", EMERGENT_VERTEX_POSITION);
  298. shaderLoader.define("VERTEX_NORMAL", EMERGENT_VERTEX_NORMAL);
  299. shaderLoader.define("VERTEX_TEXCOORD", EMERGENT_VERTEX_TEXCOORD);
  300. lightingShader = shaderLoader.load("data/shaders/lit-object.glsl", &parameterSet);
  301. if (!lightingShader)
  302. {
  303. return false;
  304. }
  305. time = 0.0f;
  306. return true;
  307. }
  308. void LightingRenderPass::unload()
  309. {
  310. delete lightingShader;
  311. lightingShader = nullptr;
  312. for (auto it = shaderCache.begin(); it != shaderCache.end(); ++it)
  313. {
  314. delete it->second;
  315. }
  316. shaderCache.clear();
  317. delete treeShadow;
  318. treeShadow = nullptr;
  319. delete diffuseCubemap;
  320. diffuseCubemap = nullptr;
  321. delete specularCubemap;
  322. specularCubemap = nullptr;
  323. }
  324. void LightingRenderPass::render(const RenderContext* renderContext)
  325. {
  326. /*
  327. time += 1.0f / 60.f;
  328. // Bind framebuffer and setup viewport
  329. glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
  330. glViewport(0, 0, renderTarget->width, renderTarget->height);
  331. // Clear the framebuffer depth
  332. //glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  333. //glClearDepth(1.0);
  334. //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  335. // Enable clipping
  336. if (renderContext->layer->getIndex() == 0)
  337. {
  338. // Clipping pass
  339. cappingRenderContext.camera = renderContext->camera;
  340. cappingRenderContext.layer = renderContext->layer;
  341. for (int i = 0; i < 5; ++i)
  342. {
  343. clippingRenderPass.setClippingPlane(clippingPlanes[i]);
  344. clippingRenderPass.render(renderContext);
  345. Transform transform = Transform::getIdentity();
  346. transform.translation = clippingPlanes[i].getNormal() * -clippingPlanes[i].getDistance();
  347. transform.scale = Vector3(150.0f);
  348. transform.rotation = glm::normalize(glm::rotation(Vector3(0, 0, -1), clippingPlanes[i].getNormal()));
  349. ModelInstance* cappingPlaneInstance = &cappingPlaneInstances[i];
  350. cappingPlaneInstance->setTransform(transform);
  351. cappingRenderQueue.clear();
  352. cappingRenderQueue.queue(cappingPlaneInstance);
  353. cappingRenderPass.render(&cappingRenderContext);
  354. }
  355. glEnable(GL_CLIP_DISTANCE0);
  356. }
  357. else
  358. {
  359. glDisable(GL_CLIP_DISTANCE0);
  360. }
  361. // Enable depth testing
  362. glEnable(GL_DEPTH_TEST);
  363. glDepthMask(GL_TRUE);
  364. glDepthFunc(GL_LEQUAL);
  365. // Enable backface culling
  366. glEnable(GL_CULL_FACE);
  367. glCullFace(GL_BACK);
  368. // Enable alpha blending
  369. glEnable(GL_BLEND);
  370. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  371. const Camera& camera = *(renderContext->camera);
  372. const std::list<RenderOperation>* operations = renderContext->queue->getOperations();
  373. // Calculate camera direction
  374. const Vector3& cameraDirection = camera.getForward();
  375. // Textures
  376. const std::size_t maxTextures = 8;
  377. int materialTexture[maxTextures];
  378. Vector2 texcoordOffset[maxTextures];
  379. Vector2 texcoordScale[maxTextures];
  380. float textureDiffuseInfluence[maxTextures];
  381. float textureSpecularInfluence[maxTextures];
  382. float textureEmissiveInfluence[maxTextures];
  383. float textureRoughnessInfluence[maxTextures];
  384. float textureOpacityInfluence[maxTextures];
  385. float textureNormalInfluence[maxTextures];
  386. for (std::size_t i = 0; i < maxTextures; ++i)
  387. {
  388. materialTexture[i] = i + 2;
  389. }
  390. // Lights
  391. // Point lights
  392. const std::size_t maxPointLightCount = 4;
  393. std::size_t pointLightCount = 0;
  394. Vector3 pointLightColor[maxPointLightCount];
  395. Vector3 pointLightPosition[maxPointLightCount];
  396. Vector3 pointLightAttenuation[maxPointLightCount];
  397. for (std::size_t i = 0; i < maxPointLightCount; ++i)
  398. pointLightColor[i] = Vector3(0.0f);
  399. // Directional lights
  400. const std::size_t maxDirectionalLightCount = 4;
  401. std::size_t directionalLightCount = 0;
  402. Vector3 directionalLightColor[maxDirectionalLightCount];
  403. Vector3 directionalLightDirection[maxDirectionalLightCount];
  404. for (std::size_t i = 0; i < maxDirectionalLightCount; ++i)
  405. directionalLightColor[i] = Vector3(0.0f);
  406. // Spotlights
  407. const std::size_t maxSpotlightCount = 4;
  408. std::size_t spotlightCount = 0;
  409. Vector3 spotlightColor[maxSpotlightCount];
  410. Vector3 spotlightPosition[maxSpotlightCount];
  411. Vector3 spotlightAttenuation[maxSpotlightCount];
  412. Vector3 spotlightDirection[maxSpotlightCount];
  413. float spotlightCutoff[maxSpotlightCount];
  414. float spotlightExponent[maxSpotlightCount];
  415. for (std::size_t i = 0; i < maxSpotlightCount; ++i)
  416. spotlightColor[i] = Vector3(0.0f);
  417. const std::list<SceneObject*>* lights = renderContext->layer->getObjects(SceneObjectType::LIGHT);
  418. if (lights != nullptr)
  419. {
  420. for (auto object: *lights)
  421. {
  422. const Light* light = static_cast<const Light*>(object);
  423. LightType lightType = light->getLightType();
  424. if (lightType == LightType::POINT)
  425. {
  426. const PointLight* pointLight = static_cast<const PointLight*>(light);
  427. pointLightColor[pointLightCount] = pointLight->getScaledColor();
  428. pointLightPosition[pointLightCount] = Vector3(camera.getView() * Vector4(pointLight->getTranslation(), 1.0f));
  429. pointLightAttenuation[pointLightCount] = pointLight->getAttenuation();
  430. ++pointLightCount;
  431. }
  432. else if (lightType == LightType::DIRECTIONAL)
  433. {
  434. const DirectionalLight* directionalLight = static_cast<const DirectionalLight*>(light);
  435. directionalLightColor[directionalLightCount] = directionalLight->getScaledColor();
  436. directionalLightDirection[directionalLightCount] = glm::normalize(Vector3(camera.getView() * Vector4(-directionalLight->getDirection(), 0.0f)));
  437. ++directionalLightCount;
  438. }
  439. else if (lightType == LightType::SPOTLIGHT)
  440. {
  441. const Spotlight* spotlight = static_cast<const Spotlight*>(light);
  442. spotlightColor[spotlightCount] = spotlight->getScaledColor();
  443. spotlightPosition[spotlightCount] = Vector3(camera.getView() * Vector4(spotlight->getTranslation(), 1.0f));
  444. spotlightAttenuation[spotlightCount] = spotlight->getAttenuation();
  445. spotlightDirection[spotlightCount] = glm::normalize(Vector3(camera.getView() * Vector4(-spotlight->getDirection(), 0.0f)));
  446. spotlightCutoff[spotlightCount] = spotlight->getCutoff();
  447. spotlightExponent[spotlightCount] = spotlight->getExponent();
  448. ++spotlightCount;
  449. }
  450. }
  451. }
  452. // Calculate the (light-space) view-projection-bias matrix
  453. Matrix4 viewProjectionBiasMatrix = biasMatrix * shadowCamera->getViewProjection();
  454. // Bind shader
  455. Shader* boundShader = nullptr;
  456. // Bind shadow map
  457. glActiveTexture(GL_TEXTURE0);
  458. glBindTexture(GL_TEXTURE_2D, shadowMap);
  459. // Bind tree shadow
  460. glActiveTexture(GL_TEXTURE1);
  461. glBindTexture(GL_TEXTURE_2D, treeShadow.getTextureID());
  462. // For each clipping plane
  463. for (int clippingPlaneIndex = 0; clippingPlaneIndex < 5; ++clippingPlaneIndex)
  464. {
  465. // Render operations
  466. for (const RenderOperation& operation: *operations)
  467. {
  468. const Material* material = operation.material;
  469. // Find shader
  470. std::size_t hashValue = material->getHashValue();
  471. auto it = shaderCache.find(hashValue);
  472. if (it == shaderCache.end())
  473. {
  474. std::cerr << "Warning: material requires unloaded shader" << std::endl;
  475. continue;
  476. }
  477. // Bind shader
  478. Shader* shader = it->second;
  479. if (shader != boundShader)
  480. {
  481. shader->bind();
  482. boundShader = shader;
  483. }
  484. // Get shader parameters
  485. ShaderParameterSet* parameters = shader->getParameters();
  486. const Matrix4& modelMatrix = operation.transform;
  487. Matrix4 modelViewMatrix = camera.getView() * modelMatrix;
  488. Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
  489. // Pass matrix parameters
  490. if (parameters->hasParameter(ShaderParameter::MODEL_MATRIX))
  491. {
  492. parameters->setValue(ShaderParameter::MODEL_MATRIX, modelMatrix);
  493. }
  494. if (parameters->hasParameter(ShaderParameter::MODEL_VIEW_MATRIX))
  495. {
  496. parameters->setValue(ShaderParameter::MODEL_VIEW_MATRIX, modelViewMatrix);
  497. }
  498. if (parameters->hasParameter(ShaderParameter::MODEL_VIEW_PROJECTION_MATRIX))
  499. {
  500. parameters->setValue(ShaderParameter::MODEL_VIEW_PROJECTION_MATRIX, modelViewProjectionMatrix);
  501. }
  502. if (parameters->hasParameter(ShaderParameter::NORMAL_MODEL_MATRIX))
  503. {
  504. Matrix3 normalModelMatrix = glm::transpose(glm::inverse(Matrix3(modelMatrix)));
  505. parameters->setValue(ShaderParameter::NORMAL_MODEL_MATRIX, normalModelMatrix);
  506. }
  507. if (parameters->hasParameter(ShaderParameter::NORMAL_MODEL_VIEW_MATRIX))
  508. {
  509. Matrix3 normalModelViewMatrix = glm::transpose(glm::inverse(Matrix3(modelViewMatrix)));
  510. parameters->setValue(ShaderParameter::NORMAL_MODEL_VIEW_MATRIX, normalModelViewMatrix);
  511. }
  512. if (parameters->hasParameter(ShaderParameter::CAMERA_DIRECTION))
  513. {
  514. parameters->setValue(ShaderParameter::CAMERA_DIRECTION, cameraDirection);
  515. }
  516. // Pass material parameters
  517. if (parameters->hasParameter(ShaderParameter::MATERIAL_DIFFUSE_COLOR))
  518. {
  519. parameters->setValue(ShaderParameter::MATERIAL_DIFFUSE_COLOR, material->getDiffuseColor());
  520. }
  521. if (parameters->hasParameter(ShaderParameter::MATERIAL_SPECULAR_COLOR))
  522. {
  523. parameters->setValue(ShaderParameter::MATERIAL_SPECULAR_COLOR, material->getSpecularColor());
  524. }
  525. if (parameters->hasParameter(ShaderParameter::MATERIAL_EMISSIVE_COLOR))
  526. {
  527. parameters->setValue(ShaderParameter::MATERIAL_EMISSIVE_COLOR, material->getEmissiveColor());
  528. }
  529. if (parameters->hasParameter(ShaderParameter::MATERIAL_ROUGHNESS))
  530. {
  531. parameters->setValue(ShaderParameter::MATERIAL_ROUGHNESS, material->getRoughness());
  532. }
  533. if (parameters->hasParameter(ShaderParameter::MATERIAL_OPACITY))
  534. {
  535. parameters->setValue(ShaderParameter::MATERIAL_OPACITY, material->getOpacity());
  536. }
  537. // Pass texture parameters
  538. if (parameters->hasParameter(ShaderParameter::MATERIAL_TEXTURE))
  539. {
  540. std::size_t textureCount = material->getTextureCount();
  541. for (std::size_t i = 0; i < textureCount; ++i)
  542. {
  543. const Texture* texture = material->getTexture(i);
  544. texcoordOffset[i] = Vector2(texture->getCoordinateOffset());
  545. texcoordScale[i] = Vector2(texture->getCoordinateScale());
  546. textureDiffuseInfluence[i] = texture->getDiffuseInfluence();
  547. textureSpecularInfluence[i] = texture->getSpecularInfluence();
  548. textureEmissiveInfluence[i] = texture->getEmissiveInfluence();
  549. textureRoughnessInfluence[i] = texture->getRoughnessInfluence();
  550. textureOpacityInfluence[i] = texture->getOpacityInfluence();
  551. textureNormalInfluence[i] = texture->getNormalInfluence();
  552. // Bind texture
  553. glActiveTexture(GL_TEXTURE2 + i);
  554. glBindTexture(GL_TEXTURE_2D, texture->getTextureID());
  555. }
  556. parameters->setValue(ShaderParameter::MATERIAL_TEXTURE, 0, &materialTexture[0], textureCount);
  557. if (parameters->hasParameter(ShaderParameter::TEXCOORD_OFFSET))
  558. parameters->setValue(ShaderParameter::TEXCOORD_OFFSET, 0, &texcoordOffset[0], textureCount);
  559. if (parameters->hasParameter(ShaderParameter::TEXCOORD_SCALE))
  560. parameters->setValue(ShaderParameter::TEXCOORD_SCALE, 0, &texcoordScale[0], textureCount);
  561. if (parameters->hasParameter(ShaderParameter::TEXTURE_DIFFUSE_INFLUENCE))
  562. parameters->setValue(ShaderParameter::TEXTURE_DIFFUSE_INFLUENCE, 0, &textureDiffuseInfluence[0], textureCount);
  563. if (parameters->hasParameter(ShaderParameter::TEXTURE_SPECULAR_INFLUENCE))
  564. parameters->setValue(ShaderParameter::TEXTURE_SPECULAR_INFLUENCE, 0, &textureSpecularInfluence[0], textureCount);
  565. if (parameters->hasParameter(ShaderParameter::TEXTURE_EMISSIVE_INFLUENCE))
  566. parameters->setValue(ShaderParameter::TEXTURE_EMISSIVE_INFLUENCE, 0, &textureEmissiveInfluence[0], textureCount);
  567. if (parameters->hasParameter(ShaderParameter::TEXTURE_ROUGHNESS_INFLUENCE))
  568. parameters->setValue(ShaderParameter::TEXTURE_ROUGHNESS_INFLUENCE, 0, &textureRoughnessInfluence[0], textureCount);
  569. if (parameters->hasParameter(ShaderParameter::TEXTURE_OPACITY_INFLUENCE))
  570. parameters->setValue(ShaderParameter::TEXTURE_OPACITY_INFLUENCE, 0, &textureOpacityInfluence[0], textureCount);
  571. if (parameters->hasParameter(ShaderParameter::TEXTURE_NORMAL_INFLUENCE))
  572. parameters->setValue(ShaderParameter::TEXTURE_NORMAL_INFLUENCE, 0, &textureNormalInfluence[0], textureCount);
  573. }
  574. // Pass lighting parameters
  575. if (parameters->hasParameter(ShaderParameter::POINT_LIGHT_COLOR))
  576. {
  577. parameters->setValue(ShaderParameter::POINT_LIGHT_COLOR, 0, &pointLightColor[0], spotlightCount);
  578. parameters->setValue(ShaderParameter::POINT_LIGHT_POSITION, 0, &pointLightPosition[0], spotlightCount);
  579. parameters->setValue(ShaderParameter::POINT_LIGHT_ATTENUATION, 0, &pointLightAttenuation[0], spotlightCount);
  580. }
  581. if (parameters->hasParameter(ShaderParameter::DIRECTIONAL_LIGHT_COLOR))
  582. {
  583. parameters->setValue(ShaderParameter::DIRECTIONAL_LIGHT_COLOR, 0, &directionalLightColor[0], directionalLightCount);
  584. parameters->setValue(ShaderParameter::DIRECTIONAL_LIGHT_DIRECTION, 0, &directionalLightDirection[0], directionalLightCount);
  585. }
  586. if (parameters->hasParameter(ShaderParameter::SPOTLIGHT_COLOR))
  587. {
  588. parameters->setValue(ShaderParameter::SPOTLIGHT_COLOR, 0, &spotlightColor[0], spotlightCount);
  589. parameters->setValue(ShaderParameter::SPOTLIGHT_POSITION, 0, &spotlightPosition[0], spotlightCount);
  590. parameters->setValue(ShaderParameter::SPOTLIGHT_ATTENUATION, 0, &spotlightAttenuation[0], spotlightCount);
  591. parameters->setValue(ShaderParameter::SPOTLIGHT_DIRECTION, 0, &spotlightDirection[0], spotlightCount);
  592. parameters->setValue(ShaderParameter::SPOTLIGHT_CUTOFF, 0, &spotlightCutoff[0], spotlightCount);
  593. parameters->setValue(ShaderParameter::SPOTLIGHT_EXPONENT, 0, &spotlightExponent[0], spotlightCount);
  594. }
  595. if (parameters->hasParameter(ShaderParameter::DIFFUSE_ENVIRONMENT_MAP))
  596. {
  597. parameters->setValue(ShaderParameter::DIFFUSE_ENVIRONMENT_MAP, 1);
  598. }
  599. if (parameters->hasParameter(ShaderParameter::SPECULAR_ENVIRONMENT_MAP))
  600. {
  601. parameters->setValue(ShaderParameter::SPECULAR_ENVIRONMENT_MAP, 2);
  602. }
  603. // Pass shadow parameters
  604. if (parameters->hasParameter(ShaderParameter::MODEL_VIEW_PROJECTION_BIAS_MATRIX))
  605. {
  606. Matrix4 modelViewProjectionBiasMatrix = viewProjectionBiasMatrix * modelMatrix;
  607. parameters->setValue(ShaderParameter::MODEL_VIEW_PROJECTION_BIAS_MATRIX, modelViewProjectionBiasMatrix);
  608. }
  609. if (parameters->hasParameter(ShaderParameter::SHADOW_MAP))
  610. {
  611. parameters->setValue(ShaderParameter::SHADOW_MAP, 0);
  612. }
  613. if (parameters->hasParameter(ShaderParameter::TREE_SHADOW))
  614. {
  615. parameters->setValue(ShaderParameter::TREE_SHADOW, 1);
  616. }
  617. if (parameters->hasParameter(ShaderParameter::TIME))
  618. {
  619. parameters->setValue(ShaderParameter::TIME, time);
  620. }
  621. // Pass clipping parameters
  622. if (parameters->hasParameter(ShaderParameter::CLIPPING_PLANES))
  623. {
  624. const Plane& clippingPlane = clippingPlanes[clippingPlaneIndex];
  625. parameters->setValue(ShaderParameter::CLIPPING_PLANES, Vector4(clippingPlane.getNormal(), clippingPlane.getDistance()));
  626. }
  627. // Draw geometry
  628. glBindVertexArray(operation.vao);
  629. if (!material->isOpaque())
  630. {
  631. //glBlendFunc(GL_ZERO, GL_SRC_COLOR);
  632. //glBlendFunc(GL_ONE, GL_ONE);
  633. //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  634. //glBlendFunc(GL_ZERO, GL_SRC_COLOR);
  635. //glDepthMask(GL_FALSE);
  636. glFrontFace(GL_CW);
  637. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  638. parameters->setValue(ShaderParameter::MATERIAL_DIFFUSE_COLOR, material->getDiffuseColor() * 0.05f);
  639. glFrontFace(GL_CCW);
  640. //glDepthMask(GL_TRUE);
  641. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  642. //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  643. }
  644. else
  645. {
  646. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  647. }
  648. }
  649. }
  650. // Disable clipping
  651. glDisable(GL_CLIP_DISTANCE0);
  652. */
  653. const Camera& camera = *(renderContext->camera);
  654. const std::list<RenderOperation>* operations = renderContext->queue->getOperations();
  655. // Enable depth testing
  656. glEnable(GL_DEPTH_TEST);
  657. glDepthMask(GL_TRUE);
  658. glDepthFunc(GL_LEQUAL);
  659. // Enable backface culling
  660. glEnable(GL_CULL_FACE);
  661. glCullFace(GL_BACK);
  662. // Enable alpha blending
  663. glEnable(GL_BLEND);
  664. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  665. // Bind shader
  666. Shader* shader = lightingShader;
  667. shader->bind();
  668. // Pass texture units to shader
  669. shader->setParameter(albedoOpacityMapParam, 0);
  670. shader->setParameter(normalOcclusionMapParam, 2);
  671. int directionalLightCount = 1;
  672. Vector3 directionalLightColors[3];
  673. Vector3 directionalLightDirections[3];
  674. directionalLightColors[0] = Vector3(1);
  675. directionalLightDirections[0] = glm::normalize(Vector3(camera.getView() * -Vector4(0, 0, -1, 0)));
  676. shader->setParameter(directionalLightCountParam, directionalLightCount);
  677. shader->setParameter(directionalLightColorsParam, 0, &directionalLightColors[0], directionalLightCount);
  678. shader->setParameter(directionalLightDirectionsParam, 0, &directionalLightDirections[0], directionalLightCount);
  679. shader->setParameter(cameraPositionParam, camera.getTranslation());
  680. glActiveTexture(GL_TEXTURE3);
  681. glBindTexture(GL_TEXTURE_CUBE_MAP, diffuseCubemap->getTextureID());
  682. shader->setParameter(diffuseCubemapParam, 3);
  683. glActiveTexture(GL_TEXTURE4);
  684. glBindTexture(GL_TEXTURE_CUBE_MAP, specularCubemap->getTextureID());
  685. shader->setParameter(specularCubemapParam, 4);
  686. Texture* albedoOpacityMap = nullptr;
  687. Texture* metalnessRoughnessMap = nullptr;
  688. Texture* normalOcclusionMap = nullptr;
  689. // Render operations
  690. for (const RenderOperation& operation: *operations)
  691. {
  692. // Skip render operations with unsupported materials
  693. if (operation.material->getMaterialFormatID() != static_cast<unsigned int>(MaterialFormat::PHYSICAL))
  694. {
  695. continue;
  696. }
  697. const PhysicalMaterial* material = static_cast<const PhysicalMaterial*>(operation.material);
  698. if (!(material->flags & (unsigned int)PhysicalMaterial::Flags::OBJECT))
  699. {
  700. continue;
  701. }
  702. // Skip render operations with unsupported vertex formats
  703. // Bind albedo-opacity map
  704. if (material->albedoOpacityMap != albedoOpacityMap)
  705. {
  706. albedoOpacityMap = material->albedoOpacityMap;
  707. if (albedoOpacityMap != nullptr)
  708. {
  709. glActiveTexture(GL_TEXTURE0);
  710. glBindTexture(GL_TEXTURE_2D, albedoOpacityMap->getTextureID());
  711. }
  712. }
  713. // Bind metalness-roughness map
  714. if (material->metalnessRoughnessMap != metalnessRoughnessMap)
  715. {
  716. metalnessRoughnessMap = material->metalnessRoughnessMap;
  717. if (metalnessRoughnessMap != nullptr)
  718. {
  719. glActiveTexture(GL_TEXTURE1);
  720. glBindTexture(GL_TEXTURE_2D, metalnessRoughnessMap->getTextureID());
  721. }
  722. }
  723. // Bind normal-occlusion map
  724. if (material->normalOcclusionMap != normalOcclusionMap)
  725. {
  726. normalOcclusionMap = material->normalOcclusionMap;
  727. if (normalOcclusionMap != nullptr)
  728. {
  729. glActiveTexture(GL_TEXTURE2);
  730. glBindTexture(GL_TEXTURE_2D, normalOcclusionMap->getTextureID());
  731. }
  732. }
  733. const Matrix4& modelMatrix = operation.transform;
  734. Matrix4 modelViewMatrix = camera.getView() * modelMatrix;
  735. Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
  736. Matrix3 normalModelViewMatrix = glm::transpose(glm::inverse(Matrix3(modelViewMatrix)));
  737. Matrix3 normalModelMatrix = glm::transpose(glm::inverse(Matrix3(modelMatrix)));
  738. shader->setParameter(modelParam, modelMatrix);
  739. shader->setParameter(modelViewParam, modelViewMatrix);
  740. shader->setParameter(modelViewProjectionParam, modelViewProjectionMatrix);
  741. shader->setParameter(normalModelViewParam, normalModelViewMatrix);
  742. shader->setParameter(normalModelParam, normalModelMatrix);
  743. glBindVertexArray(operation.vao);
  744. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  745. }
  746. }
  747. bool LightingRenderPass::loadShader(const RenderOperation& operation)
  748. {
  749. /*
  750. const std::string shaderFilename = "data/shaders/main.glsl";
  751. // Get material and its hash value
  752. const Material* material = operation.material;
  753. std::size_t hashValue = material->getHashValue();
  754. // Check if shader has already been loaded
  755. auto it = shaderCache.find(hashValue);
  756. if (it != shaderCache.end())
  757. return true;
  758. // Define shader preprocessor macros
  759. // Undefine previous definitions
  760. shaderLoader.undefine();
  761. // Clipping
  762. shaderLoader.define("CLIPPING_PLANE_COUNT", 1);
  763. // Vertex format
  764. shaderLoader.define("VERTEX_POSITION", EMERGENT_VERTEX_POSITION);
  765. shaderLoader.define("VERTEX_NORMAL", EMERGENT_VERTEX_NORMAL);
  766. //shaderLoader.define("VERTEX_COLOR", EMERGENT_VERTEX_COLOR);
  767. // Lighting
  768. // Material
  769. if (material->isShadeless())
  770. {
  771. shaderLoader.define("SHADELESS");
  772. }
  773. else
  774. {
  775. // Lighting
  776. //shaderLoader.define("POINT_LIGHT_COUNT", 1);
  777. shaderLoader.define("DIRECTIONAL_LIGHT_COUNT", 2);
  778. //shaderLoader.define("SPOTLIGHT_COUNT", 2);
  779. //shaderLoader.define("ENVIRONMENT_MAP");
  780. }
  781. if (material->isShadowReceiver())
  782. shaderLoader.define("SHADOWED");
  783. // Final
  784. shaderLoader.define("GAMMA_CORRECT");
  785. // Load shader
  786. Shader* shader = shaderLoader.load(shaderFilename);
  787. if (!shader)
  788. {
  789. std::cerr << "Failed to load shader \"" << shaderFilename << "\"" << std::endl;
  790. return false;
  791. }
  792. // Store shader in cache
  793. shaderCache[hashValue] = shader;
  794. return true;
  795. */
  796. return false;
  797. }
  798. DebugRenderPass::DebugRenderPass()
  799. {
  800. modelViewProjectionParam = parameterSet.addParameter("modelViewProjectionMatrix", ShaderParameter::Type::MATRIX_4, 1);
  801. }
  802. bool DebugRenderPass::load(const RenderContext* renderContext)
  803. {
  804. unlitSolidShader = shaderLoader.load("data/shaders/unlit-solid.glsl", &parameterSet);
  805. if (!unlitSolidShader)
  806. {
  807. return false;
  808. }
  809. const float aabbVertexData[] =
  810. {
  811. -0.5, -0.5, -0.5,
  812. 0.5, -0.5, -0.5,
  813. 0.5, 0.5, -0.5,
  814. -0.5, 0.5, -0.5,
  815. -0.5, -0.5, 0.5,
  816. 0.5, -0.5, 0.5,
  817. 0.5, 0.5, 0.5,
  818. -0.5, 0.5, 0.5,
  819. };
  820. const std::uint32_t aabbIndexData[] =
  821. {
  822. 0, 1, 1, 2, 2, 3, 3, 0,
  823. 4, 5, 5, 6, 6, 7, 7, 4,
  824. 0, 4, 1, 5, 2, 6, 3, 7
  825. };
  826. aabbVertexCount = 8;
  827. aabbIndexCount = 24;
  828. // Create AABB geometry
  829. glGenVertexArrays(1, &aabbVAO);
  830. glBindVertexArray(aabbVAO);
  831. glGenBuffers(1, &aabbVBO);
  832. glBindBuffer(GL_ARRAY_BUFFER, aabbVBO);
  833. glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * aabbVertexCount, aabbVertexData, GL_STATIC_DRAW);
  834. glEnableVertexAttribArray(EMERGENT_VERTEX_POSITION);
  835. glVertexAttribPointer(EMERGENT_VERTEX_POSITION, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (char*)0 + 0*sizeof(float));
  836. glGenBuffers(1, &aabbIBO);
  837. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, aabbIBO);
  838. glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(std::uint32_t) * aabbIndexCount, aabbIndexData, GL_STATIC_DRAW);
  839. return true;
  840. }
  841. void DebugRenderPass::unload()
  842. {
  843. delete unlitSolidShader;
  844. unlitSolidShader = nullptr;
  845. glDeleteBuffers(1, &aabbIBO);
  846. glDeleteBuffers(1, &aabbVBO);
  847. glDeleteVertexArrays(1, &aabbVAO);
  848. }
  849. void DebugRenderPass::render(const RenderContext* renderContext)
  850. {
  851. const Camera& camera = *(renderContext->camera);
  852. /*
  853. // Bind framebuffer and setup viewport
  854. glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
  855. glViewport(0, 0, renderTarget->width, renderTarget->height);
  856. // Clear the framebuffer depth
  857. glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  858. glClearDepth(1.0);
  859. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  860. // Disable depth testing
  861. glEnable(GL_DEPTH_TEST);
  862. glDepthMask(GL_TRUE);
  863. glDepthFunc(GL_LESS);
  864. */
  865. // Disable backface culling
  866. glDisable(GL_CULL_FACE);
  867. // Disable alpha blending
  868. glDisable(GL_BLEND);
  869. // Bind unlit solid shader
  870. unlitSolidShader->bind();
  871. // Bind AABB geometry
  872. glBindVertexArray(aabbVAO);
  873. const std::list<SceneObject*>* objects = renderContext->layer->getObjects();
  874. for (auto object: *objects)
  875. {
  876. if (!camera.getCullingMask()->intersects(object->getBounds()))
  877. continue;
  878. const AABB& bounds = object->getBounds();
  879. const Vector3& min = bounds.getMin();
  880. const Vector3& max = bounds.getMax();
  881. Vector3 scale = max - min;
  882. Vector3 center = (min + max) * 0.5f;
  883. const Vector3& translation = center;
  884. Matrix4 modelMatrix = glm::translate(translation) * glm::scale(scale);
  885. Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
  886. unlitSolidShader->setParameter(modelViewProjectionParam, modelViewProjectionMatrix);
  887. glDrawElements(GL_LINES, aabbIndexCount, GL_UNSIGNED_INT, (void*)0);
  888. }
  889. }
  890. UIRenderPass::UIRenderPass()
  891. {
  892. modelViewProjectionParam = parameterSet.addParameter("modelViewProjectionMatrix", ShaderParameter::Type::MATRIX_4, 1);
  893. textureParam = parameterSet.addParameter("tex", ShaderParameter::Type::INT, 1);
  894. texcoordOffsetParam = parameterSet.addParameter("texcoordOffset", ShaderParameter::Type::VECTOR_2, 1);
  895. texcoordScaleParam = parameterSet.addParameter("texcoordScale", ShaderParameter::Type::VECTOR_2, 1);
  896. }
  897. bool UIRenderPass::load(const RenderContext* renderContext)
  898. {
  899. shaderLoader.define("VERTEX_POSITION", EMERGENT_VERTEX_POSITION);
  900. shaderLoader.define("VERTEX_TEXCOORD", EMERGENT_VERTEX_TEXCOORD);
  901. shaderLoader.define("VERTEX_COLOR", EMERGENT_VERTEX_COLOR);
  902. shaderLoader.define("GAMMA_CORRECT");
  903. shaderLoader.define("TEXTURE_COUNT", 1);
  904. texturedUIShader = shaderLoader.load("data/shaders/ui.glsl", &parameterSet);
  905. shaderLoader.undefine();
  906. shaderLoader.define("VERTEX_POSITION", EMERGENT_VERTEX_POSITION);
  907. shaderLoader.define("VERTEX_COLOR", EMERGENT_VERTEX_COLOR);
  908. shaderLoader.define("GAMMA_CORRECT");
  909. untexturedUIShader = shaderLoader.load("data/shaders/ui.glsl", &parameterSet);
  910. if (!texturedUIShader || !untexturedUIShader)
  911. {
  912. return false;
  913. }
  914. return true;
  915. }
  916. void UIRenderPass::unload()
  917. {
  918. delete texturedUIShader;
  919. delete untexturedUIShader;
  920. texturedUIShader = nullptr;
  921. untexturedUIShader = nullptr;
  922. }
  923. void UIRenderPass::render(const RenderContext* renderContext)
  924. {
  925. const Camera& camera = *(renderContext->camera);
  926. // Bind framebuffer and setup viewport
  927. glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
  928. glViewport(0, 0, renderTarget->width, renderTarget->height);
  929. // Disable depth testing
  930. glDisable(GL_DEPTH_TEST);
  931. //glDepthMask(GL_FALSE);
  932. //glDepthFunc(GL_LESS);
  933. // Disable backface culling
  934. glEnable(GL_CULL_FACE);
  935. glCullFace(GL_BACK);
  936. // Enable alpha blending
  937. glEnable(GL_BLEND);
  938. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  939. glActiveTexture(GL_TEXTURE0);
  940. Shader* shader = nullptr;
  941. // Render operations
  942. const std::list<RenderOperation>* operations = renderContext->queue->getOperations();
  943. for (const RenderOperation& operation: *operations)
  944. {
  945. // Skip render operations with unsupported materials
  946. if (operation.material->getMaterialFormatID() != static_cast<unsigned int>(MaterialFormat::UI))
  947. {
  948. continue;
  949. }
  950. const UIMaterial* material = static_cast<const UIMaterial*>(operation.material);
  951. if (material->texture != nullptr)
  952. {
  953. shader = texturedUIShader;
  954. shader->bind();
  955. shader->setParameter(textureParam, 0);
  956. shader->setParameter(texcoordOffsetParam, Vector2(0.0f));
  957. shader->setParameter(texcoordScaleParam, Vector2(1.0f));
  958. glBindTexture(GL_TEXTURE_2D, material->texture->getTextureID());
  959. }
  960. else
  961. {
  962. shader = untexturedUIShader;
  963. shader->bind();
  964. }
  965. const Matrix4& modelMatrix = operation.transform;
  966. Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
  967. // Pass matrix parameters
  968. shader->setParameter(modelViewProjectionParam, modelViewProjectionMatrix);
  969. // Draw geometry
  970. glBindVertexArray(operation.vao);
  971. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  972. }
  973. }
  974. VignetteRenderPass::VignetteRenderPass():
  975. shader(nullptr)
  976. {
  977. bayerTextureParam = parameterSet.addParameter("bayerTexture", ShaderParameter::Type::INT, 1);
  978. modelViewProjectionParam = parameterSet.addParameter("modelViewProjectionMatrix", ShaderParameter::Type::MATRIX_4, 1);
  979. }
  980. bool VignetteRenderPass::load(const RenderContext* renderContext)
  981. {
  982. shaderLoader.undefine();
  983. shaderLoader.define("VERTEX_POSITION", EMERGENT_VERTEX_POSITION);
  984. shaderLoader.define("VERTEX_COLOR", EMERGENT_VERTEX_COLOR);
  985. shaderLoader.define("TEXTURE_COUNT", 1);
  986. shader = shaderLoader.load("data/shaders/vignette.glsl", &parameterSet);
  987. if (!shader)
  988. {
  989. return false;
  990. }
  991. /// @see http://www.anisopteragames.com/how-to-fix-color-banding-with-dithering/
  992. static const char pattern[] =
  993. {
  994. 0, 32, 8, 40, 2, 34, 10, 42,
  995. 48, 16, 56, 24, 50, 18, 58, 26,
  996. 12, 44, 4, 36, 14, 46, 6, 38,
  997. 60, 28, 52, 20, 62, 30, 54, 22,
  998. 3, 35, 11, 43, 1, 33, 9, 41,
  999. 51, 19, 59, 27, 49, 17, 57, 25,
  1000. 15, 47, 7, 39, 13, 45, 5, 37,
  1001. 63, 31, 55, 23, 61, 29, 53, 21
  1002. };
  1003. glGenTextures(1, &bayerTextureID);
  1004. glBindTexture(GL_TEXTURE_2D, bayerTextureID);
  1005. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  1006. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  1007. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  1008. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  1009. glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 8, 8, 0, GL_RED, GL_UNSIGNED_BYTE, pattern);
  1010. return true;
  1011. }
  1012. void VignetteRenderPass::unload()
  1013. {
  1014. delete shader;
  1015. shader = nullptr;
  1016. glDeleteTextures(1, &bayerTextureID);
  1017. }
  1018. void VignetteRenderPass::render(const RenderContext* renderContext)
  1019. {
  1020. glDisable(GL_DEPTH_TEST);
  1021. glDepthMask(GL_FALSE);
  1022. // Bind shader
  1023. shader->bind();
  1024. // Bind texture
  1025. glActiveTexture(GL_TEXTURE0);
  1026. glBindTexture(GL_TEXTURE_2D, bayerTextureID);
  1027. // Pass texture unit to shader
  1028. shader->setParameter(bayerTextureParam, 0);
  1029. const Camera& camera = *(renderContext->camera);
  1030. const std::list<RenderOperation>* operations = renderContext->queue->getOperations();
  1031. // Render operations
  1032. for (const RenderOperation& operation: *operations)
  1033. {
  1034. const Material* material = operation.material;
  1035. const Matrix4& modelMatrix = operation.transform;
  1036. Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
  1037. shader->setParameter(modelViewProjectionParam, modelViewProjectionMatrix);
  1038. glBindVertexArray(operation.vao);
  1039. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  1040. }
  1041. }
  1042. SkyboxRenderPass::SkyboxRenderPass():
  1043. shader(nullptr),
  1044. cubemap(nullptr)
  1045. {
  1046. matrixParam = parameterSet.addParameter("matrix", ShaderParameter::Type::MATRIX_4, 1);
  1047. cubemapParam = parameterSet.addParameter("cubemap", ShaderParameter::Type::INT, 1);
  1048. }
  1049. bool SkyboxRenderPass::load(const RenderContext* renderContext)
  1050. {
  1051. shaderLoader.undefine();
  1052. shaderLoader.define("VERTEX_POSITION", EMERGENT_VERTEX_POSITION);
  1053. shader = shaderLoader.load("data/shaders/skybox.glsl", &parameterSet);
  1054. if (!shader)
  1055. {
  1056. return false;
  1057. }
  1058. const float quadVertexData[] =
  1059. {
  1060. -1.0f, 1.0f, 0.0f,
  1061. -1.0f, -1.0f, 0.0f,
  1062. 1.0f, -1.0f, 0.0f,
  1063. 1.0f, 1.0f, 0.0f
  1064. };
  1065. const std::uint32_t quadIndexData[] =
  1066. {
  1067. 0, 1, 3,
  1068. 3, 1, 2
  1069. };
  1070. quadVertexCount = 4;
  1071. quadIndexCount = 6;
  1072. // Create AABB geometry
  1073. glGenVertexArrays(1, &quadVAO);
  1074. glBindVertexArray(quadVAO);
  1075. glGenBuffers(1, &quadVBO);
  1076. glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
  1077. glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * quadVertexCount, quadVertexData, GL_STATIC_DRAW);
  1078. glEnableVertexAttribArray(EMERGENT_VERTEX_POSITION);
  1079. glVertexAttribPointer(EMERGENT_VERTEX_POSITION, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (char*)0 + 0*sizeof(float));
  1080. glGenBuffers(1, &quadIBO);
  1081. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadIBO);
  1082. glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(std::uint32_t) * quadIndexCount, quadIndexData, GL_STATIC_DRAW);
  1083. return true;
  1084. }
  1085. void SkyboxRenderPass::unload()
  1086. {
  1087. delete shader;
  1088. shader = nullptr;
  1089. glDeleteBuffers(1, &quadIBO);
  1090. glDeleteBuffers(1, &quadVBO);
  1091. glDeleteVertexArrays(1, &quadVAO);
  1092. }
  1093. void SkyboxRenderPass::render(const RenderContext* renderContext)
  1094. {
  1095. if (!cubemap)
  1096. {
  1097. return;
  1098. }
  1099. glDisable(GL_DEPTH_TEST);
  1100. glDepthMask(GL_FALSE);
  1101. //glDisable(GL_CULL_FACE);
  1102. //glCullFace(GL_BACK);
  1103. // Bind shader
  1104. shader->bind();
  1105. // Bind cubemap texture
  1106. glActiveTexture(GL_TEXTURE0);
  1107. glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap->getTextureID());
  1108. // Pass texture unit to shader
  1109. shader->setParameter(cubemapParam, 0);
  1110. // Calculate matrix
  1111. const Camera& camera = *(renderContext->camera);
  1112. Matrix4 modelView = Matrix4(Matrix3(camera.getView()));
  1113. Matrix4 matrix = glm::inverse(modelView) * glm::inverse(camera.getProjection());
  1114. // Pass matrix to shader
  1115. shader->setParameter(matrixParam, matrix);
  1116. // Render quad
  1117. glBindVertexArray(quadVAO);
  1118. glDrawElementsBaseVertex(GL_TRIANGLES, quadIndexCount, GL_UNSIGNED_INT, (void*)0, 0);
  1119. }