Use instanced arrays to draw the lights
This commit is contained in:
parent
ce561fc44d
commit
e9a9b8a2cf
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);
|
||||||
|
};
|
67
src/main.cc
67
src/main.cc
@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
#define WIREFRAME 0
|
#define WIREFRAME 0
|
||||||
#define NORMALS 0
|
#define NORMALS 0
|
||||||
#define POINT_LIGHTS 0
|
#define POINT_LIGHTS 1
|
||||||
|
|
||||||
enum exit_codes : int {
|
enum exit_codes : int {
|
||||||
EXIT_CODE_SUCCESS,
|
EXIT_CODE_SUCCESS,
|
||||||
@ -116,10 +116,14 @@ class Mesh {
|
|||||||
std::vector<Texture2D> textures;
|
std::vector<Texture2D> textures;
|
||||||
|
|
||||||
Mesh(std::vector<Vertex> vertices, std::vector<GLuint> indices, 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(Shader &Shader);
|
||||||
|
void draw_instanced(Shader &Shader, unsigned int count = 1);
|
||||||
private:
|
private:
|
||||||
GLuint vao, vbo, ebo;
|
GLuint vao, vbo, ebo;
|
||||||
void setup_mesh();
|
void setup_mesh();
|
||||||
|
void set_mesh_textures_for_drawing(Shader &shader);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Model {
|
class Model {
|
||||||
@ -282,7 +286,8 @@ int main() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if POINT_LIGHTS
|
#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
|
#endif
|
||||||
|
|
||||||
const float camera_speed = 25.0f;
|
const float camera_speed = 25.0f;
|
||||||
@ -356,8 +361,36 @@ int main() {
|
|||||||
memset(constant, 0, sizeof(constant));
|
memset(constant, 0, sizeof(constant));
|
||||||
memset(linear, 0, sizeof(linear));
|
memset(linear, 0, sizeof(linear));
|
||||||
memset(quadratic, 0, sizeof(quadratic));
|
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
|
// Load cube map
|
||||||
std::vector<std::string> cube_map_textures = {
|
std::vector<std::string> cube_map_textures = {
|
||||||
"images/skybox/right.jpg",
|
"images/skybox/right.jpg",
|
||||||
@ -526,22 +559,14 @@ int main() {
|
|||||||
refractive_shader.set_mat4("model", model);
|
refractive_shader.set_mat4("model", model);
|
||||||
refractive_shader.set_mat3("normal_mat", normal_mat);
|
refractive_shader.set_mat3("normal_mat", normal_mat);
|
||||||
suzanne.draw(refractive_shader);
|
suzanne.draw(refractive_shader);
|
||||||
glEnable(GL_CULL_FACE);
|
|
||||||
|
|
||||||
#if POINT_LIGHTS
|
#if POINT_LIGHTS
|
||||||
// Draw 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_shader.set_vec3("light_diffuse", light_diffuse);
|
||||||
light.draw(light_shader);
|
light.draw_instanced(light_shader, point_light_positions.size());
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Draw skybox
|
// Draw skybox
|
||||||
glDisable(GL_CULL_FACE);
|
|
||||||
skybox_shader.activate();
|
skybox_shader.activate();
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap);
|
||||||
@ -803,7 +828,7 @@ void Mesh::setup_mesh() {
|
|||||||
glEnableVertexAttribArray(2);
|
glEnableVertexAttribArray(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::draw(Shader &shader) {
|
void Mesh::set_mesh_textures_for_drawing(Shader &shader) {
|
||||||
unsigned int diffuse = 1;
|
unsigned int diffuse = 1;
|
||||||
unsigned int specular = 1;
|
unsigned int specular = 1;
|
||||||
unsigned int index;
|
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);
|
shader.set_int(texture.name(index).c_str(), texture.texture_unit - GL_TEXTURE0);
|
||||||
texture.activate();
|
texture.activate();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::activate() {
|
||||||
glBindVertexArray(vao);
|
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);
|
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);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user