Use instanced arrays to draw the lights
This commit is contained in:
		
							
								
								
									
										18
									
								
								shaders/light_vert.glsl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								shaders/light_vert.glsl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| #version 330 core | ||||
|  | ||||
| #define POINT_LIGHT_COUNT 4 | ||||
|  | ||||
| layout(location=0) in vec3 position; | ||||
| layout(location=1) in vec3 normal; | ||||
| layout(location=2) in vec2 uv; | ||||
| layout(location=3) in mat4 model; | ||||
|  | ||||
| layout (std140) uniform Common { | ||||
|   mat4 projection; | ||||
|   mat4 view; | ||||
|   vec3 camera_position; | ||||
| }; | ||||
|  | ||||
| void main() { | ||||
|   gl_Position = projection * view * model * vec4(position, 1.0); | ||||
| }; | ||||
							
								
								
									
										69
									
								
								src/main.cc
									
									
									
									
									
								
							
							
						
						
									
										69
									
								
								src/main.cc
									
									
									
									
									
								
							| @@ -50,7 +50,7 @@ | ||||
|  | ||||
| #define WIREFRAME 0 | ||||
| #define NORMALS 0 | ||||
| #define POINT_LIGHTS 0 | ||||
| #define POINT_LIGHTS 1 | ||||
|  | ||||
| enum exit_codes : int { | ||||
|   EXIT_CODE_SUCCESS, | ||||
| @@ -116,10 +116,14 @@ class Mesh { | ||||
|     std::vector<Texture2D> textures; | ||||
|  | ||||
|     Mesh(std::vector<Vertex> vertices, std::vector<GLuint> indices, std::vector<Texture2D> textures); | ||||
|     void activate(); | ||||
|     void deactivate(); | ||||
|     void draw(Shader &Shader); | ||||
|     void draw_instanced(Shader &Shader, unsigned int count = 1); | ||||
|   private: | ||||
|     GLuint vao, vbo, ebo; | ||||
|     void setup_mesh(); | ||||
|     void set_mesh_textures_for_drawing(Shader &shader); | ||||
| }; | ||||
|  | ||||
| class Model { | ||||
| @@ -282,7 +286,8 @@ int main() { | ||||
| #endif | ||||
|  | ||||
| #if POINT_LIGHTS | ||||
|   Shader light_shader      {"shaders/vert.glsl",        "shaders/light_frag.glsl"}; | ||||
|   Shader light_shader      {"shaders/light_vert.glsl",  "shaders/light_frag.glsl"}; | ||||
|   std::vector<glm::mat4> light_shader_model_mats; | ||||
| #endif | ||||
|  | ||||
|   const float camera_speed  = 25.0f; | ||||
| @@ -356,8 +361,36 @@ int main() { | ||||
|     memset(constant,  0, sizeof(constant)); | ||||
|     memset(linear,    0, sizeof(linear)); | ||||
|     memset(quadratic, 0, sizeof(quadratic)); | ||||
|  | ||||
| #if POINT_LIGHTS | ||||
|     glm::mat4 light_shader_model_mat = glm::translate(glm::mat4(1.0f), point_light_positions[i]); | ||||
|     light_shader_model_mat = glm::scale(light_shader_model_mat, glm::vec3(0.2f)); | ||||
|     light_shader_model_mats.push_back(light_shader_model_mat); | ||||
| #endif | ||||
|   } | ||||
|  | ||||
| #if POINT_LIGHTS | ||||
|   std::size_t vec4_size = sizeof(glm::vec4); | ||||
|  | ||||
|   light.activate(); | ||||
|  | ||||
|   GLuint instanceVBO; | ||||
|   glGenBuffers(1, &instanceVBO); | ||||
|   glBindBuffer(GL_ARRAY_BUFFER, instanceVBO); | ||||
|   glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4) * light_shader_model_mats.size(), glm::value_ptr(light_shader_model_mats[0]), GL_STATIC_DRAW); | ||||
|  | ||||
|   // Set up attribute pointers for each column of the matrix | ||||
|   for (unsigned int i = 3; i < 7; ++i) { | ||||
|     glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 4 * vec4_size, (void *)((i - 3) * vec4_size)); | ||||
|     glEnableVertexAttribArray(i); | ||||
|     glVertexAttribDivisor(i, 1); | ||||
|   } | ||||
|  | ||||
|   light.deactivate(); | ||||
|  | ||||
|   glBindBuffer(GL_ARRAY_BUFFER, 0); | ||||
| #endif | ||||
|  | ||||
|   // Load cube map | ||||
|   std::vector<std::string> cube_map_textures = { | ||||
|     "images/skybox/right.jpg", | ||||
| @@ -526,22 +559,14 @@ int main() { | ||||
|     refractive_shader.set_mat4("model", model); | ||||
|     refractive_shader.set_mat3("normal_mat", normal_mat); | ||||
|     suzanne.draw(refractive_shader); | ||||
|     glEnable(GL_CULL_FACE); | ||||
|  | ||||
| #if POINT_LIGHTS | ||||
|     // Draw point lights | ||||
|     for (int i = 0; i < point_light_positions.size(); ++i) { | ||||
|       model = glm::translate(glm::mat4(1.0f), point_light_positions[i]); | ||||
|       model = glm::scale(model, glm::vec3(0.2f)); | ||||
|       light_shader.activate(); | ||||
|       light_shader.set_mat4("model", model); | ||||
|       light_shader.set_vec3("light_diffuse", light_diffuse); | ||||
|       light.draw(light_shader); | ||||
|     } | ||||
|     light_shader.set_vec3("light_diffuse", light_diffuse); | ||||
|     light.draw_instanced(light_shader, point_light_positions.size()); | ||||
| #endif | ||||
|  | ||||
|     // Draw skybox | ||||
|     glDisable(GL_CULL_FACE); | ||||
|     skybox_shader.activate(); | ||||
|     glActiveTexture(GL_TEXTURE0); | ||||
|     glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap); | ||||
| @@ -803,7 +828,7 @@ void Mesh::setup_mesh() { | ||||
|   glEnableVertexAttribArray(2); | ||||
| } | ||||
|  | ||||
| void Mesh::draw(Shader &shader) { | ||||
| void Mesh::set_mesh_textures_for_drawing(Shader &shader) { | ||||
|   unsigned int diffuse = 1; | ||||
|   unsigned int specular = 1; | ||||
|   unsigned int index; | ||||
| @@ -814,9 +839,27 @@ void Mesh::draw(Shader &shader) { | ||||
|     shader.set_int(texture.name(index).c_str(), texture.texture_unit - GL_TEXTURE0); | ||||
|     texture.activate(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void Mesh::activate() { | ||||
|   glBindVertexArray(vao); | ||||
| } | ||||
|  | ||||
| void Mesh::deactivate() { | ||||
|   glBindVertexArray(0); | ||||
| } | ||||
|  | ||||
| void Mesh::draw(Shader &shader) { | ||||
|   set_mesh_textures_for_drawing(shader); | ||||
|   activate(); | ||||
|   glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0); | ||||
|   deactivate(); | ||||
| } | ||||
|  | ||||
| void Mesh::draw_instanced(Shader &shader, unsigned int count) { | ||||
|   set_mesh_textures_for_drawing(shader); | ||||
|   glBindVertexArray(vao); | ||||
|   glDrawElementsInstanced(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0, count); | ||||
|   glBindVertexArray(0); | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user