multi layered pudding vertices

This commit is contained in:
frank 2021-08-07 01:05:55 -04:00
parent 8444f3aa16
commit 00f64b4bf9
5 changed files with 95 additions and 78 deletions

@ -1 +1 @@
Subproject commit 14759a1c79096f0c84ba1b48b7cb794b1c51f439
Subproject commit fe3e0bf27f8ab45edcb322ab89bc79a6fe15d8bf

View File

@ -33,90 +33,98 @@ Pudding::Pudding()
/* initialize a zbar image scanner for reading barcodes of any format */
image_scanner.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1);
/* set up pudding model */
const std::vector<glm::vec2> pudding_top_2d = sfw::get_points_on_circle(24);
const std::vector<glm::vec2> pudding_base_2d = sfw::get_points_on_circle(24, 1.6f);
float pudding_y = 0.6f;
set_pudding_model(pudding_top_2d, pudding_base_2d, pudding_y);
set_pudding_model(1.0f, 1.6f, 12, 5, -.6, .6, .25);
/* use gl context so we can draw 3D */
load_gl_context();
initialize_camera();
}
/* Fill the member variables that store pudding properties. Fill the vertices vector with 3D vertices of a pudding that can be drawn as
* GL_TRIANGLES, and fill the colors vector with RGB color values that will be passed to the fragment shader for coloring the faces of
* the pudding. */
void Pudding::set_pudding_model(const std::vector<glm::vec2>& top_2d, const std::vector<glm::vec2>& base_2d, float y)
void Pudding::set_pudding_model(
float top_radius, float base_radius, int ring_vertex_count, int layer_count, float min_y, float max_y, float gradient_position)
{
/* start and end points of edge on a face */
glm::vec2 start, end;
size_t ii;
pudding_colors.reserve(4 * 3 * top_2d.size());
/* use brown for the entire top and base */
// std::fill_n(pudding_colors.begin(), 4 * 3 * top_2d.size(), PUDDING_BROWN);
/* go through top and base points separately */
for (const std::vector<glm::vec2>& face : {top_2d, base_2d})
const glm::vec3 *layer_top_color, *layer_bottom_color;
const glm::vec2 *start_vertex, *end_vertex;
float layer_top_y, layer_top_percent, layer_base_y, layer_base_percent;
std::vector<glm::vec2> layer_top_ring, layer_base_ring;
layer_top_ring.reserve(ring_vertex_count);
layer_base_ring.reserve(ring_vertex_count);
/* y coordinates of each ring of vertices in the pudding */
const std::map<float, float> y_coords = sfw::range_percent_count(max_y, min_y, layer_count + 1);
/* loop through layers by looking at each layer's top and bottom rings simultaneously */
for (
auto layer_top_entry = y_coords.begin(), layer_base_entry = ++y_coords.begin();
layer_base_entry != y_coords.end();
layer_top_entry++, layer_base_entry++
)
{
layer_top_y = layer_top_entry->second;
layer_top_percent = layer_top_entry->first;
layer_base_y = layer_base_entry->second;
layer_base_percent = layer_base_entry->first;
layer_top_ring.clear();
layer_base_ring.clear();
sfw::points_on_circle(layer_top_ring, ring_vertex_count, layer_top_percent * (base_radius - top_radius) + top_radius);
sfw::points_on_circle(layer_base_ring, ring_vertex_count, layer_base_percent * (base_radius - top_radius) + top_radius);
/* layers above gradient position are brown, layers below are yellow, and the layer that contains gradient positon
* is a gradient from brown to yellow */
if (layer_top_percent <= gradient_position && layer_base_percent >= gradient_position)
{
layer_top_color = &PUDDING_BROWN;
layer_bottom_color = &PUDDING_YELLOW;
}
else if (layer_top_percent <= gradient_position)
{
layer_top_color = &PUDDING_BROWN;
layer_bottom_color = &PUDDING_BROWN;
}
else
{
layer_top_color = &PUDDING_YELLOW;
layer_bottom_color = &PUDDING_YELLOW;
}
/* go through top and base ring vertices simultaneously to build side triangles */
for (ii = 0; ii < layer_top_ring.size(); ii++)
{
/* 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_vertices.push_back({start_vertex->x, layer_top_y, start_vertex->y});
pudding_vertices.push_back({end_vertex->x, layer_top_y, end_vertex->y});
pudding_colors.insert(pudding_colors.end(), 2, *layer_top_color);
pudding_vertices.push_back({layer_base_ring[ii].x, layer_base_y, layer_base_ring[ii].y});
pudding_colors.push_back(*layer_bottom_color);
/* triangle that includes bottom two vertices and second top vertex */
start_vertex = &layer_base_ring[ii];
pudding_vertices.push_back({start_vertex->x, layer_base_y, start_vertex->y});
pudding_colors.push_back(*layer_bottom_color);
pudding_vertices.push_back({end_vertex->x, layer_top_y, end_vertex->y});
pudding_colors.push_back(*layer_top_color);
end_vertex = &layer_base_ring[(ii + 1) % layer_base_ring.size()];
pudding_vertices.push_back({end_vertex->x, layer_base_y, end_vertex->y});
pudding_colors.push_back(*layer_bottom_color);
}
}
layer_top_ring.clear();
sfw::points_on_circle(layer_top_ring, ring_vertex_count, top_radius);
float y = max_y;
const glm::vec3* face_color = &PUDDING_BROWN;
for (const std::vector<glm::vec2>& face : {layer_top_ring, layer_base_ring})
{
/* loop through points on the face */
for (ii = 0; ii < face.size(); ii++)
{
start = face[ii];
end = face[(ii + 1) % face.size()];
start_vertex = &face[ii];
end_vertex = &face[(ii + 1) % face.size()];
/* triangle from the center of the face to the edge */
pudding_vertices.push_back({start.x, y, start.y});
pudding_vertices.push_back({end.x, y, end.y});
pudding_vertices.push_back({start_vertex->x, y, start_vertex->y});
pudding_vertices.push_back({end_vertex->x, y, end_vertex->y});
pudding_vertices.push_back({0, y, 0});
pudding_colors.push_back(PUDDING_BROWN);
pudding_colors.push_back(PUDDING_BROWN);
pudding_colors.push_back(PUDDING_BROWN);
}
y *= -1;
}
/* go through top and base points simultaneously to build side triangles */
for (ii = 0; ii < top_2d.size(); ii++)
{
/* triangle using top edge */
start = top_2d[ii];
end = top_2d[(ii + 1) % top_2d.size()];
pudding_vertices.push_back({start.x, y, start.y});
pudding_vertices.push_back({end.x, y, end.y});
// std::fill_n(pudding_colors.begin(), 2, PUDDING_BROWN);
pudding_colors.push_back(PUDDING_BROWN);
pudding_colors.push_back(PUDDING_BROWN);
pudding_vertices.push_back({base_2d[ii].x, -y, base_2d[ii].y});
pudding_colors.push_back(PUDDING_YELLOW);
/* triangle using bottom edge */
start = base_2d[ii];
pudding_vertices.push_back({start.x, -y, start.y});
pudding_colors.push_back(PUDDING_YELLOW);
pudding_vertices.push_back({end.x, y, end.y});
pudding_colors.push_back(PUDDING_BROWN);
end = base_2d[(ii + 1) % base_2d.size()];
pudding_vertices.push_back({end.x, -y, end.y});
pudding_colors.push_back(PUDDING_YELLOW);
}
}
/* Fill the member variable that stores pudding wireframe vertices with 3D vertices of a pudding that can
* be drawn as GL_LINE to display as wireframe */
void Pudding::set_wireframe_pudding_vertices(const std::vector<glm::vec2>& top_2d, const std::vector<glm::vec2>& base_2d, float y)
{
glm::vec2 start, end;
size_t ii;
for (const std::vector<glm::vec2>& face : {top_2d, base_2d})
{
for (ii = 0; ii < face.size(); ii++)
{
start = face[ii];
end = face[(ii + 1) % face.size()];
wireframe_pudding_vertices.push_back({start.x, y, start.y});
wireframe_pudding_vertices.push_back({end.x, y, end.y});
}
y *= -1;
}
for (ii = 0; ii < top_2d.size(); ii++)
{
wireframe_pudding_vertices.push_back({top_2d[ii].x, y, top_2d[ii].y});
wireframe_pudding_vertices.push_back({base_2d[ii].x, -y, base_2d[ii].y});
/* single color for the entire face */
pudding_colors.insert(pudding_colors.end(), 3 * face.size(), *face_color);
y = min_y;
face_color = &PUDDING_YELLOW;
}
}
@ -590,7 +598,6 @@ void Pudding::update()
message << "read new barcode from config " << current_barcode;
log(message.str());
}
/* viewport box will be used to tell GL where to draw */
Box viewport_box = get_window_box();
/* shrink viewport if item texture or camera will be displayed */
@ -599,14 +606,14 @@ void Pudding::update()
viewport_box.set_right(get_window_box().get_center_x(), true);
}
glViewport(viewport_box.get_x(), viewport_box.get_y(), viewport_box.get_w(), viewport_box.get_h());
glClearColor(0, 1.0f, 0, 1.0f);
glClearColor(1.0, 0.5, 0.8, 1.0f);
glDisable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* draw pudding model using MVP shader */
glUseProgram(mvp_program);
/* calculate the transformation matrix for displaying pudding in viewport */
model = glm::rotate(model, weight(get_configuration()["pudding"]["rotation-speed"].get<float>()), Y_UNIT_NORMAL_3D);
projection = glm::perspective(glm::radians(37.0f), viewport_box.aspect(), 0.1f, 100.0f);
projection = glm::perspective(glm::radians(45.0f), viewport_box.aspect(), 0.1f, 100.0f);
mvp = projection * VIEW_MATRIX * model;
/* pass the mvp matrix to the shader */
glUniformMatrix4fv(mvp_id, 1, GL_FALSE, &mvp[0][0]);

