From 4a5ac87e506797a67a95dba8276d11d99771ee4b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20=C5=A0toura=C4=8D?= <525032@mail.muni.cz>
Date: Sat, 15 Apr 2023 22:42:46 +0200
Subject: [PATCH] multiple shaders and objects(vector of shared_ptr)

---
 data/shaders/basicshader.frag           |  5 +-
 src/gfx/include/gfx/object.hpp          | 12 ++++-
 src/gfx/include/gfx/render.hpp          | 13 +++--
 src/gfx/src/obj_control.cpp             |  2 +-
 src/gfx/src/object.cpp                  |  5 +-
 src/gfx/src/render.cpp                  | 66 ++++++++++++++++---------
 src/studio/include/studio/simulator.hpp | 18 +++++--
 src/studio/src/simulator.cpp            | 25 ++++++----
 8 files changed, 101 insertions(+), 45 deletions(-)

diff --git a/data/shaders/basicshader.frag b/data/shaders/basicshader.frag
index 75c6387..bb1304f 100644
--- a/data/shaders/basicshader.frag
+++ b/data/shaders/basicshader.frag
@@ -1,6 +1,9 @@
 #version 330 core
 layout(location = 0) out vec4 FragColor;
+
+uniform vec3 objectColor;
+
 void main()
 {
-    FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
+    FragColor = vec4(objectColor, 1.0f);
 }
diff --git a/src/gfx/include/gfx/object.hpp b/src/gfx/include/gfx/object.hpp
index ffa7b93..fa41958 100644
--- a/src/gfx/include/gfx/object.hpp
+++ b/src/gfx/include/gfx/object.hpp
@@ -22,12 +22,16 @@ class Object
     VBO _VBO_normal;
     EBO _EBO;
 
+    glm::vec3 color = glm::vec3(1.0f, 0.5f, 0.31f);
+    bool light = false;
+
     bool buffer_object();
 
 public:
     Object(std::vector<float> const &_vertices, 
            std::vector<unsigned int> const &_indices,
-           std::vector<float> const &_normals);
+           std::vector<float> const &_normals,
+           glm::vec3 _color = glm::vec3(1.0f, 0.5f, 0.31f));
 
     std::vector<float> const &getVertices() const { return vertices; }
     void setVertices(std::vector<float> const &new_vertices) { vertices = new_vertices; }
@@ -39,6 +43,12 @@ public:
     void setNormals(std::vector<float> const &new_normals) { normals = new_normals; }
 
     VAO &getVAO() { return _VAO; }
+
+    bool is_lit() const { return !light; }
+    void setToLight(bool b) { light = b; }
+
+    glm::vec3 getColor() const { return color; }
+    void setColor(glm::vec3 _color) { color = _color; }
 };
 
 #endif
\ No newline at end of file
diff --git a/src/gfx/include/gfx/render.hpp b/src/gfx/include/gfx/render.hpp
index 184b375..a974235 100644
--- a/src/gfx/include/gfx/render.hpp
+++ b/src/gfx/include/gfx/render.hpp
@@ -11,10 +11,15 @@
 #include <iostream>
 #include <vector>
 
+using object_ptr = std::shared_ptr<Object>;
+using frame_ptr = std::shared_ptr<Frame>;
+using obj_control_ptr = std::shared_ptr<ObjectController>;
+using shader_ptr = std::shared_ptr<Shader>;
+
 void send_matrices_to_shader(Shader &myShader, glm::mat4 &model, glm::mat4 &view, glm::mat4 &projection);
-void gfx_draw(Shader &myShader, 
-              Camera &camera, Object &object, 
-              Frame &cam_frame, Frame &obj_frame, 
-              CameraController &cam_control, ObjectController &obj_control);
+void gfx_draw(std::vector<shader_ptr> &myShaders, 
+              Camera &camera, std::vector<object_ptr> &objects, 
+              Frame &cam_frame, std::vector<frame_ptr> &obj_frames, 
+              CameraController &cam_control, std::vector<obj_control_ptr> &obj_controls);
 
 #endif
\ No newline at end of file
diff --git a/src/gfx/src/obj_control.cpp b/src/gfx/src/obj_control.cpp
index 16ef9f4..d167cea 100644
--- a/src/gfx/src/obj_control.cpp
+++ b/src/gfx/src/obj_control.cpp
@@ -2,5 +2,5 @@
 
 void ObjectController::setFrontVec() // temporary implementation
 {
-    //frontVec = glm::vec3(0.0f, 0.0f, -1.0f);
+    frontVec = glm::vec3(0.0f, 0.0f, -1.0f);
 }
\ No newline at end of file
diff --git a/src/gfx/src/object.cpp b/src/gfx/src/object.cpp
index ae0e6fe..db3f855 100644
--- a/src/gfx/src/object.cpp
+++ b/src/gfx/src/object.cpp
@@ -3,8 +3,9 @@
 
 Object::Object(std::vector<float> const &_vertices, 
                std::vector<unsigned int> const &_indices, 
-               std::vector<float> const &_normals)
- : vertices{_vertices}, indices{_indices}, normals{_normals}
+               std::vector<float> const &_normals,
+               glm::vec3 _color)
+ : vertices{_vertices}, indices{_indices}, normals{_normals}, color{_color}
 {
     buffer_object();
 }
