text: #include "stdafx.h"
  #include "PostProcessing.h"
  
  RenderEngineNS::PostProcessing::PostProcessing()
  {
  
  }
  
  RenderEngineNS::PostProcessing::~PostProcessing()
  {
  }
  
  void RenderEngineNS::PostProcessing::createDepthTexture()
  {
  
  	float planeVertices[] = {
  		// positions            // normals         // texcoords
  		25.0f, -0.5f,  25.0f,  0.0f, 1.0f, 0.0f,  25.0f,  0.0f,
  		-25.0f, -0.5f,  25.0f,  0.0f, 1.0f, 0.0f,   0.0f,  0.0f,
  		-25.0f, -0.5f, -25.0f,  0.0f, 1.0f, 0.0f,   0.0f, 25.0f,
  
  		25.0f, -0.5f,  25.0f,  0.0f, 1.0f, 0.0f,  25.0f,  0.0f,
  		-25.0f, -0.5f, -25.0f,  0.0f, 1.0f, 0.0f,   0.0f, 25.0f,
  		25.0f, -0.5f, -25.0f,  0.0f, 1.0f, 0.0f,  25.0f, 10.0f
  	};
  
  	unsigned int planeVBO;
  	glGenVertexArrays(1, &m_vao);
  	glGenBuffers(1, &m_vbo);
  	glBindVertexArray(m_vao);
  	glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
  	glBufferData(GL_ARRAY_BUFFER, sizeof(planeVertices), planeVertices, GL_STATIC_DRAW);
  	glEnableVertexAttribArray(0);
  	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
  	glEnableVertexAttribArray(1);
  	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
  	glEnableVertexAttribArray(2);
  	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
  	glBindVertexArray(0);
  
  	glGenFramebuffers(1, &m_fbo);
  	glGenTextures(1, &m_depthMap);
  	glBindTexture(GL_TEXTURE_2D, m_depthMap);
  	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
  	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  }
  
  void RenderEngineNS::PostProcessing::attachDepthTexture()
  {
  	glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
  	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthMap, 0);
  	glDrawBuffer(GL_NONE);
  	glReadBuffer(GL_NONE);
  	glBindFramebuffer(GL_FRAMEBUFFER, 0);
  }
  
  void RenderEngineNS::PostProcessing::draw(Shader & p_shader, float p_time)
  {
  	float near_plane = 1.0f, far_plane = 7.5f;
  	glm::mat4 lightProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane);
  	glm::mat4 lightView = glm::lookAt(glm::vec3(-2.0f, 4.0f, -1.0f),glm::vec3(0.0f, 0.0f, 0.0f),glm::vec3(0.0f, 1.0f, 0.0f));
  	glm::mat4 lightSpaceMatrix = lightProjection * lightView;
  
  	glUseProgram(p_shader.GetRendererID());
  	p_shader.SetUniformMat4f("lightSpaceMatrix", lightSpaceMatrix);
  
  	glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
  	glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
  	glClear(GL_DEPTH_BUFFER_BIT);
  	renderScene(p_shader);
  	glBindFramebuffer(GL_FRAMEBUFFER, 0);
  
  
  }
  
  void RenderEngineNS::PostProcessing::renderScene(Shader & p_shader)
  {
  	glm::mat4 model = glm::mat4(1.0f);
  	p_shader.SetUniformMat4f("model", model);
  	glBindVertexArray(m_vao);
  	glDrawArrays(GL_TRIANGLES, 0, 6);
  	// cubes
  	model = glm::mat4(1.0f);
  	model = glm::translate(model, glm::vec3(0.0f, 1.5f, 0.0));
  	model = glm::scale(model, glm::vec3(0.5f));
  	p_shader.SetUniformMat4f("model", model);
  	renderQuad();
  	model = glm::mat4(1.0f);
  	model = glm::translate(model, glm::vec3(2.0f, 0.0f, 1.0));
  	model = glm::scale(model, glm::vec3(0.5f));
  	p_shader.SetUniformMat4f("model", model);
  	renderQuad();
  	model = glm::mat4(1.0f);
  	model = glm::translate(model, glm::vec3(-1.0f, 0.0f, 2.0));
  	model = glm::rotate(model, glm::radians(60.0f), glm::normalize(glm::vec3(1.0, 0.0, 1.0)));
  	model = glm::scale(model, glm::vec3(0.25));
  	p_shader.SetUniformMat4f("model", model);
  	renderQuad();
  }
  
  void RenderEngineNS::PostProcessing::renderQuad()
  {
  	if (m_vao == 0)
  	{
  		float quadVertices[] = {
  			// positions        // texture Coords
  			-1.0f,  1.0f, 0.0f, 0.0f, 1.0f,
  			-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
  			1.0f,  1.0f, 0.0f, 1.0f, 1.0f,
  			1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
  		};
  		// setup plane VAO
  		glGenVertexArrays(1, &m_vao);
  		glGenBuffers(1, &m_vbo);
  		glBindVertexArray(m_vao);
  		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
  		glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
  		glEnableVertexAttribArray(0);
  		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
  		glEnableVertexAttribArray(1);
  		glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
  	}
  	glBindVertexArray(m_vao);
  	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  	glBindVertexArray(0);
  }
  