diff --git a/src/executable.cpp b/src/executable.cpp index 39a5edb..6b3d753 100644 --- a/src/executable.cpp +++ b/src/executable.cpp @@ -25,7 +25,10 @@ void Executable::use() const glUseProgram(id); } -GLuint Executable::get_uniform_location(const GLchar *name) const +void Executable::get_uniforms(unsigned count, const GLchar *const names[]) { - return glGetUniformLocation(id, name); + uniforms.resize(count); + + for (unsigned index = 0; index < count; ++index) + uniforms[index] = glGetUniformLocation(id, names[index]); } diff --git a/src/executable.hpp b/src/executable.hpp index 03831df..b33ec73 100644 --- a/src/executable.hpp +++ b/src/executable.hpp @@ -4,11 +4,13 @@ #include "gl.hpp" #include "shader.hpp" +#include + struct Executable { void use() const; - GLuint get_uniform_location(const GLchar *name) const; + inline GLuint uniform(unsigned index) const; private: friend struct Program; @@ -18,7 +20,16 @@ private: void bind_attrib_location(GLuint index, const GLchar *name); void link(); + void get_uniforms(unsigned count, const GLchar *const names[]); + GLuint id; + + std::vector uniforms; }; +GLuint Executable::uniform(unsigned index) const +{ + return uniforms.at(index); +} + #endif // _EXECUTABLE_HPP_ diff --git a/src/gl.hpp b/src/gl.hpp index 4c3f762..2473553 100644 --- a/src/gl.hpp +++ b/src/gl.hpp @@ -10,7 +10,7 @@ enum Attrib : GLuint normal, tex_coord, - __count + __attrib_count }; static const GLchar *const attribs[] = { @@ -19,7 +19,17 @@ static const GLchar *const attribs[] = { "tex_coord", }; -extern GLuint mvp_uniform; -extern GLuint local_modelview_uniform; +enum Uniform : unsigned +{ + mvp, + local_modelview, + + __uniform_count +}; + +static const GLchar *const uniforms[] = { + "mvp", + "local_modelview", +}; #endif // _GL_HPP_ diff --git a/src/main.cpp b/src/main.cpp index c12e6b3..4ad4c60 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,3 +1,5 @@ +#include "main.hpp" + #include "gl.hpp" #include "program.hpp" #include "scene.hpp" @@ -14,6 +16,8 @@ #include #include +const Executable *exe; + static Store store; static void iterate(); @@ -21,9 +25,6 @@ static void iterate(); static GLFWCALL void on_key(int key, int action); static EM_BOOL on_em_mousemove(int event_type, const EmscriptenMouseEvent *mouse_event, void *user_data); -GLuint mvp_uniform; -GLuint local_modelview_uniform; - static bool keys[GLFW_KEY_LAST]; static Scene scene; @@ -72,10 +73,10 @@ int main() glfwSetKeyCallback(on_key); emscripten_set_mousemove_callback(nullptr, nullptr, false, on_em_mousemove); - const Executable *exe = Program("textured").build(__count, attribs); - - mvp_uniform = exe->get_uniform_location("mvp"); - local_modelview_uniform = exe->get_uniform_location("local_modelview"); + exe = Program("textured").build( + __attrib_count, attribs, + __uniform_count, uniforms + ); exe->use(); diff --git a/src/main.hpp b/src/main.hpp new file mode 100644 index 0000000..f25cda0 --- /dev/null +++ b/src/main.hpp @@ -0,0 +1,8 @@ +#ifndef _MAIN_HPP_ +#define _MAIN_HPP_ + +#include "executable.hpp" + +extern const Executable *exe; + +#endif // _MAIN_HPP_ diff --git a/src/model/raw.cpp b/src/model/raw.cpp index 175eae1..8068154 100644 --- a/src/model/raw.cpp +++ b/src/model/raw.cpp @@ -1,5 +1,7 @@ #include "raw.hpp" +#include "../main.hpp" + #include #include @@ -39,10 +41,10 @@ Raw::Raw(__attribute__((unused)) Store &store, const std::string &name) void Raw::draw(const glm::mat4 &mvp, const glm::mat4 &transformation) const { const glm::mat4 transform = mvp * transformation; - glUniformMatrix4fv(mvp_uniform, 1, GL_FALSE, glm::value_ptr(transform)); + glUniformMatrix4fv(exe->uniform(Uniform::mvp), 1, GL_FALSE, glm::value_ptr(transform)); const glm::mat3 local_modelview = glm::transpose(glm::inverse(glm::mat3(transformation))); - glUniformMatrix3fv(local_modelview_uniform, 1, GL_FALSE, glm::value_ptr(local_modelview)); + glUniformMatrix3fv(exe->uniform(Uniform::local_modelview), 1, GL_FALSE, glm::value_ptr(local_modelview)); glEnableVertexAttribArray(position); glBindBuffer(GL_ARRAY_BUFFER, positions_id); diff --git a/src/model/static.cpp b/src/model/static.cpp index 1775833..9784ad2 100644 --- a/src/model/static.cpp +++ b/src/model/static.cpp @@ -1,5 +1,7 @@ #include "static.hpp" +#include "../main.hpp" + #include "../mtllib.hpp" #include @@ -109,10 +111,10 @@ Static::Static(Store &store, const std::string &name) void Static::draw(const glm::mat4 &mvp, const glm::mat4 &transformation) const { const glm::mat4 transform = mvp * transformation; - glUniformMatrix4fv(mvp_uniform, 1, GL_FALSE, glm::value_ptr(transform)); + glUniformMatrix4fv(exe->uniform(Uniform::mvp), 1, GL_FALSE, glm::value_ptr(transform)); const glm::mat3 local_modelview = glm::transpose(glm::inverse(glm::mat3(transformation))); - glUniformMatrix3fv(local_modelview_uniform, 1, GL_FALSE, glm::value_ptr(local_modelview)); + glUniformMatrix3fv(exe->uniform(Uniform::local_modelview), 1, GL_FALSE, glm::value_ptr(local_modelview)); _material->use(); diff --git a/src/program.cpp b/src/program.cpp index b904bab..241d9cf 100644 --- a/src/program.cpp +++ b/src/program.cpp @@ -14,17 +14,21 @@ Program::Program(const std::string &name): fragment_shader(GL_FRAGMENT_SHADER, filename(name) + "/fragment.glsl") {} -const Executable *Program::build(GLuint count, const GLchar *const names[]) +const Executable *Program::build( + GLuint attrib_count, const GLchar *const attribs[], + unsigned uniform_count, const GLchar *const uniforms[]) { Executable *exe = new Executable(); exe->attach_shader(vertex_shader); exe->attach_shader(fragment_shader); - for (GLuint index = 0; index < count; ++index) - exe->bind_attrib_location(index, names[index]); + for (GLuint attrib = 0; attrib < attrib_count; ++attrib) + exe->bind_attrib_location(attrib, attribs[attrib]); exe->link(); + exe->get_uniforms(uniform_count, uniforms); + return exe; } diff --git a/src/program.hpp b/src/program.hpp index 806c2bc..d1f6d77 100644 --- a/src/program.hpp +++ b/src/program.hpp @@ -9,7 +9,9 @@ struct Program { Program(const std::string &name); - const Executable *build(GLuint count, const GLchar *const names[]); + const Executable *build( + GLuint attrib_count, const GLchar *const attribs[], + unsigned uniform_count, const GLchar *const uniforms[]); private: static const std::string filename(const std::string &name);