diff --git a/src/gfx/src/render.cpp b/src/gfx/src/render.cpp
index e2967cc..4a32f06 100644
--- a/src/gfx/src/render.cpp
+++ b/src/gfx/src/render.cpp
@@ -69,21 +69,21 @@ void send_matrices_to_shader(Shader &myShader, glm::mat4 &model, glm::mat4 &view
     ASSUMPTION(glGetError() == GL_NO_ERROR);
 }
 
-void gfx_draw(Shader &myShader, 
-              Camera &camera, Object &object, 
-              Frame &cam_frame, Frame &obj_frame, 
-              CameraController &cam_control, ObjectController &obj_control)
+void gfx_draw(std::vector<shader_ptr> &myShaders, 
+              Camera &camera, std::vector<object_ptr> &objects, 
+              Frame &cam_frame, std::vector<frame_ptr> &obj_frames, 
+              CameraController &cam_control, std::vector<obj_control_ptr> &obj_controls)
 {
     glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
     ASSUMPTION(glGetError() == GL_NO_ERROR);
 
-    Frame lightPos(glm::vec3(1.2f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f));
+    Frame lightPos(glm::vec3(1.2f, 2.0f, 2.0f));
 
-    myShader.use();
-    myShader.setVec3("objectColor", glm::vec3(1.0f, 0.5f, 0.31f));
-    myShader.setVec3("lightColor", glm::vec3(1.0f, 1.0f, 1.0f));
-    myShader.setVec3("lightPos", lightPos.getPosition());
+    // myShader.use();
+    // myShader.setVec3("objectColor", glm::vec3(1.0f, 0.5f, 0.31f));
+    // myShader.setVec3("lightColor", glm::vec3(1.0f, 1.0f, 1.0f));
+    // myShader.setVec3("lightPos", lightPos.getPosition());
 
 
     /* -------------------- Transformation examples --------------------*/
@@ -101,9 +101,6 @@ void gfx_draw(Shader &myShader,
     //                    glm::vec3(0.0f, 1.0f, 0.0f));
     /* ---------------------------------------------------------------- */
 
-    // DRAW CUBE
-    glm::mat4 model = obj_frame.getModelMat();
-
     glm::mat4 view;
     view = glm::lookAt(cam_frame.getPosition(), cam_frame.getPosition() + cam_control.getFrontVec(), cam_control.getUpVec());
 
@@ -113,31 +110,54 @@ void gfx_draw(Shader &myShader,
                                   0.1f, 
                                   100.0f);
 
-    send_matrices_to_shader(myShader, model, view, projection);
-
     glEnable(GL_DEPTH_TEST);
     ASSUMPTION(glGetError() == GL_NO_ERROR);
 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     ASSUMPTION(glGetError() == GL_NO_ERROR);
 
-    object.getVAO().Bind();
-    //glDrawArrays(GL_TRIANGLES, 0, 3);
-    glDrawElements(GL_TRIANGLES, 
-                   static_cast<GLsizei>(object.getIndices().size()), 
-                   GL_UNSIGNED_INT, 
-                   0);
-    ASSUMPTION(glGetError() == GL_NO_ERROR);
+    // DRAW OBJECTS
+    for (std::size_t i = 0; i < objects.size(); ++i)
+    {
+        std::size_t shader_idx;
+        if (objects[i]->is_lit())
+        {
+            myShaders[0]->use();
+            myShaders[0]->setVec3("lightColor", glm::vec3(1.0f, 1.0f, 1.0f));
+            myShaders[0]->setVec3("lightPos", lightPos.getPosition());
+            shader_idx = 0;
+        }
+        else
+        {
+            myShaders[1]->use();
+            shader_idx = 1;
+        }
+        myShaders[shader_idx]->setVec3("objectColor", objects[i]->getColor());
+        
+        
+        glm::mat4 model = obj_frames[i]->getModelMat();
+
+        send_matrices_to_shader(*myShaders[shader_idx], model, view, projection);
+
+        objects[i]->getVAO().Bind();
+        //glDrawArrays(GL_TRIANGLES, 0, 3);
+        glDrawElements(GL_TRIANGLES, 
+                    static_cast<GLsizei>(objects[i]->getIndices().size()), 
+                    GL_UNSIGNED_INT, 
+                    0);
+        ASSUMPTION(glGetError() == GL_NO_ERROR);
+    }
 
     // DRAW GRID
     int span = 100;
     Object grid(generate_grid_vertices(span), generate_grid_indices(span), grid_normals);
     Frame grid_frame({0, 0, 0});
 
-    myShader.setVec3("objectColor", glm::vec3(0.5f, 0.5f, 0.5f));
+    myShaders[1]->use();
+    myShaders[1]->setVec3("objectColor", glm::vec3(0.5f, 0.5f, 0.5f));
     glm::mat4 grid_model = grid_frame.getModelMat() * grid_frame.getRotationMat();
 
-    send_matrices_to_shader(myShader, grid_model, view, projection);
+    send_matrices_to_shader(*myShaders[0], grid_model, view, projection);
 
     grid.getVAO().Bind();
     glDrawElements(GL_LINES, 
diff --git a/src/studio/include/studio/simulator.hpp b/src/studio/include/studio/simulator.hpp
index 2ce0e94..aa52ad4 100644
--- a/src/studio/include/studio/simulator.hpp
+++ b/src/studio/include/studio/simulator.hpp
@@ -20,9 +20,16 @@
 #include <gfx/shader.hpp>
 #include <gfx/render.hpp>
 #include <iostream>
+#include <memory>
+#include <vector>
 
 namespace studio {
 
+using object_ptr = std::shared_ptr<Object>;
+using frame_ptr = std::shared_ptr<Frame>;
+using obj_control_ptr = std::shared_ptr<ObjectController>;
+using shader_ptr = std::shared_ptr<Shader>;
+
 struct Simulator : public osi::Simulator
 {
     Simulator();
@@ -35,15 +42,18 @@ struct Simulator : public osi::Simulator
 
     private:    
     Camera camera;
-    Object object; // TO DO: vector of objects
+    // Object object; // TO DO: vector of objects
+    std::vector<object_ptr> objects;
 
     Frame cam_frame;
-    Frame obj_frame;
+    // Frame obj_frame;
+    std::vector<frame_ptr> obj_frames;
 
     CameraController cam_control;
-    ObjectController obj_control;
+    // ObjectController obj_control;
+    std::vector<obj_control_ptr> obj_controls;
 
-    Shader myShader;
+    std::vector<shader_ptr> myShaders;
 };
 
 }
diff --git a/src/studio/src/simulator.cpp b/src/studio/src/simulator.cpp
index 3207ddd..f74a079 100644
--- a/src/studio/src/simulator.cpp
+++ b/src/studio/src/simulator.cpp
@@ -95,10 +95,13 @@ std::vector<float> getnormals(std::vector<unsigned int> &indices, std::vector<fl
 Simulator::Simulator()
     : osi::Simulator()
     // camera frame, object frame, camera, object
-    , myShader{"./data/shaders/lightshader.vert",
-               "./data/shaders/lightshader.frag"}
+    , myShaders{std::make_shared<Shader>("./data/shaders/lightshader.vert",
+                                         "./data/shaders/lightshader.frag"),
+                std::make_shared<Shader>("./data/shaders/basicshader.vert",
+                                         "./data/shaders/basicshader.frag")}
     , camera{60.0f}
-    , object{lit_cube_vertices, lit_cube_indices, lit_cube_normals}
+    , objects{std::make_shared<Object>(lit_cube_vertices, lit_cube_indices, lit_cube_normals),
+              std::make_shared<Object>(lit_cube_vertices, lit_cube_indices, lit_cube_normals, glm::vec3(1.0f, 1.0f, 1.0f))}
     // , object{{
     //           0, 0, 0,       1, -0.2f, 0,       1, 0.2f, 0,
     //           0, 0, 0,   -0.2f,     2, 0,    0.2f,    2, 0,
@@ -115,11 +118,14 @@ Simulator::Simulator()
     //             0, 1,  0,   0, 1,  0,     0, 1,  0
     //          }
     //         }
-    , cam_frame{{0.0f, 0.0f, 3.0f}, {0.0f, -90.0f, 0.0f}} // Setting camera rotation currently does nothing
-    , obj_frame{{ 0.0f, 0.0f, 0.0f }}
+    , cam_frame{{0.0f, 1.0f, 6.0f}, {0.0f, -90.0f, 0.0f}} // Setting camera rotation currently does nothing
+    , obj_frames{std::make_shared<Frame>(glm::vec3(0.0f, 0.0f, 0.0f )),
+                 std::make_shared<Frame>(glm::vec3(1.2f, 2.0f, 2.0f ))}
     , cam_control{cam_frame}
-    , obj_control{obj_frame}
+    , obj_controls{std::make_shared<ObjectController>(*obj_frames[0]),
+                   std::make_shared<ObjectController>(*obj_frames[1])}
 {
+    objects[1]->setToLight(true);
     camera.setWindowSize(window().size()); 
     //obj_control.rotate(glm::vec3(0.0f, 50.0f, 0.0f));
 }
@@ -149,9 +155,10 @@ void Simulator::present()
         camera.setWindowSize(window().size());
     }
     
-    gfx_draw(myShader, camera, object, cam_frame, obj_frame, cam_control, obj_control);
+    gfx_draw(myShaders, camera, objects, cam_frame, obj_frames, cam_control, obj_controls);
 }
 
+// Object movement now works only for the first input object
 void Simulator::process_input()
 {
     if (!window().has_keyboard_focus())
@@ -159,8 +166,8 @@ void Simulator::process_input()
 
     if (keyboard().down().contains("O"))
     {
-        obj_control.setStep(timer().dt());
-        obj_control.move(keyboard().down());
+        obj_controls[0]->setStep(timer().dt());
+        obj_controls[0]->move(keyboard().down());
     }
     else
     {
-- 
GitLab