💿🐜 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.

1731 lines
54 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
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. #include <limits>
  23. ClearRenderPass::ClearRenderPass():
  24. clearColor(true),
  25. clearDepth(true),
  26. clearStencil(true),
  27. color(0.0f),
  28. depth(1.0f),
  29. index(0)
  30. {}
  31. bool ClearRenderPass::load(const RenderContext* renderContext)
  32. {
  33. return true;
  34. }
  35. void ClearRenderPass::unload()
  36. {}
  37. void ClearRenderPass::render(RenderContext* renderContext)
  38. {
  39. glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
  40. GLbitfield mask = 0;
  41. if (clearColor)
  42. {
  43. mask |= GL_COLOR_BUFFER_BIT;
  44. glClearColor(color[0], color[1], color[2], color[3]);
  45. }
  46. if (clearDepth)
  47. {
  48. mask |= GL_DEPTH_BUFFER_BIT;
  49. glClearDepth(depth);
  50. }
  51. if (clearStencil)
  52. {
  53. mask |= GL_STENCIL_BUFFER_BIT;
  54. glClearStencil(index);
  55. }
  56. glClear(mask);
  57. }
  58. void ClearRenderPass::setClear(bool color, bool depth, bool stencil)
  59. {
  60. clearColor = color;
  61. clearDepth = depth;
  62. clearStencil = stencil;
  63. }
  64. void ClearRenderPass::setClearColor(const Vector4& color)
  65. {
  66. this->color = color;
  67. }
  68. void ClearRenderPass::setClearDepth(float depth)
  69. {
  70. this->depth = depth;
  71. }
  72. void ClearRenderPass::setClearStencil(int index)
  73. {
  74. this->index = index;
  75. }
  76. ShadowMapRenderPass::ShadowMapRenderPass():
  77. unskinnedShader(nullptr),
  78. skinnedShader(nullptr),
  79. croppedShadowMapViewports(nullptr),
  80. viewCamera(nullptr),
  81. splitViewFrustum(nullptr),
  82. cropMatrices(nullptr),
  83. tileMatrices(nullptr)
  84. {}
  85. bool ShadowMapRenderPass::load(const RenderContext* renderContext)
  86. {
  87. // Set maximum number of bones for skinned meshes
  88. maxBoneCount = 64;
  89. // Set number of frustum splits
  90. frustumSplitCount = 4;
  91. // Create split view frustum
  92. splitViewFrustum = new SplitViewFrustum(frustumSplitCount);
  93. // Determine resolution of shadow maps
  94. shadowMapResolution = 4096;
  95. croppedShadowMapResolution = shadowMapResolution >> 1;
  96. // Allocate viewports
  97. croppedShadowMapViewports = new Vector4[frustumSplitCount];
  98. // Setup viewports
  99. for (int i = 0; i < frustumSplitCount; ++i)
  100. {
  101. int x = i % 2;
  102. int y = i / 2;
  103. Vector4* viewport = &croppedShadowMapViewports[i];
  104. (*viewport)[0] = static_cast<float>(x * croppedShadowMapResolution);
  105. (*viewport)[1] = static_cast<float>(y * croppedShadowMapResolution);
  106. (*viewport)[2] = static_cast<float>(croppedShadowMapResolution);
  107. (*viewport)[3] = static_cast<float>(croppedShadowMapResolution);
  108. }
  109. // Allocate matrices
  110. cropMatrices = new Matrix4[frustumSplitCount];
  111. tileMatrices = new Matrix4[frustumSplitCount];
  112. // Setup tile matrices
  113. Matrix4 tileScale = glm::scale(Vector3(0.5f, 0.5f, 1.0f));
  114. for (int i = 0; i < frustumSplitCount; ++i)
  115. {
  116. float x = static_cast<float>(i % 2) * 0.5f;
  117. float y = static_cast<float>(i / 2) * 0.5f;
  118. tileMatrices[i] = glm::translate(Vector3(x, y, 0.0f)) * tileScale;
  119. }
  120. // Setup shader parameters
  121. modelViewProjectionParam = parameterSet.addParameter("modelViewProjectionMatrix", ShaderParameter::Type::MATRIX_4, 1);
  122. matrixPaletteParam = parameterSet.addParameter("matrixPalette", ShaderParameter::Type::MATRIX_4, maxBoneCount);
  123. // Load unskinned shader
  124. shaderLoader.undefine();
  125. shaderLoader.define("VERTEX_POSITION", EMERGENT_VERTEX_POSITION);
  126. unskinnedShader = shaderLoader.load("data/shaders/depth-pass.glsl", &parameterSet);
  127. if (!unskinnedShader)
  128. {
  129. return false;
  130. }
  131. // Load skinned shader
  132. shaderLoader.define("SKINNED");
  133. shaderLoader.define("VERTEX_BONE_INDICES", EMERGENT_VERTEX_BONE_INDICES);
  134. shaderLoader.define("VERTEX_BONE_WEIGHTS", EMERGENT_VERTEX_BONE_WEIGHTS);
  135. shaderLoader.define("MAX_BONE_COUNT", maxBoneCount);
  136. skinnedShader = shaderLoader.load("data/shaders/depth-pass.glsl", &parameterSet);
  137. if (!skinnedShader)
  138. {
  139. return false;
  140. }
  141. return true;
  142. }
  143. void ShadowMapRenderPass::unload()
  144. {
  145. delete unskinnedShader;
  146. unskinnedShader = nullptr;
  147. delete skinnedShader;
  148. skinnedShader = nullptr;
  149. delete[] croppedShadowMapViewports;
  150. croppedShadowMapViewports = nullptr;
  151. delete splitViewFrustum;
  152. splitViewFrustum = nullptr;
  153. delete[] cropMatrices;
  154. cropMatrices = nullptr;
  155. delete[] tileMatrices;
  156. tileMatrices = nullptr;
  157. parameterSet.removeParameters();
  158. }
  159. void ShadowMapRenderPass::render(RenderContext* renderContext)
  160. {
  161. // Bind framebuffer and setup viewport
  162. glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
  163. glViewport(0, 0, renderTarget->width, renderTarget->height);
  164. // Clear the framebuffer depth
  165. glClear(GL_DEPTH_BUFFER_BIT);
  166. // Enable depth testing
  167. glEnable(GL_DEPTH_TEST);
  168. glDepthMask(GL_TRUE);
  169. glDepthFunc(GL_LESS);
  170. // Draw front and back faces
  171. glDisable(GL_CULL_FACE);
  172. // Disable alpha blending
  173. glDisable(GL_BLEND);
  174. //const Camera& lightCamera = *(renderContext->camera);
  175. const std::list<RenderOperation>* operations = renderContext->queue->getOperations();
  176. Shader* shader = nullptr;
  177. // Update split view frustum
  178. //splitViewFrustum->setMatrices(viewCamera->getView(), viewCamera->getProjection());
  179. const ViewFrustum& viewFrustum = viewCamera->getViewFrustum();
  180. // Find center of view frustum
  181. Vector3 center = Vector3(0.0f);
  182. for (std::size_t i = 0; i < viewFrustum.getCornerCount(); ++i)
  183. {
  184. center += viewFrustum.getCorner(i);
  185. }
  186. center = center * 1.0f / static_cast<float>(viewFrustum.getCornerCount());
  187. // Position light camera in center of view frustum
  188. //lightCamera->lookAt(center, center + lightCamera->getForward(), lightCamera->getUp());
  189. // Calculate split distances
  190. float clipNear = viewCamera->getClipNear();
  191. float clipFar = viewCamera->getClipFar();
  192. float* splitDistances = new float[frustumSplitCount + 1];
  193. float splitSchemeWeight = 0.5f;
  194. for (std::size_t i = 1; i < frustumSplitCount; ++i)
  195. {
  196. float part = static_cast<float>(i) / static_cast<float>(frustumSplitCount);
  197. // Calculate uniform split distance
  198. float uniformSplitDistance = clipNear + (clipFar - clipNear) * part;
  199. // Calculate logarithmic split distance
  200. float logSplitDistance = clipNear * std::pow(clipFar / clipNear, part);
  201. // Interpolate between uniform and logarithmic split distances
  202. splitDistances[i] = logSplitDistance * splitSchemeWeight + uniformSplitDistance * (1.0f - splitSchemeWeight);
  203. }
  204. splitDistances[0] = clipNear;
  205. splitDistances[frustumSplitCount] = clipFar;
  206. // For each frustum split
  207. for (int i = 0; i < frustumSplitCount; ++i)
  208. {
  209. // Calculate crop matrix
  210. {
  211. ViewFrustum frustumSplit;
  212. // Determine near and far distances for this subfrustum
  213. float splitNear = splitDistances[0];
  214. float splitFar = splitDistances[4];
  215. // Calculate subfrustum projection matrix
  216. Matrix4 splitProjection = glm::ortho(viewCamera->getClipLeft(), viewCamera->getClipRight(), viewCamera->getClipBottom(), viewCamera->getClipTop(), splitNear, splitFar);
  217. // Set subfrustum matrices
  218. frustumSplit.setMatrices(viewCamera->getView(), splitProjection);
  219. // Create AABB containing the frustum split corners
  220. AABB frustumSplitBounds(Vector3(std::numeric_limits<float>::infinity()), Vector3(-std::numeric_limits<float>::infinity()));
  221. for (std::size_t j = 0; j < frustumSplit.getCornerCount(); ++j)
  222. {
  223. frustumSplitBounds.add(frustumSplit.getCorner(j));
  224. }
  225. // Transform frustum split bounds into light's clip space
  226. AABB croppingBounds = frustumSplitBounds.transformed(lightCamera->getViewProjection());
  227. Vector3 cropMax = croppingBounds.getMax();
  228. Vector3 cropMin = croppingBounds.getMin();
  229. //cropMin.z = 0.0f;
  230. // Calculate scale
  231. Vector3 scale;
  232. scale.x = 2.0f / (cropMax.x - cropMin.x);
  233. scale.y = 2.0f / (cropMax.y - cropMin.y);
  234. scale.z = 1.0f / (cropMax.z - cropMin.z);
  235. // Quantize scale
  236. //float scaleQuantizer = 64.0f;
  237. //scale.x = 1.0f / std::ceil(1.0f / scale.x * scaleQuantizer) * scaleQuantizer;
  238. //scale.y = 1.0f / std::ceil(1.0f / scale.y * scaleQuantizer) * scaleQuantizer;
  239. // Calculate offset
  240. Vector3 offset;
  241. offset.x = (cropMax.x + cropMin.x) * scale.x * -0.5f;
  242. offset.y = (cropMax.y + cropMin.y) * scale.y * -0.5f;
  243. offset.z = -cropMin.z * scale.z;
  244. // Quantize offset
  245. //float halfTextureSize = static_cast<float>(croppedShadowMapResolution) * 0.5f;
  246. //offset.x = std::ceil(offset.x * halfTextureSize) / halfTextureSize;
  247. //offset.y = std::ceil(offset.y * halfTextureSize) / halfTextureSize;
  248. cropMatrices[i] = glm::translate(offset) * glm::scale(scale);
  249. }
  250. Matrix4 croppedViewProjection = cropMatrices[i] * lightCamera->getViewProjection();
  251. // Activate viewport for corresponding cropped shadow map
  252. const Vector4& viewport = croppedShadowMapViewports[i];
  253. glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
  254. // Render operations
  255. for (const RenderOperation& operation: *operations)
  256. {
  257. // Skip render operations with unsupported materials
  258. if (operation.material->getMaterialFormatID() != static_cast<unsigned int>(MaterialFormat::PHYSICAL))
  259. {
  260. continue;
  261. }
  262. // Skip non shadow casters
  263. const PhysicalMaterial* material = static_cast<const PhysicalMaterial*>(operation.material);
  264. if (!material->shadowCaster)
  265. {
  266. continue;
  267. }
  268. // Select shader
  269. Shader* targetShader = nullptr;
  270. if (operation.pose != nullptr)
  271. {
  272. targetShader = skinnedShader;
  273. }
  274. else
  275. {
  276. targetShader = unskinnedShader;
  277. }
  278. // Switch shader if necessary
  279. if (shader != targetShader)
  280. {
  281. shader = targetShader;
  282. // Bind shader
  283. shader->bind();
  284. }
  285. // Pass matrix palette
  286. if (operation.pose != nullptr)
  287. {
  288. shader->setParameter(matrixPaletteParam, 0, operation.pose->getMatrixPalette(), operation.pose->getSkeleton()->getBoneCount());
  289. }
  290. const Matrix4& modelMatrix = operation.transform;
  291. Matrix4 modelViewProjectionMatrix = croppedViewProjection * modelMatrix;
  292. shader->setParameter(modelViewProjectionParam, modelViewProjectionMatrix);
  293. glBindVertexArray(operation.vao);
  294. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  295. }
  296. }
  297. delete[] splitDistances;
  298. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  299. }
  300. ClippingRenderPass::ClippingRenderPass():
  301. shader(nullptr)
  302. {
  303. clippingPlanesParam = parameterSet.addParameter("clippingPlanes", ShaderParameter::Type::VECTOR_4, 1);
  304. modelParam = parameterSet.addParameter("modelMatrix", ShaderParameter::Type::MATRIX_4, 1);
  305. modelViewProjectionParam = parameterSet.addParameter("modelViewProjectionMatrix", ShaderParameter::Type::MATRIX_4, 1);
  306. }
  307. bool ClippingRenderPass::load(const RenderContext* renderContext)
  308. {
  309. shaderLoader.undefine();
  310. shaderLoader.define("CLIPPING_PLANE_COUNT", 1);
  311. shader = shaderLoader.load("data/shaders/clip.glsl", &parameterSet);
  312. if (!shader)
  313. {
  314. return false;
  315. }
  316. return true;
  317. }
  318. void ClippingRenderPass::unload()
  319. {
  320. delete shader;
  321. shader = nullptr;
  322. }
  323. void ClippingRenderPass::render(RenderContext* renderContext)
  324. {
  325. glEnable(GL_CLIP_DISTANCE0);
  326. glEnable(GL_STENCIL_TEST);
  327. glDisable(GL_DEPTH_TEST);
  328. glDepthMask(GL_TRUE);
  329. glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  330. // Bind shader
  331. shader->bind();
  332. // Pass clipping planes to shader
  333. shader->setParameter(clippingPlanesParam, clippingPlane);
  334. // Grab render context parameters
  335. const Camera& camera = *(renderContext->camera);
  336. const std::list<RenderOperation>* operations = renderContext->queue->getOperations();
  337. // Two passes
  338. for (int i = 0; i < 2; ++i)
  339. {
  340. if (!i)
  341. {
  342. // Increment stencil for back faces
  343. glStencilFunc(GL_ALWAYS, 0, 0);
  344. glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
  345. glCullFace(GL_FRONT);
  346. }
  347. else
  348. {
  349. // Decrement stencil for front faces
  350. glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
  351. glCullFace(GL_BACK);
  352. }
  353. for (const RenderOperation& operation: *operations)
  354. {
  355. const Matrix4& modelMatrix = operation.transform;
  356. Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
  357. shader->setParameter(modelParam, modelMatrix);
  358. shader->setParameter(modelViewProjectionParam, modelViewProjectionMatrix);
  359. glBindVertexArray(operation.vao);
  360. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  361. }
  362. }
  363. glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  364. glEnable(GL_DEPTH_TEST);
  365. glDepthMask(GL_TRUE);
  366. glDepthFunc(GL_LESS);
  367. glDisable(GL_CLIP_DISTANCE0);
  368. }
  369. void ClippingRenderPass::setClippingPlane(const Plane& plane)
  370. {
  371. this->clippingPlane = Vector4(plane.getNormal(), plane.getDistance());
  372. }
  373. SoilRenderPass::SoilRenderPass():
  374. shader(nullptr)
  375. {
  376. horizonTexturesParam = parameterSet.addParameter("horizonTextures", ShaderParameter::Type::INT, 4);
  377. modelParam = parameterSet.addParameter("modelMatrix", ShaderParameter::Type::MATRIX_4, 1);
  378. modelViewProjectionParam = parameterSet.addParameter("modelViewProjectionMatrix", ShaderParameter::Type::MATRIX_4, 1);
  379. horizonOTexture = nullptr;
  380. horizonATexture = nullptr;
  381. horizonBTexture = nullptr;
  382. horizonCTexture = nullptr;
  383. }
  384. bool SoilRenderPass::load(const RenderContext* renderContext)
  385. {
  386. shaderLoader.define("VERTEX_POSITION", EMERGENT_VERTEX_POSITION);
  387. shaderLoader.define("VERTEX_TEXCOORD", EMERGENT_VERTEX_TEXCOORD);
  388. shaderLoader.define("VERTEX_NORMAL", EMERGENT_VERTEX_NORMAL);
  389. shader = shaderLoader.load("data/shaders/soil-profile.glsl", &parameterSet);
  390. if (!shader)
  391. {
  392. return false;
  393. }
  394. return true;
  395. }
  396. void SoilRenderPass::unload()
  397. {
  398. shaderLoader.undefine();
  399. delete shader;
  400. shader = nullptr;
  401. delete horizonOTexture;
  402. delete horizonATexture;
  403. delete horizonBTexture;
  404. delete horizonCTexture;
  405. horizonOTexture = nullptr;
  406. horizonATexture = nullptr;
  407. horizonBTexture = nullptr;
  408. horizonCTexture = nullptr;
  409. }
  410. void SoilRenderPass::render(RenderContext* renderContext)
  411. {
  412. // Bind framebuffer and setup viewport
  413. glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
  414. glViewport(0, 0, renderTarget->width, renderTarget->height);
  415. // Bind shader
  416. shader->bind();
  417. if (!horizonOTexture || !horizonATexture || !horizonBTexture || !horizonCTexture)
  418. {
  419. return;
  420. }
  421. // Bind textures
  422. glActiveTexture(GL_TEXTURE0);
  423. glBindTexture(GL_TEXTURE_2D, horizonOTexture->getTextureID());
  424. glActiveTexture(GL_TEXTURE1);
  425. glBindTexture(GL_TEXTURE_2D, horizonATexture->getTextureID());
  426. glActiveTexture(GL_TEXTURE2);
  427. glBindTexture(GL_TEXTURE_2D, horizonBTexture->getTextureID());
  428. glActiveTexture(GL_TEXTURE3);
  429. glBindTexture(GL_TEXTURE_2D, horizonCTexture->getTextureID());
  430. // Pass texture units to shader
  431. int textureUnits[] = {0, 1, 2, 3};
  432. shader->setParameter(horizonTexturesParam, 0, &textureUnits[0], 4);
  433. // Enable depth testing
  434. glEnable(GL_DEPTH_TEST);
  435. glDepthMask(GL_TRUE);
  436. glDepthFunc(GL_LEQUAL);
  437. // Enable backface culling
  438. glEnable(GL_CULL_FACE);
  439. glCullFace(GL_BACK);
  440. const Camera& camera = *(renderContext->camera);
  441. const std::list<RenderOperation>* operations = renderContext->queue->getOperations();
  442. // Render operations
  443. for (const RenderOperation& operation: *operations)
  444. {
  445. // Skip render operations with unsupported materials
  446. if (operation.material->getMaterialFormatID() != static_cast<unsigned int>(MaterialFormat::PHYSICAL))
  447. {
  448. continue;
  449. }
  450. const PhysicalMaterial* material = static_cast<const PhysicalMaterial*>(operation.material);
  451. if (!(material->flags & (unsigned int)PhysicalMaterial::Flags::SOIL))
  452. {
  453. continue;
  454. }
  455. const Matrix4& modelMatrix = operation.transform;
  456. Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
  457. shader->setParameter(modelParam, modelMatrix);
  458. shader->setParameter(modelViewProjectionParam, modelViewProjectionMatrix);
  459. glBindVertexArray(operation.vao);
  460. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  461. }
  462. }
  463. LightingRenderPass::LightingRenderPass():
  464. shadowMap(0),
  465. shadowCamera(nullptr),
  466. treeShadow(nullptr),
  467. diffuseCubemap(nullptr),
  468. specularCubemap(nullptr),
  469. shadowMapPass(nullptr)
  470. {
  471. // Initialize bias matrix for calculating the model-view-projection-bias matrix (used for shadow map texture coordinate calculation)
  472. biasMatrix = glm::translate(Vector3(0.5f)) * glm::scale(Vector3(0.5f));
  473. maxBoneCount = 64;
  474. matrixPaletteParam = parameterSet.addParameter("matrixPalette", ShaderParameter::Type::MATRIX_4, maxBoneCount);
  475. modelParam = parameterSet.addParameter("modelMatrix", ShaderParameter::Type::MATRIX_4, 1);
  476. modelViewParam = parameterSet.addParameter("modelViewMatrix", ShaderParameter::Type::MATRIX_4, 1);
  477. modelViewProjectionParam = parameterSet.addParameter("modelViewProjectionMatrix", ShaderParameter::Type::MATRIX_4, 1);
  478. normalModelViewParam = parameterSet.addParameter("normalModelViewMatrix", ShaderParameter::Type::MATRIX_3, 1);
  479. normalModelParam = parameterSet.addParameter("normalModelMatrix", ShaderParameter::Type::MATRIX_3, 1);
  480. lightViewProjectionParam = parameterSet.addParameter("lightViewProjectionMatrix", ShaderParameter::Type::MATRIX_4, 1);
  481. shadowMapParam = parameterSet.addParameter("shadowMap", ShaderParameter::Type::INT, 1);
  482. cameraPositionParam = parameterSet.addParameter("cameraPosition", ShaderParameter::Type::VECTOR_3, 1);
  483. directionalLightCountParam = parameterSet.addParameter("directionalLightCount", ShaderParameter::Type::INT, 1);
  484. directionalLightColorsParam = parameterSet.addParameter("directionalLightColors", ShaderParameter::Type::VECTOR_3, 1);
  485. directionalLightDirectionsParam = parameterSet.addParameter("directionalLightDirections", ShaderParameter::Type::VECTOR_3, 1);
  486. albedoOpacityMapParam = parameterSet.addParameter("albedoOpacityMap", ShaderParameter::Type::INT, 1);
  487. metalnessRoughnessMapParam = parameterSet.addParameter("metalnessRoughnessMap", ShaderParameter::Type::INT, 1);
  488. normalOcclusionMapParam = parameterSet.addParameter("normalOcclusionMap", ShaderParameter::Type::INT, 1);
  489. diffuseCubemapParam = parameterSet.addParameter("diffuseCubemap", ShaderParameter::Type::INT, 1);
  490. specularCubemapParam = parameterSet.addParameter("specularCubemap", ShaderParameter::Type::INT, 1);
  491. }
  492. bool LightingRenderPass::load(const RenderContext* renderContext)
  493. {
  494. // Load tree shadow
  495. TextureLoader textureLoader;
  496. treeShadow = textureLoader.load("data/textures/tree-shadow-0.png");
  497. if (!treeShadow)
  498. {
  499. std::cerr << "Failed to load tree shadow" << std::endl;
  500. }
  501. // Load unskinned shader
  502. shaderLoader.undefine();
  503. shaderLoader.define("TEXTURE_COUNT", 0);
  504. shaderLoader.define("VERTEX_POSITION", EMERGENT_VERTEX_POSITION);
  505. shaderLoader.define("VERTEX_NORMAL", EMERGENT_VERTEX_NORMAL);
  506. shaderLoader.define("VERTEX_TEXCOORD", EMERGENT_VERTEX_TEXCOORD);
  507. unskinnedShader = shaderLoader.load("data/shaders/lit-object.glsl", &parameterSet);
  508. // Load skinned shader
  509. shaderLoader.define("SKINNED");
  510. shaderLoader.define("MAX_BONE_COUNT", maxBoneCount);
  511. shaderLoader.define("VERTEX_BONE_INDICES", EMERGENT_VERTEX_BONE_INDICES);
  512. shaderLoader.define("VERTEX_BONE_WEIGHTS", EMERGENT_VERTEX_BONE_WEIGHTS);
  513. skinnedShader = shaderLoader.load("data/shaders/lit-object.glsl", &parameterSet);
  514. if (!unskinnedShader || !skinnedShader)
  515. {
  516. return false;
  517. }
  518. time = 0.0f;
  519. return true;
  520. }
  521. void LightingRenderPass::unload()
  522. {
  523. delete unskinnedShader;
  524. delete skinnedShader;
  525. unskinnedShader = nullptr;
  526. skinnedShader = nullptr;
  527. for (auto it = shaderCache.begin(); it != shaderCache.end(); ++it)
  528. {
  529. delete it->second;
  530. }
  531. shaderCache.clear();
  532. delete treeShadow;
  533. treeShadow = nullptr;
  534. delete diffuseCubemap;
  535. diffuseCubemap = nullptr;
  536. delete specularCubemap;
  537. specularCubemap = nullptr;
  538. }
  539. void LightingRenderPass::render(RenderContext* renderContext)
  540. {
  541. /*
  542. time += 1.0f / 60.f;
  543. // Bind framebuffer and setup viewport
  544. glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
  545. glViewport(0, 0, renderTarget->width, renderTarget->height);
  546. // Clear the framebuffer depth
  547. //glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  548. //glClearDepth(1.0);
  549. //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  550. // Enable clipping
  551. if (renderContext->layer->getIndex() == 0)
  552. {
  553. // Clipping pass
  554. cappingRenderContext.camera = renderContext->camera;
  555. cappingRenderContext.layer = renderContext->layer;
  556. for (int i = 0; i < 5; ++i)
  557. {
  558. clippingRenderPass.setClippingPlane(clippingPlanes[i]);
  559. clippingRenderPass.render(renderContext);
  560. Transform transform = Transform::getIdentity();
  561. transform.translation = clippingPlanes[i].getNormal() * -clippingPlanes[i].getDistance();
  562. transform.scale = Vector3(150.0f);
  563. transform.rotation = glm::normalize(glm::rotation(Vector3(0, 0, -1), clippingPlanes[i].getNormal()));
  564. ModelInstance* cappingPlaneInstance = &cappingPlaneInstances[i];
  565. cappingPlaneInstance->setTransform(transform);
  566. cappingRenderQueue.clear();
  567. cappingRenderQueue.queue(cappingPlaneInstance);
  568. cappingRenderPass.render(&cappingRenderContext);
  569. }
  570. glEnable(GL_CLIP_DISTANCE0);
  571. }
  572. else
  573. {
  574. glDisable(GL_CLIP_DISTANCE0);
  575. }
  576. // Enable depth testing
  577. glEnable(GL_DEPTH_TEST);
  578. glDepthMask(GL_TRUE);
  579. glDepthFunc(GL_LEQUAL);
  580. // Enable backface culling
  581. glEnable(GL_CULL_FACE);
  582. glCullFace(GL_BACK);
  583. // Enable alpha blending
  584. glEnable(GL_BLEND);
  585. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  586. const Camera& camera = *(renderContext->camera);
  587. const std::list<RenderOperation>* operations = renderContext->queue->getOperations();
  588. // Calculate camera direction
  589. const Vector3& cameraDirection = camera.getForward();
  590. // Textures
  591. const std::size_t maxTextures = 8;
  592. int materialTexture[maxTextures];
  593. Vector2 texcoordOffset[maxTextures];
  594. Vector2 texcoordScale[maxTextures];
  595. float textureDiffuseInfluence[maxTextures];
  596. float textureSpecularInfluence[maxTextures];
  597. float textureEmissiveInfluence[maxTextures];
  598. float textureRoughnessInfluence[maxTextures];
  599. float textureOpacityInfluence[maxTextures];
  600. float textureNormalInfluence[maxTextures];
  601. for (std::size_t i = 0; i < maxTextures; ++i)
  602. {
  603. materialTexture[i] = i + 2;
  604. }
  605. // Lights
  606. // Point lights
  607. const std::size_t maxPointLightCount = 4;
  608. std::size_t pointLightCount = 0;
  609. Vector3 pointLightColor[maxPointLightCount];
  610. Vector3 pointLightPosition[maxPointLightCount];
  611. Vector3 pointLightAttenuation[maxPointLightCount];
  612. for (std::size_t i = 0; i < maxPointLightCount; ++i)
  613. pointLightColor[i] = Vector3(0.0f);
  614. // Directional lights
  615. const std::size_t maxDirectionalLightCount = 4;
  616. std::size_t directionalLightCount = 0;
  617. Vector3 directionalLightColor[maxDirectionalLightCount];
  618. Vector3 directionalLightDirection[maxDirectionalLightCount];
  619. for (std::size_t i = 0; i < maxDirectionalLightCount; ++i)
  620. directionalLightColor[i] = Vector3(0.0f);
  621. // Spotlights
  622. const std::size_t maxSpotlightCount = 4;
  623. std::size_t spotlightCount = 0;
  624. Vector3 spotlightColor[maxSpotlightCount];
  625. Vector3 spotlightPosition[maxSpotlightCount];
  626. Vector3 spotlightAttenuation[maxSpotlightCount];
  627. Vector3 spotlightDirection[maxSpotlightCount];
  628. float spotlightCutoff[maxSpotlightCount];
  629. float spotlightExponent[maxSpotlightCount];
  630. for (std::size_t i = 0; i < maxSpotlightCount; ++i)
  631. spotlightColor[i] = Vector3(0.0f);
  632. const std::list<SceneObject*>* lights = renderContext->layer->getObjects(SceneObjectType::LIGHT);
  633. if (lights != nullptr)
  634. {
  635. for (auto object: *lights)
  636. {
  637. const Light* light = static_cast<const Light*>(object);
  638. LightType lightType = light->getLightType();
  639. if (lightType == LightType::POINT)
  640. {
  641. const PointLight* pointLight = static_cast<const PointLight*>(light);
  642. pointLightColor[pointLightCount] = pointLight->getScaledColor();
  643. pointLightPosition[pointLightCount] = Vector3(camera.getView() * Vector4(pointLight->getTranslation(), 1.0f));
  644. pointLightAttenuation[pointLightCount] = pointLight->getAttenuation();
  645. ++pointLightCount;
  646. }
  647. else if (lightType == LightType::DIRECTIONAL)
  648. {
  649. const DirectionalLight* directionalLight = static_cast<const DirectionalLight*>(light);
  650. directionalLightColor[directionalLightCount] = directionalLight->getScaledColor();
  651. directionalLightDirection[directionalLightCount] = glm::normalize(Vector3(camera.getView() * Vector4(-directionalLight->getDirection(), 0.0f)));
  652. ++directionalLightCount;
  653. }
  654. else if (lightType == LightType::SPOTLIGHT)
  655. {
  656. const Spotlight* spotlight = static_cast<const Spotlight*>(light);
  657. spotlightColor[spotlightCount] = spotlight->getScaledColor();
  658. spotlightPosition[spotlightCount] = Vector3(camera.getView() * Vector4(spotlight->getTranslation(), 1.0f));
  659. spotlightAttenuation[spotlightCount] = spotlight->getAttenuation();
  660. spotlightDirection[spotlightCount] = glm::normalize(Vector3(camera.getView() * Vector4(-spotlight->getDirection(), 0.0f)));
  661. spotlightCutoff[spotlightCount] = spotlight->getCutoff();
  662. spotlightExponent[spotlightCount] = spotlight->getExponent();
  663. ++spotlightCount;
  664. }
  665. }
  666. }
  667. // Calculate the (light-space) view-projection-bias matrix
  668. Matrix4 viewProjectionBiasMatrix = biasMatrix * shadowCamera->getViewProjection();
  669. // Bind shader
  670. Shader* boundShader = nullptr;
  671. // Bind shadow map
  672. glActiveTexture(GL_TEXTURE0);
  673. glBindTexture(GL_TEXTURE_2D, shadowMap);
  674. // Bind tree shadow
  675. glActiveTexture(GL_TEXTURE1);
  676. glBindTexture(GL_TEXTURE_2D, treeShadow.getTextureID());
  677. // For each clipping plane
  678. for (int clippingPlaneIndex = 0; clippingPlaneIndex < 5; ++clippingPlaneIndex)
  679. {
  680. // Render operations
  681. for (const RenderOperation& operation: *operations)
  682. {
  683. const Material* material = operation.material;
  684. // Find shader
  685. std::size_t hashValue = material->getHashValue();
  686. auto it = shaderCache.find(hashValue);
  687. if (it == shaderCache.end())
  688. {
  689. std::cerr << "Warning: material requires unloaded shader" << std::endl;
  690. continue;
  691. }
  692. // Bind shader
  693. Shader* shader = it->second;
  694. if (shader != boundShader)
  695. {
  696. shader->bind();
  697. boundShader = shader;
  698. }
  699. // Get shader parameters
  700. ShaderParameterSet* parameters = shader->getParameters();
  701. const Matrix4& modelMatrix = operation.transform;
  702. Matrix4 modelViewMatrix = camera.getView() * modelMatrix;
  703. Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
  704. // Pass matrix parameters
  705. if (parameters->hasParameter(ShaderParameter::MODEL_MATRIX))
  706. {
  707. parameters->setValue(ShaderParameter::MODEL_MATRIX, modelMatrix);
  708. }
  709. if (parameters->hasParameter(ShaderParameter::MODEL_VIEW_MATRIX))
  710. {
  711. parameters->setValue(ShaderParameter::MODEL_VIEW_MATRIX, modelViewMatrix);
  712. }
  713. if (parameters->hasParameter(ShaderParameter::MODEL_VIEW_PROJECTION_MATRIX))
  714. {
  715. parameters->setValue(ShaderParameter::MODEL_VIEW_PROJECTION_MATRIX, modelViewProjectionMatrix);
  716. }
  717. if (parameters->hasParameter(ShaderParameter::NORMAL_MODEL_MATRIX))
  718. {
  719. Matrix3 normalModelMatrix = glm::transpose(glm::inverse(Matrix3(modelMatrix)));
  720. parameters->setValue(ShaderParameter::NORMAL_MODEL_MATRIX, normalModelMatrix);
  721. }
  722. if (parameters->hasParameter(ShaderParameter::NORMAL_MODEL_VIEW_MATRIX))
  723. {
  724. Matrix3 normalModelViewMatrix = glm::transpose(glm::inverse(Matrix3(modelViewMatrix)));
  725. parameters->setValue(ShaderParameter::NORMAL_MODEL_VIEW_MATRIX, normalModelViewMatrix);
  726. }
  727. if (parameters->hasParameter(ShaderParameter::CAMERA_DIRECTION))
  728. {
  729. parameters->setValue(ShaderParameter::CAMERA_DIRECTION, cameraDirection);
  730. }
  731. // Pass material parameters
  732. if (parameters->hasParameter(ShaderParameter::MATERIAL_DIFFUSE_COLOR))
  733. {
  734. parameters->setValue(ShaderParameter::MATERIAL_DIFFUSE_COLOR, material->getDiffuseColor());
  735. }
  736. if (parameters->hasParameter(ShaderParameter::MATERIAL_SPECULAR_COLOR))
  737. {
  738. parameters->setValue(ShaderParameter::MATERIAL_SPECULAR_COLOR, material->getSpecularColor());
  739. }
  740. if (parameters->hasParameter(ShaderParameter::MATERIAL_EMISSIVE_COLOR))
  741. {
  742. parameters->setValue(ShaderParameter::MATERIAL_EMISSIVE_COLOR, material->getEmissiveColor());
  743. }
  744. if (parameters->hasParameter(ShaderParameter::MATERIAL_ROUGHNESS))
  745. {
  746. parameters->setValue(ShaderParameter::MATERIAL_ROUGHNESS, material->getRoughness());
  747. }
  748. if (parameters->hasParameter(ShaderParameter::MATERIAL_OPACITY))
  749. {
  750. parameters->setValue(ShaderParameter::MATERIAL_OPACITY, material->getOpacity());
  751. }
  752. // Pass texture parameters
  753. if (parameters->hasParameter(ShaderParameter::MATERIAL_TEXTURE))
  754. {
  755. std::size_t textureCount = material->getTextureCount();
  756. for (std::size_t i = 0; i < textureCount; ++i)
  757. {
  758. const Texture* texture = material->getTexture(i);
  759. texcoordOffset[i] = Vector2(texture->getCoordinateOffset());
  760. texcoordScale[i] = Vector2(texture->getCoordinateScale());
  761. textureDiffuseInfluence[i] = texture->getDiffuseInfluence();
  762. textureSpecularInfluence[i] = texture->getSpecularInfluence();
  763. textureEmissiveInfluence[i] = texture->getEmissiveInfluence();
  764. textureRoughnessInfluence[i] = texture->getRoughnessInfluence();
  765. textureOpacityInfluence[i] = texture->getOpacityInfluence();
  766. textureNormalInfluence[i] = texture->getNormalInfluence();
  767. // Bind texture
  768. glActiveTexture(GL_TEXTURE2 + i);
  769. glBindTexture(GL_TEXTURE_2D, texture->getTextureID());
  770. }
  771. parameters->setValue(ShaderParameter::MATERIAL_TEXTURE, 0, &materialTexture[0], textureCount);
  772. if (parameters->hasParameter(ShaderParameter::TEXCOORD_OFFSET))
  773. parameters->setValue(ShaderParameter::TEXCOORD_OFFSET, 0, &texcoordOffset[0], textureCount);
  774. if (parameters->hasParameter(ShaderParameter::TEXCOORD_SCALE))
  775. parameters->setValue(ShaderParameter::TEXCOORD_SCALE, 0, &texcoordScale[0], textureCount);
  776. if (parameters->hasParameter(ShaderParameter::TEXTURE_DIFFUSE_INFLUENCE))
  777. parameters->setValue(ShaderParameter::TEXTURE_DIFFUSE_INFLUENCE, 0, &textureDiffuseInfluence[0], textureCount);
  778. if (parameters->hasParameter(ShaderParameter::TEXTURE_SPECULAR_INFLUENCE))
  779. parameters->setValue(ShaderParameter::TEXTURE_SPECULAR_INFLUENCE, 0, &textureSpecularInfluence[0], textureCount);
  780. if (parameters->hasParameter(ShaderParameter::TEXTURE_EMISSIVE_INFLUENCE))
  781. parameters->setValue(ShaderParameter::TEXTURE_EMISSIVE_INFLUENCE, 0, &textureEmissiveInfluence[0], textureCount);
  782. if (parameters->hasParameter(ShaderParameter::TEXTURE_ROUGHNESS_INFLUENCE))
  783. parameters->setValue(ShaderParameter::TEXTURE_ROUGHNESS_INFLUENCE, 0, &textureRoughnessInfluence[0], textureCount);
  784. if (parameters->hasParameter(ShaderParameter::TEXTURE_OPACITY_INFLUENCE))
  785. parameters->setValue(ShaderParameter::TEXTURE_OPACITY_INFLUENCE, 0, &textureOpacityInfluence[0], textureCount);
  786. if (parameters->hasParameter(ShaderParameter::TEXTURE_NORMAL_INFLUENCE))
  787. parameters->setValue(ShaderParameter::TEXTURE_NORMAL_INFLUENCE, 0, &textureNormalInfluence[0], textureCount);
  788. }
  789. // Pass lighting parameters
  790. if (parameters->hasParameter(ShaderParameter::POINT_LIGHT_COLOR))
  791. {
  792. parameters->setValue(ShaderParameter::POINT_LIGHT_COLOR, 0, &pointLightColor[0], spotlightCount);
  793. parameters->setValue(ShaderParameter::POINT_LIGHT_POSITION, 0, &pointLightPosition[0], spotlightCount);
  794. parameters->setValue(ShaderParameter::POINT_LIGHT_ATTENUATION, 0, &pointLightAttenuation[0], spotlightCount);
  795. }
  796. if (parameters->hasParameter(ShaderParameter::DIRECTIONAL_LIGHT_COLOR))
  797. {
  798. parameters->setValue(ShaderParameter::DIRECTIONAL_LIGHT_COLOR, 0, &directionalLightColor[0], directionalLightCount);
  799. parameters->setValue(ShaderParameter::DIRECTIONAL_LIGHT_DIRECTION, 0, &directionalLightDirection[0], directionalLightCount);
  800. }
  801. if (parameters->hasParameter(ShaderParameter::SPOTLIGHT_COLOR))
  802. {
  803. parameters->setValue(ShaderParameter::SPOTLIGHT_COLOR, 0, &spotlightColor[0], spotlightCount);
  804. parameters->setValue(ShaderParameter::SPOTLIGHT_POSITION, 0, &spotlightPosition[0], spotlightCount);
  805. parameters->setValue(ShaderParameter::SPOTLIGHT_ATTENUATION, 0, &spotlightAttenuation[0], spotlightCount);
  806. parameters->setValue(ShaderParameter::SPOTLIGHT_DIRECTION, 0, &spotlightDirection[0], spotlightCount);
  807. parameters->setValue(ShaderParameter::SPOTLIGHT_CUTOFF, 0, &spotlightCutoff[0], spotlightCount);
  808. parameters->setValue(ShaderParameter::SPOTLIGHT_EXPONENT, 0, &spotlightExponent[0], spotlightCount);
  809. }
  810. if (parameters->hasParameter(ShaderParameter::DIFFUSE_ENVIRONMENT_MAP))
  811. {
  812. parameters->setValue(ShaderParameter::DIFFUSE_ENVIRONMENT_MAP, 1);
  813. }
  814. if (parameters->hasParameter(ShaderParameter::SPECULAR_ENVIRONMENT_MAP))
  815. {
  816. parameters->setValue(ShaderParameter::SPECULAR_ENVIRONMENT_MAP, 2);
  817. }
  818. // Pass shadow parameters
  819. if (parameters->hasParameter(ShaderParameter::MODEL_VIEW_PROJECTION_BIAS_MATRIX))
  820. {
  821. Matrix4 modelViewProjectionBiasMatrix = viewProjectionBiasMatrix * modelMatrix;
  822. parameters->setValue(ShaderParameter::MODEL_VIEW_PROJECTION_BIAS_MATRIX, modelViewProjectionBiasMatrix);
  823. }
  824. if (parameters->hasParameter(ShaderParameter::SHADOW_MAP))
  825. {
  826. parameters->setValue(ShaderParameter::SHADOW_MAP, 0);
  827. }
  828. if (parameters->hasParameter(ShaderParameter::TREE_SHADOW))
  829. {
  830. parameters->setValue(ShaderParameter::TREE_SHADOW, 1);
  831. }
  832. if (parameters->hasParameter(ShaderParameter::TIME))
  833. {
  834. parameters->setValue(ShaderParameter::TIME, time);
  835. }
  836. // Pass clipping parameters
  837. if (parameters->hasParameter(ShaderParameter::CLIPPING_PLANES))
  838. {
  839. const Plane& clippingPlane = clippingPlanes[clippingPlaneIndex];
  840. parameters->setValue(ShaderParameter::CLIPPING_PLANES, Vector4(clippingPlane.getNormal(), clippingPlane.getDistance()));
  841. }
  842. // Draw geometry
  843. glBindVertexArray(operation.vao);
  844. if (!material->isOpaque())
  845. {
  846. //glBlendFunc(GL_ZERO, GL_SRC_COLOR);
  847. //glBlendFunc(GL_ONE, GL_ONE);
  848. //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  849. //glBlendFunc(GL_ZERO, GL_SRC_COLOR);
  850. //glDepthMask(GL_FALSE);
  851. glFrontFace(GL_CW);
  852. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  853. parameters->setValue(ShaderParameter::MATERIAL_DIFFUSE_COLOR, material->getDiffuseColor() * 0.05f);
  854. glFrontFace(GL_CCW);
  855. //glDepthMask(GL_TRUE);
  856. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  857. //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  858. }
  859. else
  860. {
  861. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  862. }
  863. }
  864. }
  865. // Disable clipping
  866. glDisable(GL_CLIP_DISTANCE0);
  867. */
  868. const Camera& camera = *(renderContext->camera);
  869. std::list<RenderOperation>* operations = renderContext->queue->getOperations();
  870. // Bind framebuffer and setup viewport
  871. glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
  872. glViewport(0, 0, renderTarget->width, renderTarget->height);
  873. // Enable depth testing
  874. glEnable(GL_DEPTH_TEST);
  875. glDepthMask(GL_TRUE);
  876. glDepthFunc(GL_LEQUAL);
  877. // Enable backface culling
  878. glEnable(GL_CULL_FACE);
  879. glCullFace(GL_BACK);
  880. // Enable alpha blending
  881. glEnable(GL_BLEND);
  882. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  883. int directionalLightCount = 1;
  884. Vector3 directionalLightColors[3];
  885. Vector3 directionalLightDirections[3];
  886. directionalLightColors[0] = Vector3(1);
  887. directionalLightDirections[0] = glm::normalize(Vector3(camera.getView() * -Vector4(0, -2, -1, 0)));
  888. // Calculate the (light-space) view-projection matrix
  889. Matrix4 lightViewProjectionMatrix = shadowMapPass->getTileMatrix(0) * biasMatrix * shadowMapPass->getCropMatrix(0) * shadowCamera->getViewProjection();
  890. //Matrix4 lightViewProjectionMatrix = biasMatrix * shadowCamera->getViewProjection();
  891. glActiveTexture(GL_TEXTURE3);
  892. glBindTexture(GL_TEXTURE_CUBE_MAP, diffuseCubemap->getTextureID());
  893. glActiveTexture(GL_TEXTURE4);
  894. glBindTexture(GL_TEXTURE_CUBE_MAP, specularCubemap->getTextureID());
  895. glActiveTexture(GL_TEXTURE5);
  896. glBindTexture(GL_TEXTURE_2D, shadowMap);
  897. Shader* shader = nullptr;
  898. Texture* albedoOpacityMap = nullptr;
  899. Texture* metalnessRoughnessMap = nullptr;
  900. Texture* normalOcclusionMap = nullptr;
  901. // Sort operations
  902. operations->sort(RenderOpCompare());
  903. // Render operations
  904. for (const RenderOperation& operation: *operations)
  905. {
  906. // Skip render operations with unsupported materials
  907. if (operation.material->getMaterialFormatID() != static_cast<unsigned int>(MaterialFormat::PHYSICAL))
  908. {
  909. continue;
  910. }
  911. const PhysicalMaterial* material = static_cast<const PhysicalMaterial*>(operation.material);
  912. if (!(material->flags & (unsigned int)PhysicalMaterial::Flags::OBJECT))
  913. {
  914. continue;
  915. }
  916. // Skip render operations with unsupported vertex formats
  917. // Select shader
  918. Shader* targetShader = nullptr;
  919. if (operation.pose != nullptr)
  920. {
  921. targetShader = skinnedShader;
  922. }
  923. else
  924. {
  925. targetShader = unskinnedShader;
  926. }
  927. // Switch shader if necessary
  928. if (shader != targetShader)
  929. {
  930. shader = targetShader;
  931. // Bind shader
  932. shader->bind();
  933. // Pass static params
  934. shader->setParameter(lightViewProjectionParam, lightViewProjectionMatrix);
  935. shader->setParameter(albedoOpacityMapParam, 0);
  936. shader->setParameter(metalnessRoughnessMapParam, 1);
  937. shader->setParameter(normalOcclusionMapParam, 2);
  938. shader->setParameter(diffuseCubemapParam, 3);
  939. shader->setParameter(specularCubemapParam, 4);
  940. shader->setParameter(shadowMapParam, 5);
  941. shader->setParameter(directionalLightCountParam, directionalLightCount);
  942. shader->setParameter(directionalLightColorsParam, 0, &directionalLightColors[0], directionalLightCount);
  943. shader->setParameter(directionalLightDirectionsParam, 0, &directionalLightDirections[0], directionalLightCount);
  944. shader->setParameter(cameraPositionParam, camera.getTranslation());
  945. }
  946. // Pass matrix palette
  947. if (operation.pose != nullptr)
  948. {
  949. shader->setParameter(matrixPaletteParam, 0, operation.pose->getMatrixPalette(), operation.pose->getSkeleton()->getBoneCount());
  950. }
  951. // Bind albedo-opacity map
  952. if (material->albedoOpacityMap != albedoOpacityMap)
  953. {
  954. albedoOpacityMap = material->albedoOpacityMap;
  955. if (albedoOpacityMap != nullptr)
  956. {
  957. glActiveTexture(GL_TEXTURE0);
  958. glBindTexture(GL_TEXTURE_2D, albedoOpacityMap->getTextureID());
  959. }
  960. }
  961. // Bind metalness-roughness map
  962. if (material->metalnessRoughnessMap != metalnessRoughnessMap)
  963. {
  964. metalnessRoughnessMap = material->metalnessRoughnessMap;
  965. if (metalnessRoughnessMap != nullptr)
  966. {
  967. glActiveTexture(GL_TEXTURE1);
  968. glBindTexture(GL_TEXTURE_2D, metalnessRoughnessMap->getTextureID());
  969. }
  970. }
  971. // Bind normal-occlusion map
  972. if (material->normalOcclusionMap != normalOcclusionMap)
  973. {
  974. normalOcclusionMap = material->normalOcclusionMap;
  975. if (normalOcclusionMap != nullptr)
  976. {
  977. glActiveTexture(GL_TEXTURE2);
  978. glBindTexture(GL_TEXTURE_2D, normalOcclusionMap->getTextureID());
  979. }
  980. }
  981. const Matrix4& modelMatrix = operation.transform;
  982. Matrix4 modelViewMatrix = camera.getView() * modelMatrix;
  983. Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
  984. Matrix3 normalModelViewMatrix = glm::transpose(glm::inverse(Matrix3(modelViewMatrix)));
  985. Matrix3 normalModelMatrix = glm::transpose(glm::inverse(Matrix3(modelMatrix)));
  986. shader->setParameter(modelParam, modelMatrix);
  987. shader->setParameter(modelViewParam, modelViewMatrix);
  988. shader->setParameter(modelViewProjectionParam, modelViewProjectionMatrix);
  989. shader->setParameter(normalModelViewParam, normalModelViewMatrix);
  990. shader->setParameter(normalModelParam, normalModelMatrix);
  991. glBindVertexArray(operation.vao);
  992. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  993. }
  994. glActiveTexture(GL_TEXTURE5);
  995. glBindTexture(GL_TEXTURE_2D, 0);
  996. }
  997. bool LightingRenderPass::loadShader(const RenderOperation& operation)
  998. {
  999. /*
  1000. const std::string shaderFilename = "data/shaders/main.glsl";
  1001. // Get material and its hash value
  1002. const Material* material = operation.material;
  1003. std::size_t hashValue = material->getHashValue();
  1004. // Check if shader has already been loaded
  1005. auto it = shaderCache.find(hashValue);
  1006. if (it != shaderCache.end())
  1007. return true;
  1008. // Define shader preprocessor macros
  1009. // Undefine previous definitions
  1010. shaderLoader.undefine();
  1011. // Clipping
  1012. shaderLoader.define("CLIPPING_PLANE_COUNT", 1);
  1013. // Vertex format
  1014. shaderLoader.define("VERTEX_POSITION", EMERGENT_VERTEX_POSITION);
  1015. shaderLoader.define("VERTEX_NORMAL", EMERGENT_VERTEX_NORMAL);
  1016. //shaderLoader.define("VERTEX_COLOR", EMERGENT_VERTEX_COLOR);
  1017. // Lighting
  1018. // Material
  1019. if (material->isShadeless())
  1020. {
  1021. shaderLoader.define("SHADELESS");
  1022. }
  1023. else
  1024. {
  1025. // Lighting
  1026. //shaderLoader.define("POINT_LIGHT_COUNT", 1);
  1027. shaderLoader.define("DIRECTIONAL_LIGHT_COUNT", 2);
  1028. //shaderLoader.define("SPOTLIGHT_COUNT", 2);
  1029. //shaderLoader.define("ENVIRONMENT_MAP");
  1030. }
  1031. if (material->isShadowReceiver())
  1032. shaderLoader.define("SHADOWED");
  1033. // Final
  1034. shaderLoader.define("GAMMA_CORRECT");
  1035. // Load shader
  1036. Shader* shader = shaderLoader.load(shaderFilename);
  1037. if (!shader)
  1038. {
  1039. std::cerr << "Failed to load shader \"" << shaderFilename << "\"" << std::endl;
  1040. return false;
  1041. }
  1042. // Store shader in cache
  1043. shaderCache[hashValue] = shader;
  1044. return true;
  1045. */
  1046. return false;
  1047. }
  1048. bool LightingRenderPass::RenderOpCompare::operator()(const RenderOperation& opA, const RenderOperation& opB) const
  1049. {
  1050. // Skip render operations with unsupported materials
  1051. if (opA.material->getMaterialFormatID() != static_cast<unsigned int>(MaterialFormat::PHYSICAL))
  1052. {
  1053. return false;
  1054. }
  1055. else if (opB.material->getMaterialFormatID() != static_cast<unsigned int>(MaterialFormat::PHYSICAL))
  1056. {
  1057. return true;
  1058. }
  1059. // Cast materials
  1060. const PhysicalMaterial* materialA = static_cast<const PhysicalMaterial*>(opA.material);
  1061. const PhysicalMaterial* materialB = static_cast<const PhysicalMaterial*>(opB.material);
  1062. // Determine transparency
  1063. bool transparentA = materialA->flags & (unsigned int)PhysicalMaterial::Flags::TRANSLUCENT;
  1064. bool transparentB = materialB->flags & (unsigned int)PhysicalMaterial::Flags::TRANSLUCENT;
  1065. if (transparentA)
  1066. {
  1067. if (transparentB)
  1068. {
  1069. // A and B are both transparent, sort by depth
  1070. return (opA.depth <= opB.depth);
  1071. }
  1072. else
  1073. {
  1074. // A is transparent, B is opaque. Render B first
  1075. return false;
  1076. }
  1077. }
  1078. else
  1079. {
  1080. if (transparentB)
  1081. {
  1082. // A is opaque, B is transparent. Render A first
  1083. return true;
  1084. }
  1085. else
  1086. {
  1087. // A and B are both opaque, sort by material
  1088. return (opA.material < opB.material);
  1089. }
  1090. }
  1091. }
  1092. DebugRenderPass::DebugRenderPass()
  1093. {
  1094. modelViewProjectionParam = parameterSet.addParameter("modelViewProjectionMatrix", ShaderParameter::Type::MATRIX_4, 1);
  1095. }
  1096. bool DebugRenderPass::load(const RenderContext* renderContext)
  1097. {
  1098. unlitSolidShader = shaderLoader.load("data/shaders/unlit-solid.glsl", &parameterSet);
  1099. if (!unlitSolidShader)
  1100. {
  1101. return false;
  1102. }
  1103. const float aabbVertexData[] =
  1104. {
  1105. -0.5, -0.5, -0.5,
  1106. 0.5, -0.5, -0.5,
  1107. 0.5, 0.5, -0.5,
  1108. -0.5, 0.5, -0.5,
  1109. -0.5, -0.5, 0.5,
  1110. 0.5, -0.5, 0.5,
  1111. 0.5, 0.5, 0.5,
  1112. -0.5, 0.5, 0.5,
  1113. };
  1114. const std::uint32_t aabbIndexData[] =
  1115. {
  1116. 0, 1, 1, 2, 2, 3, 3, 0,
  1117. 4, 5, 5, 6, 6, 7, 7, 4,
  1118. 0, 4, 1, 5, 2, 6, 3, 7
  1119. };
  1120. aabbVertexCount = 8;
  1121. aabbIndexCount = 24;
  1122. // Create AABB geometry
  1123. glGenVertexArrays(1, &aabbVAO);
  1124. glBindVertexArray(aabbVAO);
  1125. glGenBuffers(1, &aabbVBO);
  1126. glBindBuffer(GL_ARRAY_BUFFER, aabbVBO);
  1127. glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * aabbVertexCount, aabbVertexData, GL_STATIC_DRAW);
  1128. glEnableVertexAttribArray(EMERGENT_VERTEX_POSITION);
  1129. glVertexAttribPointer(EMERGENT_VERTEX_POSITION, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (char*)0 + 0*sizeof(float));
  1130. glGenBuffers(1, &aabbIBO);
  1131. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, aabbIBO);
  1132. glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(std::uint32_t) * aabbIndexCount, aabbIndexData, GL_STATIC_DRAW);
  1133. return true;
  1134. }
  1135. void DebugRenderPass::unload()
  1136. {
  1137. delete unlitSolidShader;
  1138. unlitSolidShader = nullptr;
  1139. glDeleteBuffers(1, &aabbIBO);
  1140. glDeleteBuffers(1, &aabbVBO);
  1141. glDeleteVertexArrays(1, &aabbVAO);
  1142. }
  1143. void DebugRenderPass::render(RenderContext* renderContext)
  1144. {
  1145. // Bind framebuffer and setup viewport
  1146. glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
  1147. glViewport(0, 0, renderTarget->width, renderTarget->height);
  1148. const Camera& camera = *(renderContext->camera);
  1149. /*
  1150. // Bind framebuffer and setup viewport
  1151. glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
  1152. glViewport(0, 0, renderTarget->width, renderTarget->height);
  1153. // Clear the framebuffer depth
  1154. glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  1155. glClearDepth(1.0);
  1156. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  1157. // Disable depth testing
  1158. glEnable(GL_DEPTH_TEST);
  1159. glDepthMask(GL_TRUE);
  1160. glDepthFunc(GL_LESS);
  1161. */
  1162. // Disable backface culling
  1163. glDisable(GL_CULL_FACE);
  1164. // Disable alpha blending
  1165. glDisable(GL_BLEND);
  1166. // Bind unlit solid shader
  1167. unlitSolidShader->bind();
  1168. // Bind AABB geometry
  1169. glBindVertexArray(aabbVAO);
  1170. const std::list<SceneObject*>* objects = renderContext->layer->getObjects();
  1171. for (auto object: *objects)
  1172. {
  1173. if (!camera.getCullingMask()->intersects(object->getBounds()))
  1174. continue;
  1175. const AABB& bounds = object->getBounds();
  1176. const Vector3& min = bounds.getMin();
  1177. const Vector3& max = bounds.getMax();
  1178. Vector3 scale = max - min;
  1179. Vector3 center = (min + max) * 0.5f;
  1180. const Vector3& translation = center;
  1181. Matrix4 modelMatrix = glm::translate(translation) * glm::scale(scale);
  1182. Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
  1183. unlitSolidShader->setParameter(modelViewProjectionParam, modelViewProjectionMatrix);
  1184. glDrawElements(GL_LINES, aabbIndexCount, GL_UNSIGNED_INT, (void*)0);
  1185. }
  1186. }
  1187. UIRenderPass::UIRenderPass()
  1188. {
  1189. modelViewProjectionParam = parameterSet.addParameter("modelViewProjectionMatrix", ShaderParameter::Type::MATRIX_4, 1);
  1190. textureParam = parameterSet.addParameter("tex", ShaderParameter::Type::INT, 1);
  1191. texcoordOffsetParam = parameterSet.addParameter("texcoordOffset", ShaderParameter::Type::VECTOR_2, 1);
  1192. texcoordScaleParam = parameterSet.addParameter("texcoordScale", ShaderParameter::Type::VECTOR_2, 1);
  1193. }
  1194. bool UIRenderPass::load(const RenderContext* renderContext)
  1195. {
  1196. shaderLoader.define("VERTEX_POSITION", EMERGENT_VERTEX_POSITION);
  1197. shaderLoader.define("VERTEX_TEXCOORD", EMERGENT_VERTEX_TEXCOORD);
  1198. shaderLoader.define("VERTEX_COLOR", EMERGENT_VERTEX_COLOR);
  1199. shaderLoader.define("GAMMA_CORRECT");
  1200. shaderLoader.define("TEXTURE_COUNT", 1);
  1201. texturedUIShader = shaderLoader.load("data/shaders/ui.glsl", &parameterSet);
  1202. shaderLoader.undefine();
  1203. shaderLoader.define("VERTEX_POSITION", EMERGENT_VERTEX_POSITION);
  1204. shaderLoader.define("VERTEX_COLOR", EMERGENT_VERTEX_COLOR);
  1205. shaderLoader.define("GAMMA_CORRECT");
  1206. untexturedUIShader = shaderLoader.load("data/shaders/ui.glsl", &parameterSet);
  1207. if (!texturedUIShader || !untexturedUIShader)
  1208. {
  1209. return false;
  1210. }
  1211. return true;
  1212. }
  1213. void UIRenderPass::unload()
  1214. {
  1215. delete texturedUIShader;
  1216. delete untexturedUIShader;
  1217. texturedUIShader = nullptr;
  1218. untexturedUIShader = nullptr;
  1219. }
  1220. void UIRenderPass::render(RenderContext* renderContext)
  1221. {
  1222. const Camera& camera = *(renderContext->camera);
  1223. // Bind framebuffer and setup viewport
  1224. glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
  1225. glViewport(0, 0, renderTarget->width, renderTarget->height);
  1226. // Disable depth testing
  1227. glDisable(GL_DEPTH_TEST);
  1228. //glDepthMask(GL_FALSE);
  1229. //glDepthFunc(GL_LESS);
  1230. // Disable backface culling
  1231. glEnable(GL_CULL_FACE);
  1232. glCullFace(GL_BACK);
  1233. // Enable alpha blending
  1234. glEnable(GL_BLEND);
  1235. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1236. glActiveTexture(GL_TEXTURE0);
  1237. Shader* shader = nullptr;
  1238. // Render operations
  1239. const std::list<RenderOperation>* operations = renderContext->queue->getOperations();
  1240. for (const RenderOperation& operation: *operations)
  1241. {
  1242. // Skip render operations with unsupported materials
  1243. if (operation.material->getMaterialFormatID() != static_cast<unsigned int>(MaterialFormat::UI))
  1244. {
  1245. continue;
  1246. }
  1247. const UIMaterial* material = static_cast<const UIMaterial*>(operation.material);
  1248. if (material->texture != nullptr)
  1249. {
  1250. shader = texturedUIShader;
  1251. shader->bind();
  1252. shader->setParameter(textureParam, 0);
  1253. shader->setParameter(texcoordOffsetParam, Vector2(0.0f));
  1254. shader->setParameter(texcoordScaleParam, Vector2(1.0f));
  1255. glBindTexture(GL_TEXTURE_2D, material->texture->getTextureID());
  1256. }
  1257. else
  1258. {
  1259. shader = untexturedUIShader;
  1260. shader->bind();
  1261. }
  1262. const Matrix4& modelMatrix = operation.transform;
  1263. Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
  1264. // Pass matrix parameters
  1265. shader->setParameter(modelViewProjectionParam, modelViewProjectionMatrix);
  1266. // Draw geometry
  1267. glBindVertexArray(operation.vao);
  1268. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  1269. }
  1270. }
  1271. VignetteRenderPass::VignetteRenderPass():
  1272. shader(nullptr)
  1273. {
  1274. bayerTextureParam = parameterSet.addParameter("bayerTexture", ShaderParameter::Type::INT, 1);
  1275. modelViewProjectionParam = parameterSet.addParameter("modelViewProjectionMatrix", ShaderParameter::Type::MATRIX_4, 1);
  1276. }
  1277. bool VignetteRenderPass::load(const RenderContext* renderContext)
  1278. {
  1279. shaderLoader.undefine();
  1280. shaderLoader.define("VERTEX_POSITION", EMERGENT_VERTEX_POSITION);
  1281. shaderLoader.define("VERTEX_COLOR", EMERGENT_VERTEX_COLOR);
  1282. shaderLoader.define("TEXTURE_COUNT", 1);
  1283. shader = shaderLoader.load("data/shaders/vignette.glsl", &parameterSet);
  1284. if (!shader)
  1285. {
  1286. return false;
  1287. }
  1288. /// @see http://www.anisopteragames.com/how-to-fix-color-banding-with-dithering/
  1289. static const char pattern[] =
  1290. {
  1291. 0, 32, 8, 40, 2, 34, 10, 42,
  1292. 48, 16, 56, 24, 50, 18, 58, 26,
  1293. 12, 44, 4, 36, 14, 46, 6, 38,
  1294. 60, 28, 52, 20, 62, 30, 54, 22,
  1295. 3, 35, 11, 43, 1, 33, 9, 41,
  1296. 51, 19, 59, 27, 49, 17, 57, 25,
  1297. 15, 47, 7, 39, 13, 45, 5, 37,
  1298. 63, 31, 55, 23, 61, 29, 53, 21
  1299. };
  1300. glGenTextures(1, &bayerTextureID);
  1301. glBindTexture(GL_TEXTURE_2D, bayerTextureID);
  1302. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  1303. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  1304. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  1305. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  1306. glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 8, 8, 0, GL_RED, GL_UNSIGNED_BYTE, pattern);
  1307. return true;
  1308. }
  1309. void VignetteRenderPass::unload()
  1310. {
  1311. delete shader;
  1312. shader = nullptr;
  1313. glDeleteTextures(1, &bayerTextureID);
  1314. }
  1315. void VignetteRenderPass::render(RenderContext* renderContext)
  1316. {
  1317. glDisable(GL_DEPTH_TEST);
  1318. glDepthMask(GL_FALSE);
  1319. // Bind shader
  1320. shader->bind();
  1321. // Bind texture
  1322. glActiveTexture(GL_TEXTURE0);
  1323. glBindTexture(GL_TEXTURE_2D, bayerTextureID);
  1324. // Pass texture unit to shader
  1325. shader->setParameter(bayerTextureParam, 0);
  1326. const Camera& camera = *(renderContext->camera);
  1327. const std::list<RenderOperation>* operations = renderContext->queue->getOperations();
  1328. // Render operations
  1329. for (const RenderOperation& operation: *operations)
  1330. {
  1331. const Material* material = operation.material;
  1332. const Matrix4& modelMatrix = operation.transform;
  1333. Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
  1334. shader->setParameter(modelViewProjectionParam, modelViewProjectionMatrix);
  1335. glBindVertexArray(operation.vao);
  1336. glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
  1337. }
  1338. }
  1339. SkyboxRenderPass::SkyboxRenderPass():
  1340. shader(nullptr),
  1341. cubemap(nullptr)
  1342. {
  1343. matrixParam = parameterSet.addParameter("matrix", ShaderParameter::Type::MATRIX_4, 1);
  1344. cubemapParam = parameterSet.addParameter("cubemap", ShaderParameter::Type::INT, 1);
  1345. }
  1346. bool SkyboxRenderPass::load(const RenderContext* renderContext)
  1347. {
  1348. shaderLoader.undefine();
  1349. shaderLoader.define("VERTEX_POSITION", EMERGENT_VERTEX_POSITION);
  1350. shader = shaderLoader.load("data/shaders/skybox.glsl", &parameterSet);
  1351. if (!shader)
  1352. {
  1353. return false;
  1354. }
  1355. const float quadVertexData[] =
  1356. {
  1357. -1.0f, 1.0f, 0.0f,
  1358. -1.0f, -1.0f, 0.0f,
  1359. 1.0f, -1.0f, 0.0f,
  1360. 1.0f, 1.0f, 0.0f
  1361. };
  1362. const std::uint32_t quadIndexData[] =
  1363. {
  1364. 0, 1, 3,
  1365. 3, 1, 2
  1366. };
  1367. quadVertexCount = 4;
  1368. quadIndexCount = 6;
  1369. // Create AABB geometry
  1370. glGenVertexArrays(1, &quadVAO);
  1371. glBindVertexArray(quadVAO);
  1372. glGenBuffers(1, &quadVBO);
  1373. glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
  1374. glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * quadVertexCount, quadVertexData, GL_STATIC_DRAW);
  1375. glEnableVertexAttribArray(EMERGENT_VERTEX_POSITION);
  1376. glVertexAttribPointer(EMERGENT_VERTEX_POSITION, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (char*)0 + 0*sizeof(float));
  1377. glGenBuffers(1, &quadIBO);
  1378. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadIBO);
  1379. glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(std::uint32_t) * quadIndexCount, quadIndexData, GL_STATIC_DRAW);
  1380. return true;
  1381. }
  1382. void SkyboxRenderPass::unload()
  1383. {
  1384. delete shader;
  1385. shader = nullptr;
  1386. glDeleteBuffers(1, &quadIBO);
  1387. glDeleteBuffers(1, &quadVBO);
  1388. glDeleteVertexArrays(1, &quadVAO);
  1389. }
  1390. void SkyboxRenderPass::render(RenderContext* renderContext)
  1391. {
  1392. if (!cubemap)
  1393. {
  1394. return;
  1395. }
  1396. glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
  1397. glViewport(0, 0, renderTarget->width, renderTarget->height);
  1398. glDisable(GL_DEPTH_TEST);
  1399. glDepthMask(GL_FALSE);
  1400. //glDisable(GL_CULL_FACE);
  1401. //glCullFace(GL_BACK);
  1402. // Bind shader
  1403. shader->bind();
  1404. // Bind cubemap texture
  1405. glActiveTexture(GL_TEXTURE0);
  1406. glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap->getTextureID());
  1407. // Pass texture unit to shader
  1408. shader->setParameter(cubemapParam, 0);
  1409. // Calculate matrix
  1410. const Camera& camera = *(renderContext->camera);
  1411. Matrix4 modelView = Matrix4(Matrix3(camera.getView()));
  1412. Matrix4 matrix = glm::inverse(modelView) * glm::inverse(camera.getProjection());
  1413. // Pass matrix to shader
  1414. shader->setParameter(matrixParam, matrix);
  1415. // Render quad
  1416. glBindVertexArray(quadVAO);
  1417. glDrawElementsBaseVertex(GL_TRIANGLES, quadIndexCount, GL_UNSIGNED_INT, (void*)0, 0);
  1418. }