pudding attributes moved into model class

This commit is contained in:
frank 2021-10-29 01:17:05 -04:00
parent 67a7f9c3f2
commit 5374b7f76a
6 changed files with 83 additions and 58 deletions

2
lib/sb

@ -1 +1 @@
Subproject commit 70bc054c7f763d1ec14c696d9c66bddefe0126bc
Subproject commit 950a95502bb178619376121ac9781ad1f2fe151e

View File

@ -36,6 +36,7 @@ class Item : public Node
private:
nlohmann::json json = {};
// Plane image;
std::vector<sb::Texture> image_textures;
std::string brand_name = "", product_name = "", upc = "";
int current_image_index = 0;

View File

@ -33,21 +33,45 @@ Model::Model(const std::map<std::string, sb::Attributes>& 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<std::string>& 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<std::string, std::shared_ptr<sb::Attributes>> Model::attributes()
std::map<std::string, std::shared_ptr<sb::Attributes>>& 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<sb::Attributes> 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<sb::Attributes>& 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<sb::Attributes>& 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);
}

View File

@ -39,13 +39,15 @@ public:
Model();
Model(const std::map<std::string, std::shared_ptr<sb::Attributes>>&);
Model(const std::map<std::string, sb::Attributes>&);
std::map<std::string, std::shared_ptr<sb::Attributes>> attributes();
std::shared_ptr<sb::Attributes> attributes(const std::string&);
Model(const std::initializer_list<std::string>&);
std::map<std::string, std::shared_ptr<sb::Attributes>>& attributes();
std::shared_ptr<sb::Attributes>& attributes(const std::string&);
void attributes(const std::string&, const sb::Attributes&);
void attributes(const std::string&, const std::shared_ptr<sb::Attributes>&);
std::shared_ptr<sb::Attributes>& 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();

View File

@ -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>(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 */

View File

@ -85,8 +85,9 @@ private:
std::map<std::string, std::map<std::string, GLuint>> uniform;
GLuint flat_program, mvp_program;
glm::mat4 projection, model = glm::mat4(1.0f), mvp;
std::map<std::string, sb::Attributes> 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<sb::Texture> tiles;