From ae78f0a399f5b4b3a4d8fb33fd338f6a24daf605 Mon Sep 17 00:00:00 2001 From: ktyl Date: Sun, 13 Aug 2023 22:44:06 +0200 Subject: [PATCH] refactor: extract sphere model matrix calc --- src/gfx.cpp | 18 +++++++++++------- src/gfx.hpp | 4 ++-- src/icosphere.cpp | 20 +++++++++++++++++++- src/icosphere.hpp | 7 ++++++- src/main.cpp | 2 +- 5 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/gfx.cpp b/src/gfx.cpp index fa3bed1..6155253 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -116,18 +116,22 @@ void updateProjectionMatrix(GLuint shaderProgram) glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, &projection[0][0]); } -void updateModelMatrix(GLuint shaderProgram, float time) +void updateModelMatrix(GLuint shaderProgram) { - constexpr float angle = glm::radians(10.0); - glm::vec3 axis = glm::vec3(0.0, 1.0, 0.0); - glm::mat4 model = glm::rotate(glm::mat4(1.0), angle * time, axis); + glm::mat4 model = glm::mat4(1.0); GLint modelLocation = getShaderUniformLocation(shaderProgram, "_Model"); glUniformMatrix4fv(modelLocation, 1, GL_FALSE, &model[0][0]); } -void updateViewMatrix(GLuint shaderProgram) +void updateViewMatrix(GLuint shaderProgram, float time) { glm::mat4 view = glm::mat4(1.0); + + // Rotation + constexpr float angle = glm::radians(10.0); + glm::vec3 axis = glm::vec3(0.0, 1.0, 0.0); + view = glm::rotate(view, angle * time, axis); + GLint viewLocation = getShaderUniformLocation(shaderProgram, "_View"); glUniformMatrix4fv(viewLocation, 1, GL_FALSE, &view[0][0]); } @@ -136,8 +140,8 @@ void updateModelViewProjectionMatrix(GLuint shaderProgram, float time) { // Calculate matrices updateProjectionMatrix(shaderProgram); - updateModelMatrix(shaderProgram, time); - updateViewMatrix(shaderProgram); + updateModelMatrix(shaderProgram); + updateViewMatrix(shaderProgram, time); } GLint getShaderUniformLocation(GLuint shaderProgram, const std::string& uniformName) diff --git a/src/gfx.hpp b/src/gfx.hpp index 1de9fac..419e121 100644 --- a/src/gfx.hpp +++ b/src/gfx.hpp @@ -13,6 +13,6 @@ GLuint compileShader(const std::string& shaderPath, GLenum shaderType); GLint getShaderUniformLocation(GLuint shaderProgram, const std::string& uniformName); void updateProjectionMatrix(GLuint shaderProgram); -void updateModelMatrix(GLuint shaderProgram, float time); -void updateViewMatrix(GLuint shaderProgram); +void updateModelMatrix(GLuint shaderProgram); +void updateViewMatrix(GLuint shaderProgram, float time); void updateModelViewProjectionMatrix(GLuint shaderProgram, float time); diff --git a/src/icosphere.cpp b/src/icosphere.cpp index 1672169..11d92ff 100644 --- a/src/icosphere.cpp +++ b/src/icosphere.cpp @@ -3,7 +3,13 @@ #include #include -Icosphere::Icosphere(float radius, int subdivisions) +#include "glm/gtc/matrix_transform.hpp" + +#include "gfx.hpp" + +Icosphere::Icosphere(float radius, int subdivisions, GLuint shaderProgram, glm::vec3 position) : + _shaderProgram(shaderProgram), + _position(position) { VertexList vertices = _isocahedronVertices; TriangleList triangles = _isocahedronTriangles; @@ -125,8 +131,20 @@ Icosphere::TriangleList Icosphere::subdivide(VertexList& vertices, TriangleList return result; } +void Icosphere::updateModelMatrix() +{ + // To be able to define a position for a particular instance of a sphere we will + // need to calculate a model projection matrix per-instance + glm::mat4 model = glm::translate(glm::mat4(1.0), _position); + + GLint modelLocation = getShaderUniformLocation(_shaderProgram, "_Model"); + glUniformMatrix4fv(modelLocation, 1, GL_FALSE, &model[0][0]); +} + void Icosphere::render() { + updateModelMatrix(); + glBindVertexArray(_vao); glBindBuffer(GL_ARRAY_BUFFER, _vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); diff --git a/src/icosphere.hpp b/src/icosphere.hpp index 1ef5bf6..8e9ae88 100644 --- a/src/icosphere.hpp +++ b/src/icosphere.hpp @@ -10,7 +10,7 @@ class Icosphere { public: - Icosphere(float radius, int subdivisions); + Icosphere(float radius, int subdivisions, GLuint shaderProgram, glm::vec3 position); void render(); ~Icosphere(); @@ -19,10 +19,13 @@ private: GLuint _vbo; GLuint _vao; GLuint _ebo; + GLuint _shaderProgram; std::vector _vertices; std::vector _indices; + glm::vec3 _position; + // Generating an isosphere // https://schneide.blog/2016/07/15/generating-an-icosphere-in-c/ struct Triangle @@ -56,4 +59,6 @@ private: int vertexForEdge(Lookup& lookup, VertexList& vertices, int first, int second); TriangleList subdivide(VertexList& vertices, TriangleList triangles); + + void updateModelMatrix(); }; diff --git a/src/main.cpp b/src/main.cpp index 87dcfb7..8d119a2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -51,7 +51,7 @@ int main() GLuint litProgram = compileShaderProgram("./frag_lit.glsl"); GLuint unlitProgram = compileShaderProgram("./frag_unlit.glsl"); - Icosphere sphere(0.5, 2); + Icosphere sphere(0.5, 2, litProgram, glm::vec3(0.0, 0.0, 0.0)); Orbit orbit(100); // Main loop