Shadow maps now use instanced rendering
This commit is contained in:
		
							parent
							
								
									be06ee2d20
								
							
						
					
					
						commit
						231ac792d7
					
				@ -317,7 +317,6 @@ namespace nf {
 | 
				
			|||||||
				if (m_stateChange)
 | 
									if (m_stateChange)
 | 
				
			||||||
					doStateChange();
 | 
										doStateChange();
 | 
				
			||||||
				startOfLastFrame = std::chrono::steady_clock::now();
 | 
									startOfLastFrame = std::chrono::steady_clock::now();
 | 
				
			||||||
				//Should the physics update before user code?
 | 
					 | 
				
			||||||
				m_physics->update(m_deltaTime);
 | 
									m_physics->update(m_deltaTime);
 | 
				
			||||||
				m_currentState->update(m_deltaTime);
 | 
									m_currentState->update(m_deltaTime);
 | 
				
			||||||
				m_currentState->render(*m_renderer);
 | 
									m_currentState->render(*m_renderer);
 | 
				
			||||||
 | 
				
			|||||||
@ -59,7 +59,7 @@ namespace nf {
 | 
				
			|||||||
				modelsRemaining -= modelCount;
 | 
									modelsRemaining -= modelCount;
 | 
				
			||||||
				for (unsigned int i = 0; i < modelCount; i++) {
 | 
									for (unsigned int i = 0; i < modelCount; i++) {
 | 
				
			||||||
					pos = std::to_string(i) + "]";
 | 
										pos = std::to_string(i) + "]";
 | 
				
			||||||
					shader->setUniform(m_modelString + pos, mats[i]);
 | 
										shader->setUniform("model[" + pos, mats[i]);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				curr.first->render(shader, false, (unsigned int)modelCount);
 | 
									curr.first->render(shader, false, (unsigned int)modelCount);
 | 
				
			||||||
				mats.erase(mats.begin(), mats.begin() + modelCount);
 | 
									mats.erase(mats.begin(), mats.begin() + modelCount);
 | 
				
			||||||
 | 
				
			|||||||
@ -10,6 +10,7 @@
 | 
				
			|||||||
#include "Shader.h"
 | 
					#include "Shader.h"
 | 
				
			||||||
#include "Light.h"
 | 
					#include "Light.h"
 | 
				
			||||||
#include "Entity.h"
 | 
					#include "Entity.h"
 | 
				
			||||||
 | 
					#include "Model.h"
 | 
				
			||||||
#include "Cubemap.h"
 | 
					#include "Cubemap.h"
 | 
				
			||||||
#include "UIElement.h"
 | 
					#include "UIElement.h"
 | 
				
			||||||
#include "Button.h"
 | 
					#include "Button.h"
 | 
				
			||||||
@ -289,87 +290,6 @@ namespace nf {
 | 
				
			|||||||
		SwapBuffers(m_hdc);
 | 
							SwapBuffers(m_hdc);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void Renderer::renderShadowMaps(size_t count) {
 | 
					 | 
				
			||||||
		float nearP = 0.1f, farP = 400.0f;
 | 
					 | 
				
			||||||
		glm::mat4 directionalLightProj = glm::ortho(-50.0f, 50.0f, -50.0f, 50.0f, nearP, farP);
 | 
					 | 
				
			||||||
		glm::mat4 pointLightProj = glm::perspective(glm::radians(90.0f), 1.0f, nearP, farP);
 | 
					 | 
				
			||||||
		glm::mat4 lightView;
 | 
					 | 
				
			||||||
		glm::mat4 lightSpaceMat;
 | 
					 | 
				
			||||||
		bool directionalRendered = false;
 | 
					 | 
				
			||||||
		unsigned int directionalSlot = 0; //TODO: Test this
 | 
					 | 
				
			||||||
		glBindFramebuffer(GL_FRAMEBUFFER, m_shadowMapFBO);
 | 
					 | 
				
			||||||
		for (unsigned int i = 0; i < count; i++) {
 | 
					 | 
				
			||||||
			Light::Type type = m_lights[i]->getType();
 | 
					 | 
				
			||||||
			unsigned int tex = type == Light::Type::DIRECTIONAL ? m_directionalShadowMap : m_pointShadowMaps[i];
 | 
					 | 
				
			||||||
			switch (type) {
 | 
					 | 
				
			||||||
				case Light::Type::DIRECTIONAL: {
 | 
					 | 
				
			||||||
					std::string stringPos;
 | 
					 | 
				
			||||||
					glViewport(0, 0, m_directionalDepthTexSize, m_directionalDepthTexSize);
 | 
					 | 
				
			||||||
					glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
 | 
					 | 
				
			||||||
					glDrawBuffer(GL_NONE);
 | 
					 | 
				
			||||||
					glReadBuffer(GL_NONE);
 | 
					 | 
				
			||||||
					glClear(GL_DEPTH_BUFFER_BIT);
 | 
					 | 
				
			||||||
					Vec3 posTemp = m_lights[i]->getPosition();
 | 
					 | 
				
			||||||
					glm::vec3 lightPos(posTemp.x, posTemp.y, posTemp.z);
 | 
					 | 
				
			||||||
					lightView = glm::lookAt(lightPos, glm::vec3(0.0), glm::vec3(0.0, 1.0, 0.0));
 | 
					 | 
				
			||||||
					lightSpaceMat = directionalLightProj * lightView;
 | 
					 | 
				
			||||||
					m_directionalShadowShader->setUniform("lightSpace", lightSpaceMat);
 | 
					 | 
				
			||||||
					stringPos = "lightSpaceMat[";
 | 
					 | 
				
			||||||
					stringPos += std::to_string(i);
 | 
					 | 
				
			||||||
					stringPos += "]";
 | 
					 | 
				
			||||||
					m_lightingShader->setUniform(stringPos, lightSpaceMat);
 | 
					 | 
				
			||||||
					for (Entity* curr : m_lGame) {
 | 
					 | 
				
			||||||
						curr->render(m_directionalShadowShader, true);
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					stringPos = "light[";
 | 
					 | 
				
			||||||
					stringPos += std::to_string(i);
 | 
					 | 
				
			||||||
					stringPos += "].directionalDepthTex";
 | 
					 | 
				
			||||||
					glActiveTexture(GL_TEXTURE4 + i);
 | 
					 | 
				
			||||||
					glBindTexture(GL_TEXTURE_2D, tex);
 | 
					 | 
				
			||||||
					m_lightingShader->setUniform(stringPos, 4 + (int)i);
 | 
					 | 
				
			||||||
					directionalRendered = true;
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				case Light::Type::POINT: {
 | 
					 | 
				
			||||||
					glViewport(0, 0, m_pointDepthTexSize, m_pointDepthTexSize);
 | 
					 | 
				
			||||||
					glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, tex, 0);
 | 
					 | 
				
			||||||
					glDrawBuffer(GL_NONE);
 | 
					 | 
				
			||||||
					glReadBuffer(GL_NONE);
 | 
					 | 
				
			||||||
					glClear(GL_DEPTH_BUFFER_BIT);
 | 
					 | 
				
			||||||
					Vec3 posTemp = m_lights[i]->getPosition();
 | 
					 | 
				
			||||||
					glm::vec3 lightPos(posTemp.x, posTemp.y, posTemp.z);
 | 
					 | 
				
			||||||
					std::vector<glm::mat4> lightSpaceMats;
 | 
					 | 
				
			||||||
					lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
 | 
					 | 
				
			||||||
					lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(-1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
 | 
					 | 
				
			||||||
					lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 1.0, 0.0), glm::vec3(0.0, 0.0, 1.0)));
 | 
					 | 
				
			||||||
					lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, -1.0, 0.0), glm::vec3(0.0, 0.0, -1.0)));
 | 
					 | 
				
			||||||
					lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 0.0, 1.0), glm::vec3(0.0, -1.0, 0.0)));
 | 
					 | 
				
			||||||
					lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 0.0, -1.0), glm::vec3(0.0, -1.0, 0.0)));
 | 
					 | 
				
			||||||
					for (int j = 0; j < 6; j++) {
 | 
					 | 
				
			||||||
						std::string stringPos = "lightSpaceMat[";
 | 
					 | 
				
			||||||
						stringPos += std::to_string(j);
 | 
					 | 
				
			||||||
						stringPos += "]";
 | 
					 | 
				
			||||||
						m_pointShadowShader->setUniform(stringPos, lightSpaceMats[j]);
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					m_pointShadowShader->setUniform("farPlane", farP);
 | 
					 | 
				
			||||||
					m_pointShadowShader->setUniform("lightPos", lightPos);
 | 
					 | 
				
			||||||
					for (Entity* curr : m_lGame) {
 | 
					 | 
				
			||||||
						curr->render(m_pointShadowShader, true);
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					std::string stringPos = "light[";
 | 
					 | 
				
			||||||
					stringPos += std::to_string(i);
 | 
					 | 
				
			||||||
					stringPos += "].pointDepthTex";
 | 
					 | 
				
			||||||
					glActiveTexture(GL_TEXTURE4 + i);
 | 
					 | 
				
			||||||
					glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
 | 
					 | 
				
			||||||
					m_lightingShader->setUniform(stringPos, 4 + (int)i);
 | 
					 | 
				
			||||||
					m_lightingShader->setUniform("farPlane", farP);
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		m_lightingShader->setUniform("numMats", (int)count);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void Renderer::loadBaseAssets() {
 | 
						void Renderer::loadBaseAssets() {
 | 
				
			||||||
		m_baseAP.load("base.nfpack");
 | 
							m_baseAP.load("base.nfpack");
 | 
				
			||||||
		const char* gBufferVertex = m_baseAP.get("gBufferVertex.shader")->data;
 | 
							const char* gBufferVertex = m_baseAP.get("gBufferVertex.shader")->data;
 | 
				
			||||||
@ -438,6 +358,113 @@ namespace nf {
 | 
				
			|||||||
		glBindTexture(GL_TEXTURE_2D, 0);
 | 
							glBindTexture(GL_TEXTURE_2D, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void Renderer::renderShadowMaps(size_t count) {
 | 
				
			||||||
 | 
							float nearP = 0.1f, farP = 400.0f;
 | 
				
			||||||
 | 
							glm::mat4 directionalLightProj = glm::ortho(-50.0f, 50.0f, -50.0f, 50.0f, nearP, farP);
 | 
				
			||||||
 | 
							glm::mat4 pointLightProj = glm::perspective(glm::radians(90.0f), 1.0f, nearP, farP);
 | 
				
			||||||
 | 
							glm::mat4 lightView;
 | 
				
			||||||
 | 
							glm::mat4 lightSpaceMat;
 | 
				
			||||||
 | 
							bool directionalRendered = false;
 | 
				
			||||||
 | 
							unsigned int directionalSlot = 0; //TODO: Test this
 | 
				
			||||||
 | 
							glBindFramebuffer(GL_FRAMEBUFFER, m_shadowMapFBO);
 | 
				
			||||||
 | 
							for (unsigned int i = 0; i < count; i++) {
 | 
				
			||||||
 | 
								Light::Type type = m_lights[i]->getType();
 | 
				
			||||||
 | 
								unsigned int tex = type == Light::Type::DIRECTIONAL ? m_directionalShadowMap : m_pointShadowMaps[i];
 | 
				
			||||||
 | 
								switch (type) {
 | 
				
			||||||
 | 
								case Light::Type::DIRECTIONAL: {
 | 
				
			||||||
 | 
									std::string stringPos;
 | 
				
			||||||
 | 
									glViewport(0, 0, m_directionalDepthTexSize, m_directionalDepthTexSize);
 | 
				
			||||||
 | 
									glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
 | 
				
			||||||
 | 
									glDrawBuffer(GL_NONE);
 | 
				
			||||||
 | 
									glReadBuffer(GL_NONE);
 | 
				
			||||||
 | 
									glClear(GL_DEPTH_BUFFER_BIT);
 | 
				
			||||||
 | 
									Vec3 posTemp = m_lights[i]->getPosition();
 | 
				
			||||||
 | 
									glm::vec3 lightPos(posTemp.x, posTemp.y, posTemp.z);
 | 
				
			||||||
 | 
									lightView = glm::lookAt(lightPos, glm::vec3(0.0), glm::vec3(0.0, 1.0, 0.0));
 | 
				
			||||||
 | 
									lightSpaceMat = directionalLightProj * lightView;
 | 
				
			||||||
 | 
									m_directionalShadowShader->setUniform("lightSpace", lightSpaceMat);
 | 
				
			||||||
 | 
									stringPos = "lightSpaceMat[";
 | 
				
			||||||
 | 
									stringPos += std::to_string(i);
 | 
				
			||||||
 | 
									stringPos += "]";
 | 
				
			||||||
 | 
									m_lightingShader->setUniform(stringPos, lightSpaceMat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									instancedRenderShadows(m_directionalShadowShader);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									stringPos = "light[";
 | 
				
			||||||
 | 
									stringPos += std::to_string(i);
 | 
				
			||||||
 | 
									stringPos += "].directionalDepthTex";
 | 
				
			||||||
 | 
									glActiveTexture(GL_TEXTURE4 + i);
 | 
				
			||||||
 | 
									glBindTexture(GL_TEXTURE_2D, tex);
 | 
				
			||||||
 | 
									m_lightingShader->setUniform(stringPos, 4 + (int)i);
 | 
				
			||||||
 | 
									directionalRendered = true;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								case Light::Type::POINT: {
 | 
				
			||||||
 | 
									glViewport(0, 0, m_pointDepthTexSize, m_pointDepthTexSize);
 | 
				
			||||||
 | 
									glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, tex, 0);
 | 
				
			||||||
 | 
									glDrawBuffer(GL_NONE);
 | 
				
			||||||
 | 
									glReadBuffer(GL_NONE);
 | 
				
			||||||
 | 
									glClear(GL_DEPTH_BUFFER_BIT);
 | 
				
			||||||
 | 
									Vec3 posTemp = m_lights[i]->getPosition();
 | 
				
			||||||
 | 
									glm::vec3 lightPos(posTemp.x, posTemp.y, posTemp.z);
 | 
				
			||||||
 | 
									std::vector<glm::mat4> lightSpaceMats;
 | 
				
			||||||
 | 
									lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
 | 
				
			||||||
 | 
									lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(-1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
 | 
				
			||||||
 | 
									lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 1.0, 0.0), glm::vec3(0.0, 0.0, 1.0)));
 | 
				
			||||||
 | 
									lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, -1.0, 0.0), glm::vec3(0.0, 0.0, -1.0)));
 | 
				
			||||||
 | 
									lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 0.0, 1.0), glm::vec3(0.0, -1.0, 0.0)));
 | 
				
			||||||
 | 
									lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 0.0, -1.0), glm::vec3(0.0, -1.0, 0.0)));
 | 
				
			||||||
 | 
									for (int j = 0; j < 6; j++) {
 | 
				
			||||||
 | 
										std::string stringPos = "lightSpaceMat[";
 | 
				
			||||||
 | 
										stringPos += std::to_string(j);
 | 
				
			||||||
 | 
										stringPos += "]";
 | 
				
			||||||
 | 
										m_pointShadowShader->setUniform(stringPos, lightSpaceMats[j]);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									m_pointShadowShader->setUniform("farPlane", farP);
 | 
				
			||||||
 | 
									m_pointShadowShader->setUniform("lightPos", lightPos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									instancedRenderShadows(m_pointShadowShader);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									std::string stringPos = "light[";
 | 
				
			||||||
 | 
									stringPos += std::to_string(i);
 | 
				
			||||||
 | 
									stringPos += "].pointDepthTex";
 | 
				
			||||||
 | 
									glActiveTexture(GL_TEXTURE4 + i);
 | 
				
			||||||
 | 
									glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
 | 
				
			||||||
 | 
									m_lightingShader->setUniform(stringPos, 4 + (int)i);
 | 
				
			||||||
 | 
									m_lightingShader->setUniform("farPlane", farP);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							m_lightingShader->setUniform("numMats", (int)count);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void Renderer::instancedRenderShadows(Shader* shader) {
 | 
				
			||||||
 | 
							std::unordered_map<Model*, std::vector<glm::mat4>> modelsToDraw;
 | 
				
			||||||
 | 
							for (Entity* curr : m_lGame) {
 | 
				
			||||||
 | 
								modelsToDraw[curr->getModel()].push_back(curr->getModelMatrix());
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for (auto& curr : modelsToDraw) {
 | 
				
			||||||
 | 
								std::vector<glm::mat4>& mats = curr.second;
 | 
				
			||||||
 | 
								std::string pos;
 | 
				
			||||||
 | 
								size_t modelsRemaining = mats.size();
 | 
				
			||||||
 | 
								while (modelsRemaining != 0) {
 | 
				
			||||||
 | 
									size_t modelCount;
 | 
				
			||||||
 | 
									if (modelsRemaining > 60)
 | 
				
			||||||
 | 
										modelCount = 60;
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										modelCount = modelsRemaining;
 | 
				
			||||||
 | 
									modelsRemaining -= modelCount;
 | 
				
			||||||
 | 
									for (unsigned int i = 0; i < modelCount; i++) {
 | 
				
			||||||
 | 
										pos = std::to_string(i) + "]";
 | 
				
			||||||
 | 
										shader->setUniform("model[" + pos, mats[i]);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									curr.first->render(shader, true, (unsigned int)modelCount);
 | 
				
			||||||
 | 
									mats.erase(mats.begin(), mats.begin() + modelCount);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Renderer::~Renderer() {
 | 
						Renderer::~Renderer() {
 | 
				
			||||||
		delete m_gBufferShader;
 | 
							delete m_gBufferShader;
 | 
				
			||||||
		delete m_lightingShader;
 | 
							delete m_lightingShader;
 | 
				
			||||||
 | 
				
			|||||||
@ -25,6 +25,5 @@ namespace nf {
 | 
				
			|||||||
		unsigned int m_width, m_height;
 | 
							unsigned int m_width, m_height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		std::unordered_map<Model*, std::vector<glm::mat4>> m_modelsToDraw;
 | 
							std::unordered_map<Model*, std::vector<glm::mat4>> m_modelsToDraw;
 | 
				
			||||||
		const std::string m_modelString = "model[";
 | 
					 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -33,10 +33,10 @@ namespace nf {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		~Renderer();
 | 
							~Renderer();
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		void renderShadowMaps(size_t count);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		void loadBaseAssets();
 | 
							void loadBaseAssets();
 | 
				
			||||||
		void createShadowMaps();
 | 
							void createShadowMaps();
 | 
				
			||||||
 | 
							void renderShadowMaps(size_t count);
 | 
				
			||||||
 | 
							void instancedRenderShadows(Shader* shader);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Application* m_app;
 | 
							Application* m_app;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user