Parcourir la source

Start writing code for material.

Sam Jaffe il y a 6 ans
Parent
commit
c51715264d

+ 16 - 2
graphics/include/game/graphics/material.hpp

@@ -7,16 +7,30 @@
 
 #pragma once
 
-#include "game/util/identity.hpp"
+#include <vector>
 
+#include "game/util/identity.hpp"
 #include "shader_program.hpp"
 
 namespace graphics {
+  class texture;
   class material : public identity<material> {
+  public:
+    struct uniform {
+      flyweight<texture> texture;
+      int uniform_id; // TODO (sjaffe): use an enum and hide remapping?
+    };
+
   public:
     shader_program const shaders;
+    std::vector<uniform> uniforms;
+
+  public:
+    static flyweight<material> create(shader_program const & sp,
+                                      std::string const & texture,
+                                      std::string const & uniform);
 
   private:
-    material(unsigned int, shader_program);
+    material(unsigned int, shader_program const &);
   };
 }

+ 1 - 0
graphics/src/helper.hpp

@@ -27,6 +27,7 @@ namespace graphics {
     unsigned int init(flyweight<shader> const & fragmentShader,
                       flyweight<shader> const & vertexShader);
     void activate(unsigned int id);
+    int uniform_location(unsigned int id, std::string const & uniform);
   }
 }
 

+ 42 - 0
graphics/src/material.cpp

@@ -6,3 +6,45 @@
 //
 
 #include "game/graphics/material.hpp"
+
+#include "game/graphics/texture.hpp"
+#include "helper.hpp"
+
+using namespace graphics;
+
+namespace {
+  using key_t = std::pair<shaders::type, std::string>;
+  std::unordered_map<std::string, material> g_materials;
+}
+
+flyweight<texture> get_texture(std::string const & texture,
+                               std::string const & uniform) {
+  if (!texture.empty()) {
+    try {
+      return texture::create(texture);
+    } catch (std::exception const & e) {
+      // TODO: Logging
+    }
+  }
+  if (uniform == "u_normalMap") {
+    return texture::LIGHT_BLUE;
+  } else if (uniform == "u_specularMap") {
+    return texture::DARK_YELLOW;
+  } else if (uniform == "u_diffuseMap") {
+    return texture::WHITE;
+  }
+  throw;
+}
+
+flyweight<material> material::create(shader_program const & sp,
+                                     std::string const & texture,
+                                     std::string const & uniform) {
+  static unsigned int id{0};
+  material mat{++id, sp};
+  mat.uniforms.push_back({get_texture(texture, uniform),
+                          shaders::uniform_location(sp.id, uniform)});
+  return g_materials.emplace("", std::move(mat)).first->second;
+}
+
+material::material(unsigned int id, shader_program const & sp)
+    : identity<material>(id), shaders(sp) {}

+ 4 - 0
graphics/src/opengl_helper.cxx

@@ -331,4 +331,8 @@ namespace graphics { namespace shaders {
     // for GL_TEXTURE3, texture unit 3
     glUniform1i(emissiveMapUniformLocation, 3);
   }
+
+  int uniform_location(unsigned int id, std::string const & uniform) {
+    return glGetUniformLocation(id, uniform.c_str());
+  }
 }}