View File

@ -37,7 +37,7 @@ private:
const std::string GIANTBOMB_API_URL = "https://www.giantbomb.com/api/release/?api_key=";
const glm::vec3 ZERO_VECTOR_3D = glm::vec3(0, 0, 0);
const glm::vec3 Y_UNIT_NORMAL_3D = glm::vec3(0, 1, 0);
const glm::mat4 VIEW_MATRIX = glm::lookAt(glm::vec3(4, 3, 3), ZERO_VECTOR_3D, Y_UNIT_NORMAL_3D);
const glm::mat4 VIEW_MATRIX = glm::lookAt(glm::vec3(4, 2, 1), glm::vec3(0, -0.325, 0), Y_UNIT_NORMAL_3D);
const glm::vec3 PUDDING_BROWN = glm::vec3(0.713f, 0.359f, 0.224f);
const glm::vec3 PUDDING_YELLOW = glm::vec3(0.878f, 0.859f, 0.122f);
std::string current_barcode, previous_barcode, current_config_barcode, current_camera_barcode;
@ -48,10 +48,9 @@ private:
zbar::ImageScanner image_scanner;
GLuint vbo, flat_program, mvp_program, video_capture_texture_id, mvp_id;
glm::mat4 projection, model = glm::mat4(1.0f), mvp;
std::vector<glm::vec3> wireframe_pudding_vertices, pudding_vertices, pudding_colors;
std::vector<glm::vec3> pudding_vertices, pudding_colors;
void set_pudding_model(const std::vector<glm::vec2>&, const std::vector<glm::vec2>&, float y);
void set_wireframe_pudding_vertices(const std::vector<glm::vec2>&, const std::vector<glm::vec2>&, float y);
void set_pudding_model(float, float, int, int = 1, float = -1, float = 1, float = 0.3f);
void load_gl_context();
void initialize_camera();
void incorporate_open_food_api(Item&);

9
src/mvp.frag Normal file
View File

@ -0,0 +1,9 @@
#version 130
in vec3 ex_Color;
in float x;
void main(void)
{
gl_FragColor = vec4(ex_Color * x, 1);
}

View File

@ -4,9 +4,11 @@ in vec3 in_Position;
in vec3 in_Color;
uniform mat4 MVP;
out vec3 ex_Color;
out float x;
void main(void)
{
gl_Position = MVP * vec4(in_Position, 1);
ex_Color = in_Color;
x = 1.8 - abs(in_Position[0]);
}