From 5374b7f76a367b3e142b9761d9535c61a0444f1c Mon Sep 17 00:00:00 2001 From: frank <420@shampoo.ooo> Date: Fri, 29 Oct 2021 01:17:05 -0400 Subject: [PATCH] pudding attributes moved into model class --- lib/sb | 2 +- src/Item.hpp | 1 + src/Model.cpp | 36 +++++++++++++++---- src/Model.hpp | 8 +++-- src/Pudding.cpp | 91 ++++++++++++++++++++++++------------------------- src/Pudding.hpp | 3 +- 6 files changed, 83 insertions(+), 58 deletions(-) diff --git a/lib/sb b/lib/sb index 70bc054..950a955 160000 --- a/lib/sb +++ b/lib/sb @@ -1 +1 @@ -Subproject commit 70bc054c7f763d1ec14c696d9c66bddefe0126bc +Subproject commit 950a95502bb178619376121ac9781ad1f2fe151e diff --git a/src/Item.hpp b/src/Item.hpp index c3b5323..f72ace8 100644 --- a/src/Item.hpp +++ b/src/Item.hpp @@ -36,6 +36,7 @@ class Item : public Node private: nlohmann::json json = {}; + // Plane image; std::vector image_textures; std::string brand_name = "", product_name = "", upc = ""; int current_image_index = 0; diff --git a/src/Model.cpp b/src/Model.cpp index 599a5a0..618ce4e 100644 --- a/src/Model.cpp +++ b/src/Model.cpp @@ -33,21 +33,45 @@ Model::Model(const std::map& attributes_pack) } } +/* Construct a new model object by passing a list of names which will be used to initialize + * empty attributes objects with the given names */ +Model::Model(const std::initializer_list& names) +{ + for (const std::string& name : names) + { + this->attributes(name, sb::Attributes()); + } +} + /* 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() +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) +/* Get the attributes under name, wrapped in the shared pointer held by this object. This + * function uses the at method of std::map, so name must refer to attributes already + * stored in this model. Use this function 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); } +/* Get the attributes under name, wrapped in the shared pointer held by this object. This + * function uses operator[] or std::map, so this can be used to add new attributes to the + * object if they are wrapped in a shared pointer. */ +std::shared_ptr& Model::operator[](const std::string& name) +{ + auto element = model_attributes.find(name); + if (element == model_attributes.end()) + { + attributes(name, sb::Attributes{}); + } + return model_attributes[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) @@ -81,7 +105,7 @@ void Model::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) +sb::Texture& Model::texture(const std::string& name) { return model_texture.at(name); } diff --git a/src/Model.hpp b/src/Model.hpp index 758da2a..25b224f 100644 --- a/src/Model.hpp +++ b/src/Model.hpp @@ -39,13 +39,15 @@ public: Model(); Model(const std::map>&); Model(const std::map&); - std::map> attributes(); - std::shared_ptr attributes(const std::string&); + Model(const std::initializer_list&); + 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&); + std::shared_ptr& operator[](const std::string&); void enable(); void disable(); - sb::Texture texture(const std::string&); + sb::Texture& texture(const std::string&); void texture(const std::string&, const sb::Texture&); void transformation(const glm::mat4&); std::size_t size(); diff --git a/src/Pudding.cpp b/src/Pudding.cpp index 6a7182c..a730048 100644 --- a/src/Pudding.cpp +++ b/src/Pudding.cpp @@ -38,6 +38,11 @@ Pudding::Pudding() /* use gl context so we can draw 3D */ load_gl_context(); load_tiles(); + Model boom; + boom["hello world"] = std::make_shared(sb::Attributes{1, 2, 3, 4, 5}); + std::cout << *boom["hello world"] << std::endl; + boom.attributes("bam", {{4.2f, 42.0f, 420.0f}, {.69f, 6.9f, 69.0f}}); + std::cout << *boom["bam"] << std::endl; } /* Assign vertices, colors and texture UV coordinates to the pudding model */ @@ -92,30 +97,30 @@ void Pudding::set_pudding_model( /* triangle that includes top two vertices and first base vertex */ start_vertex = &layer_top_ring[ii]; end_vertex = &layer_top_ring[(ii + 1) % layer_top_ring.size()]; - pudding_attributes["position"].add(start_vertex->x, layer_top_y, start_vertex->y); - pudding_attributes["uv"].add(ring_start_vertex_u, layer_top_percent); - pudding_attributes["position"].add(end_vertex->x, layer_top_y, end_vertex->y); - pudding_attributes["uv"].add(ring_start_vertex_u + u_step, layer_top_percent); - pudding_attributes["color"].extend(*layer_top_color, 2); - pudding_attributes["position"].add(layer_base_ring[ii].x, layer_base_y, layer_base_ring[ii].y); - pudding_attributes["uv"].add(ring_start_vertex_u, layer_base_percent); - pudding_attributes["color"].add(*layer_bottom_color); + pudding_model["position"]->add(start_vertex->x, layer_top_y, start_vertex->y); + pudding_model["uv"]->add(ring_start_vertex_u, layer_top_percent); + pudding_model["position"]->add(end_vertex->x, layer_top_y, end_vertex->y); + pudding_model["uv"]->add(ring_start_vertex_u + u_step, layer_top_percent); + pudding_model["color"]->extend(*layer_top_color, 2); + pudding_model["position"]->add(layer_base_ring[ii].x, layer_base_y, layer_base_ring[ii].y); + pudding_model["uv"]->add(ring_start_vertex_u, layer_base_percent); + pudding_model["color"]->add(*layer_bottom_color); /* triangle that includes bottom two vertices and second top vertex */ start_vertex = &layer_base_ring[ii]; - pudding_attributes["position"].add(start_vertex->x, layer_base_y, start_vertex->y); - pudding_attributes["uv"].add(ring_start_vertex_u, layer_base_percent); - pudding_attributes["color"].add(*layer_bottom_color); - pudding_attributes["position"].add(end_vertex->x, layer_top_y, end_vertex->y); - pudding_attributes["uv"].add(ring_start_vertex_u + u_step, layer_top_percent); - pudding_attributes["color"].add(*layer_top_color); + pudding_model["position"]->add(start_vertex->x, layer_base_y, start_vertex->y); + pudding_model["uv"]->add(ring_start_vertex_u, layer_base_percent); + pudding_model["color"]->add(*layer_bottom_color); + pudding_model["position"]->add(end_vertex->x, layer_top_y, end_vertex->y); + pudding_model["uv"]->add(ring_start_vertex_u + u_step, layer_top_percent); + pudding_model["color"]->add(*layer_top_color); end_vertex = &layer_base_ring[(ii + 1) % layer_base_ring.size()]; - pudding_attributes["position"].add(end_vertex->x, layer_base_y, end_vertex->y); - pudding_attributes["uv"].add(ring_start_vertex_u + u_step, layer_base_percent); - pudding_attributes["color"].add(*layer_bottom_color); + pudding_model["position"]->add(end_vertex->x, layer_base_y, end_vertex->y); + pudding_model["uv"]->add(ring_start_vertex_u + u_step, layer_base_percent); + pudding_model["color"]->add(*layer_bottom_color); ring_start_vertex_u += u_step; } } - pudding_triangle_vertex_count = pudding_attributes["position"].count(); + pudding_triangle_vertex_count = pudding_model["position"]->count(); /* process the top and bottom of pudding, filling each face with a triangle fan */ float y = max_y; const glm::vec3* face_color = &PUDDING_BROWN; @@ -123,8 +128,8 @@ void Pudding::set_pudding_model( for (float radius : {top_radius, base_radius}) { /* first point in a GL_TRIANGLE_FAN is the center */ - pudding_attributes["position"].add(0.0f, y, 0.0f); - pudding_attributes["uv"].add(0.0f, 0.0f); + pudding_model["position"]->add(0.0f, y, 0.0f); + pudding_model["uv"]->add(0.0f, 0.0f); layer_top_ring.clear(); sb::points_on_circle(layer_top_ring, ring_vertex_count, radius); /* loop through points on the face */ @@ -132,25 +137,22 @@ void Pudding::set_pudding_model( { start_vertex = &layer_top_ring[ii]; /* for GL_TRIANGLE_FAN we just need to add an outer vertex */ - pudding_attributes["position"].add(start_vertex->x, y, start_vertex->y); - pudding_attributes["uv"].add(*start_vertex); + pudding_model["position"]->add(start_vertex->x, y, start_vertex->y); + pudding_model["uv"]->add(*start_vertex); /* connect the ring on the last vertex */ if (ii == layer_top_ring.size() - 1) { end_vertex = &layer_top_ring[(ii + 1) % layer_top_ring.size()]; - pudding_attributes["position"].add(end_vertex->x, y, end_vertex->y); - pudding_attributes["uv"].add(*end_vertex); + pudding_model["position"]->add(end_vertex->x, y, end_vertex->y); + pudding_model["uv"]->add(*end_vertex); } } /* single color for the entire layer_top_ring */ - pudding_attributes["color"].extend(*face_color, layer_top_ring.size() + 2); + pudding_model["color"]->extend(*face_color, layer_top_ring.size() + 2); y = min_y; face_color = &PUDDING_YELLOW; } - pudding_fan_vertex_count = (pudding_attributes["position"].count() - pudding_triangle_vertex_count) / 2; - pudding_attributes["position"].index(0); - pudding_attributes["color"].index(1); - pudding_attributes["uv"].index(2); + pudding_fan_vertex_count = (pudding_model["position"]->count() - pudding_triangle_vertex_count) / 2; } /* Create GL context via super class and load vertices, UV data, and shaders */ @@ -186,18 +188,17 @@ void Pudding::load_gl_context() mvp_program = glCreateProgram(); glAttachShader(mvp_program, vertex_shader); glAttachShader(mvp_program, fragment_shader); - glBindAttribLocation(mvp_program, pudding_attributes["position"], "in_position"); - glBindAttribLocation(mvp_program, pudding_attributes["color"], "in_color"); - glBindAttribLocation(mvp_program, pudding_attributes["uv"], "vertex_uv"); + pudding_model.attributes("position")->bind(0, mvp_program, "in_position"); + pudding_model.attributes("color")->bind(1, mvp_program, "in_color"); + pudding_model.attributes("uv")->bind(2, mvp_program, "vertex_uv"); sb::Log::gl_errors("after loading shaders"); /* Fill VBO with attribute data */ - vbo.allocate(plane.size() + pudding_attributes["uv"].size() + pudding_attributes["position"].size() + - pudding_attributes["color"].size(), GL_STATIC_DRAW); + vbo.allocate(plane.size() + pudding_model.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"]); + vbo.add(*pudding_model.attributes("uv")); + vbo.add(*pudding_model.attributes("position")); + vbo.add(*pudding_model.attributes("color")); sb::Log::gl_errors("after filling VBO"); /* link shaders */ link_shader(flat_program); @@ -746,9 +747,7 @@ void Pudding::update() glUseProgram(flat_program); glUniform1f(uniform["flat"]["time"], time_seconds); /* disable pudding attributes and enable rectangle attributes */ - pudding_attributes["position"].disable(); - pudding_attributes["color"].disable(); - pudding_attributes["uv"].disable(); + pudding_model.disable(); plane.enable(); glUniform1i(uniform["flat"]["texture"], 0); glActiveTexture(GL_TEXTURE0); @@ -771,17 +770,17 @@ void Pudding::update() glUniformMatrix4fv(uniform["mvp"]["mvp"], 1, GL_FALSE, &mvp[0][0]); /* disable rectangle attributes and enable pudding attributes */ plane.disable(); - pudding_attributes["position"].enable(); + pudding_model.attributes("position")->enable(); if (items.size() == 0) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - pudding_attributes["color"].enable(); + pudding_model.attributes("color")->enable(); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - pudding_attributes["color"].enable(); - pudding_attributes["uv"].enable(); + pudding_model.attributes("color")->enable(); + pudding_model.attributes("uv")->enable(); glUniform1i(uniform["mvp"]["pudding texture"], 0); glActiveTexture(GL_TEXTURE0); current_item().get_active_image_texture().bind(); @@ -806,9 +805,7 @@ void Pudding::update() /* switch to flat shader for item and camera */ glUseProgram(flat_program); /* disable pudding attributes and enable rectangle attributes */ - glDisableVertexAttribArray(pudding_attributes["position"]); - glDisableVertexAttribArray(pudding_attributes["color"]); - glDisableVertexAttribArray(pudding_attributes["uv"]); + pudding_model.disable(); plane.enable(); glDisable(GL_DEPTH_TEST); /* just need to set these once since we're drawing one texture per viewport */ diff --git a/src/Pudding.hpp b/src/Pudding.hpp index 984ac86..dc621ed 100644 --- a/src/Pudding.hpp +++ b/src/Pudding.hpp @@ -85,8 +85,9 @@ private: std::map> uniform; GLuint flat_program, mvp_program; glm::mat4 projection, model = glm::mat4(1.0f), mvp; - std::map pudding_attributes; + Model pudding_model; Plane plane; + // Plane background, camera_frame; bool show_item = false, reading_capture_frame = false; SDL_GLContext capture_frame_thread_context = nullptr; std::vector tiles;