diff --git a/config.json b/config.json index 7eaef27..fe596c0 100644 --- a/config.json +++ b/config.json @@ -47,7 +47,7 @@ "enabled": true, "json-save": true, "json-save-directory": "local/scans", - "barcode": "014100085980", + "barcode": "", "capture-device": "/dev/video0" }, "api": diff --git a/lib/sb b/lib/sb index 3212dc1..70bc054 160000 --- a/lib/sb +++ b/lib/sb @@ -1 +1 @@ -Subproject commit 3212dc15cf15ecb9639f13b9076780ffd676ffa6 +Subproject commit 70bc054c7f763d1ec14c696d9c66bddefe0126bc diff --git a/src/Pudding.cpp b/src/Pudding.cpp index eeb1d15..7f1f111 100644 --- a/src/Pudding.cpp +++ b/src/Pudding.cpp @@ -166,24 +166,7 @@ void Pudding::load_gl_context() /* Generate a vertex array object ID, bind it as current (requirement of OpenGL) */ vao.generate(); vao.bind(); - /* 2D attributes (location and UV) for any texture that is a plane spanning the screen */ - rectangle_attributes = { - { - "position", sb::Attributes({ - {-1.0f, 1.0f}, {1.0f, 1.0f}, {-1.0f, -1.0f}, - {1.0f, 1.0f}, {1.0f, -1.0f}, {-1.0f, -1.0f} - }) - }, - { - "uv", sb::Attributes({ - {0.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}, - {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 0.0f} - }) - } - }; - rectangle_attributes["position"].index(11); - rectangle_attributes["uv"].index(12); - /* Generate one vertex buffer object to hold all vertex data. Since we're using one buffer, data + /* Generate ID for the vertex buffer object that will hold all vertex data. Since we're using one buffer, data * will be copied in one after the other, offset to after the previous data location. The same buffer offset will * be passed to the vertex attributes for each data. */ vbo.generate(); @@ -195,11 +178,11 @@ void Pudding::load_gl_context() flat_program = glCreateProgram(); glAttachShader(flat_program, vertex_shader); glAttachShader(flat_program, fragment_shader); - glBindAttribLocation(flat_program, rectangle_attributes["position"], "in_position"); - glBindAttribLocation(flat_program, rectangle_attributes["uv"], "vertex_uv"); /* load, configure and link the 3D world program */ vertex_shader = load_shader("src/mvp.vert", GL_VERTEX_SHADER); fragment_shader = load_shader("src/mvp.frag", GL_FRAGMENT_SHADER); + plane.attributes("position")->bind(12, flat_program, "in_position"); + plane.attributes("uv")->bind(13, flat_program, "vertex_uv"); mvp_program = glCreateProgram(); glAttachShader(mvp_program, vertex_shader); glAttachShader(mvp_program, fragment_shader); @@ -208,10 +191,10 @@ void Pudding::load_gl_context() glBindAttribLocation(mvp_program, pudding_attributes["uv"], "vertex_uv"); sb::Log::gl_errors("after loading shaders"); /* Fill VBO with attribute data */ - vbo.allocate(rectangle_attributes["position"].size() + rectangle_attributes["uv"].size() + pudding_attributes["uv"].size() + - pudding_attributes["position"].size() + pudding_attributes["color"].size(), GL_STATIC_DRAW); - vbo.add(rectangle_attributes["position"]); - vbo.add(rectangle_attributes["uv"]); + vbo.allocate(plane.size() + pudding_attributes["uv"].size() + pudding_attributes["position"].size() + + pudding_attributes["color"].size(), GL_STATIC_DRAW); + vbo.add(*plane.attributes("position")); + vbo.add(*plane.attributes("uv")); vbo.add(pudding_attributes["uv"]); vbo.add(pudding_attributes["position"]); vbo.add(pudding_attributes["color"]); @@ -763,11 +746,10 @@ void Pudding::update() glUseProgram(flat_program); glUniform1f(uniform["flat"]["time"], time_seconds); /* disable pudding attributes and enable rectangle attributes */ - glDisableVertexAttribArray(pudding_attributes["position"]); - glDisableVertexAttribArray(pudding_attributes["color"]); - glDisableVertexAttribArray(pudding_attributes["uv"]); - glEnableVertexAttribArray(rectangle_attributes["position"]); - glEnableVertexAttribArray(rectangle_attributes["uv"]); + pudding_attributes["position"].disable(); + pudding_attributes["color"].disable(); + pudding_attributes["uv"].disable(); + plane.enable(); glUniform1i(uniform["flat"]["texture"], 0); glActiveTexture(GL_TEXTURE0); tiles[current_tile_index].bind(); @@ -775,7 +757,7 @@ void Pudding::update() glUniform3f(uniform["flat"]["blend"], 0.0f, 0.0f, 1.0f); glUniform1i(uniform["flat"]["scroll"], true); /* draws rectangle vertices and rectangle texture using UV coords */ - glDrawArrays(GL_TRIANGLES, 0, rectangle_attributes["position"].count()); + glDrawArrays(GL_TRIANGLES, 0, plane.attributes("position")->count()); glUniform1i(uniform["flat"]["scroll"], false); /* draw pudding model using MVP shader */ glUseProgram(mvp_program); @@ -788,19 +770,18 @@ void Pudding::update() /* pass the mvp matrix to the shader */ glUniformMatrix4fv(uniform["mvp"]["mvp"], 1, GL_FALSE, &mvp[0][0]); /* disable rectangle attributes and enable pudding attributes */ - glDisableVertexAttribArray(rectangle_attributes["position"]); - glDisableVertexAttribArray(rectangle_attributes["color"]); - glEnableVertexAttribArray(pudding_attributes["position"]); + plane.disable(); + pudding_attributes["position"].enable(); if (items.size() == 0) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glEnableVertexAttribArray(pudding_attributes["color"]); + pudding_attributes["color"].enable(); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glEnableVertexAttribArray(pudding_attributes["color"]); - glEnableVertexAttribArray(pudding_attributes["uv"]); + pudding_attributes["color"].enable(); + pudding_attributes["uv"].enable(); glUniform1i(uniform["mvp"]["pudding texture"], 0); glActiveTexture(GL_TEXTURE0); current_item().get_active_image_texture().bind(); @@ -828,8 +809,7 @@ void Pudding::update() glDisableVertexAttribArray(pudding_attributes["position"]); glDisableVertexAttribArray(pudding_attributes["color"]); glDisableVertexAttribArray(pudding_attributes["uv"]); - glEnableVertexAttribArray(rectangle_attributes["position"].index()); - glEnableVertexAttribArray(rectangle_attributes["uv"].index()); + plane.enable(); glDisable(GL_DEPTH_TEST); /* just need to set these once since we're drawing one texture per viewport */ glUniform1i(uniform["flat"]["texture"], 0); @@ -850,7 +830,7 @@ void Pudding::update() glViewport(viewport_box.left(), viewport_box.bottom(), viewport_box.width(), viewport_box.height()); current_item().get_active_image_texture().bind(); /* draws rectangle vertices and rectangle texture using UV coords */ - glDrawArrays(GL_TRIANGLES, 0, rectangle_attributes["position"].count()); + glDrawArrays(GL_TRIANGLES, 0, plane.attributes("position")->count()); } /* draw the camera if the camera has been opened */ if (capture.isOpened()) @@ -860,7 +840,7 @@ void Pudding::update() /* bind texture for drawing */ capture_texture.bind(); /* draws rectangle vertices and rectangle texture using UV coords */ - glDrawArrays(GL_TRIANGLES, 0, rectangle_attributes["position"].count()); + glDrawArrays(GL_TRIANGLES, 0, plane.attributes("position")->count()); } } SDL_GL_SwapWindow(get_window()); @@ -872,3 +852,104 @@ void Pudding::update() previous_barcode = current_barcode; } } + +/* Default constructor for Model */ +Model::Model() {}; + +Model::Model(const std::map>& attributes_pack) +{ + for (auto attributes : attributes_pack) + { + this->attributes(attributes.first, attributes.second); + } +} + +Model::Model(const std::map& attributes_pack) +{ + for (auto attributes : attributes_pack) + { + this->attributes(attributes.first, attributes.second); + } +} + +/* Get the entire map of attributes, each wrapped in its shared pointer held by this object. + * Can be used to iterate through the attributes. */ +std::map> Model::attributes() +{ + return model_attributes; +} + +/* Get the attributes under name, wrapped in the shared pointer held by this object. Use + * this to share ownership of the attributes or to gain access to the public interface + * of the attributes. */ +std::shared_ptr Model::attributes(const std::string& name) +{ + return model_attributes.at(name); +} + +/* Assign name to attributes, copy and wrap in a shared pointer. The model can share + * ownership of the created attribute memory with callers that request it. */ +void Model::attributes(const std::string& name, const sb::Attributes& attributes) +{ + this->attributes(name, std::make_shared(attributes)); +} + +/* Assign name to attributes and share ownership. */ +void Model::attributes(const std::string& name, const std::shared_ptr& attributes) +{ + model_attributes[name] = attributes; +} + +/* Enable all attributes. */ +void Model::enable() +{ + for (const auto& attributes : this->attributes()) + { + attributes.second->enable(); + } +} + +/* Disable all attributes. */ +void Model::disable() +{ + for (const auto& attributes : this->attributes()) + { + attributes.second->disable(); + } +} + +/* Get the texture at name. This can be used to read the texture memory, share ownership of it, or + * anything else a Texture object can be used for with direct calls to GL functions. */ +sb::Texture Model::texture(const std::string& name) +{ + return model_texture.at(name); +} + +/* Assign name to texture and share ownership. */ +void Model::texture(const std::string& name, const sb::Texture& texture) +{ + model_texture[name] = texture; +} + +/* Set the transformation matrix. */ +void Model::transformation(const glm::mat4& transformation) +{ + model_transformation = transformation; +} + +/* Return the size in bytes of the sum of the attributes. */ +std::size_t Model::size() +{ + std::size_t sum = 0; + for (const auto& attributes : this->attributes()) + { + sum += attributes.second->size(); + } + return sum; +} + +/* Return the transformation matrix. */ +Model::operator glm::mat4() const +{ + return model_transformation; +} diff --git a/src/Pudding.hpp b/src/Pudding.hpp index 3069eb8..b8b9f4d 100644 --- a/src/Pudding.hpp +++ b/src/Pudding.hpp @@ -40,6 +40,54 @@ #include "Attributes.hpp" #include "VBO.hpp" +class Model +{ + +private: + + std::map> model_attributes; + std::map model_texture; + glm::mat4 model_transformation = glm::mat4(1); + +public: + + Model(); + Model(const std::map>&); + Model(const std::map&); + std::map> attributes(); + std::shared_ptr attributes(const std::string&); + void attributes(const std::string&, const sb::Attributes&); + void attributes(const std::string&, const std::shared_ptr&); + void enable(); + void disable(); + sb::Texture texture(const std::string&); + void texture(const std::string&, const sb::Texture&); + void transformation(const glm::mat4&); + std::size_t size(); + operator glm::mat4() const; + +}; + +class Plane : public Model +{ + +public: + + inline const static std::shared_ptr position = std::make_shared(sb::Attributes{ + {-1.0f, 1.0f}, {1.0f, 1.0f}, {-1.0f, -1.0f}, + {1.0f, 1.0f}, {1.0f, -1.0f}, {-1.0f, -1.0f} + }); + inline const static std::shared_ptr uv = std::make_shared(sb::Attributes{ + {0.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}, + {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 0.0f} + }); + +public: + + Plane() : Model(std::map>({{"position", position}, {"uv", uv}})) {} + +}; + class Pudding : public Game { @@ -84,7 +132,8 @@ private: std::map> uniform; GLuint flat_program, mvp_program; glm::mat4 projection, model = glm::mat4(1.0f), mvp; - std::map rectangle_attributes, pudding_attributes; + std::map pudding_attributes; + Plane plane; bool show_item = false, reading_capture_frame = false; SDL_GLContext capture_frame_thread_context = nullptr; std::vector tiles; @@ -122,21 +171,15 @@ public: }; -class Model -{ - -private: - - std::map attributes; - -}; - -class Plane : public Model -{ -}; - /* Apply force until reaching a threshold. Use a connection object to run user functions - * when force reaches threshold and when force goes below threshold. */ + * when force reaches threshold and when force goes below threshold. + * + * - shares single Plane (vertices in VBO and UV in VBO) + * - each has different Texture + * - each has different response to click + * - shares collision with mouse code + * - each has different position +*/ class Button { /* threshold */