pad class with example that runs camera toggle on click
This commit is contained in:
parent
c9868db346
commit
80aebaf8de
|
@ -5,7 +5,8 @@
|
|||
"framerate": 60,
|
||||
"title": "Pudding",
|
||||
"debug": false,
|
||||
"render driver": "opengl"
|
||||
"render driver": "opengl",
|
||||
"show-cursor": true
|
||||
},
|
||||
"configuration":
|
||||
{
|
||||
|
|
2
lib/sb
2
lib/sb
|
@ -1 +1 @@
|
|||
Subproject commit 863db5467bfc625df916ac9a04e9d14aa13d7e55
|
||||
Subproject commit 03d179eed4c8323576157f806806b214e42d07c7
|
|
@ -79,21 +79,20 @@ void Item::texture(sb::Texture& texture, const std::string& name)
|
|||
|
||||
sb::Texture& Item::current_texture()
|
||||
{
|
||||
// return image.texture().begin()->second;
|
||||
return carousel.current(image.texture())->second;
|
||||
return carousel.current(image.textures())->second;
|
||||
}
|
||||
|
||||
void Item::next_texture()
|
||||
{
|
||||
carousel.next(image.texture());
|
||||
carousel.next(image.textures());
|
||||
}
|
||||
|
||||
void Item::previous_texture()
|
||||
{
|
||||
carousel.previous(image.texture());
|
||||
carousel.previous(image.textures());
|
||||
}
|
||||
|
||||
std::size_t Item::texture_count()
|
||||
{
|
||||
return image.texture().size();
|
||||
return image.textures().size();
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ std::map<std::string, std::shared_ptr<sb::Attributes>>& Model::attributes()
|
|||
* access to the public interface of the attributes. */
|
||||
std::shared_ptr<sb::Attributes>& Model::attributes(const std::string& name)
|
||||
{
|
||||
return model_attributes.at(name);
|
||||
return attributes().at(name);
|
||||
}
|
||||
|
||||
/* Get the attributes under name, wrapped in the shared pointer held by this object. This
|
||||
|
@ -64,12 +64,13 @@ std::shared_ptr<sb::Attributes>& Model::attributes(const std::string& name)
|
|||
* 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())
|
||||
auto element = attributes().find(name);
|
||||
/* add an empty Attributes at name if it doesn't exist yet */
|
||||
if (element == attributes().end())
|
||||
{
|
||||
attributes(sb::Attributes{}, name);
|
||||
}
|
||||
return model_attributes[name];
|
||||
return attributes()[name];
|
||||
}
|
||||
|
||||
/* Assign name to attributes, copy and wrap in a shared pointer. The model can share
|
||||
|
@ -82,7 +83,7 @@ void Model::attributes(const sb::Attributes& attributes, const std::string& name
|
|||
/* Assign name to attributes and share ownership. */
|
||||
void Model::attributes(const std::shared_ptr<sb::Attributes>& attributes, const std::string& name)
|
||||
{
|
||||
model_attributes[name] = attributes;
|
||||
this->attributes()[name] = attributes;
|
||||
}
|
||||
|
||||
/* Enable all attributes. */
|
||||
|
@ -104,26 +105,46 @@ void Model::disable()
|
|||
}
|
||||
|
||||
/* Return a reference to the texture container. */
|
||||
std::map<std::string, sb::Texture>& Model::texture()
|
||||
std::map<std::string, sb::Texture>& Model::textures()
|
||||
{
|
||||
return model_texture;
|
||||
return model_textures;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
return textures().at(name);
|
||||
}
|
||||
|
||||
/* Get the default texture. The default texture must have previously been set with the default key as
|
||||
* the name, which can be done using Model::texture(sb::Texture). */
|
||||
sb::Texture& Model::texture()
|
||||
{
|
||||
return texture(DEFAULT_TEXTURE_NAME);
|
||||
}
|
||||
|
||||
/* Assign name to texture and share ownership. */
|
||||
void Model::texture(const sb::Texture& texture, const std::string& name)
|
||||
{
|
||||
model_texture[name] = texture;
|
||||
textures()[name] = texture;
|
||||
}
|
||||
|
||||
/* If no name is specified, use the default texture. This can be used to conveniently setup a model
|
||||
* with only one texture. */
|
||||
void Model::texture(const sb::Texture& texture)
|
||||
{
|
||||
this->texture(texture, DEFAULT_TEXTURE_NAME);
|
||||
}
|
||||
|
||||
/* Set the transformation matrix. */
|
||||
void Model::transformation(const glm::mat4& transformation)
|
||||
const glm::mat4& Model::transformation() const
|
||||
{
|
||||
return model_transformation;
|
||||
}
|
||||
|
||||
/* Set the transformation matrix. */
|
||||
void Model::transform(const glm::mat4& transformation)
|
||||
{
|
||||
model_transformation = transformation;
|
||||
}
|
||||
|
@ -149,13 +170,13 @@ Model::operator glm::mat4() const
|
|||
* start over from the beginning. */
|
||||
void Background::next()
|
||||
{
|
||||
carousel.next(model_texture);
|
||||
carousel.next(textures());
|
||||
}
|
||||
|
||||
/* Return the currently active texture. */
|
||||
sb::Texture& Background::current()
|
||||
{
|
||||
return carousel.current(model_texture)->second;
|
||||
return carousel.current(textures())->second;
|
||||
}
|
||||
|
||||
CameraView::CameraView() : Plane()
|
||||
|
|
|
@ -30,10 +30,11 @@
|
|||
class Model
|
||||
{
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
inline static const std::string DEFAULT_TEXTURE_NAME = "default";
|
||||
std::map<std::string, sb::Texture> model_textures;
|
||||
std::map<std::string, std::shared_ptr<sb::Attributes>> model_attributes;
|
||||
std::map<std::string, sb::Texture> model_texture;
|
||||
glm::mat4 model_transformation = glm::mat4(1);
|
||||
|
||||
public:
|
||||
|
@ -49,10 +50,13 @@ public:
|
|||
std::shared_ptr<sb::Attributes>& operator[](const std::string&);
|
||||
void enable();
|
||||
void disable();
|
||||
std::map<std::string, sb::Texture>& texture();
|
||||
std::map<std::string, sb::Texture>& textures();
|
||||
sb::Texture& texture(const std::string&);
|
||||
sb::Texture& texture();
|
||||
void texture(const sb::Texture&, const std::string&);
|
||||
void transformation(const glm::mat4&);
|
||||
void texture(const sb::Texture&);
|
||||
const glm::mat4& transformation() const;
|
||||
void transform(const glm::mat4&);
|
||||
std::size_t size();
|
||||
operator glm::mat4() const;
|
||||
|
||||
|
|
116
src/Pudding.cpp
116
src/Pudding.cpp
|
@ -29,15 +29,29 @@ Pudding::Pudding()
|
|||
{
|
||||
/* subscribe to command events */
|
||||
get_delegate().subscribe(&Pudding::respond, this);
|
||||
get_delegate().subscribe(&Pudding::respond, this, SDL_MOUSEBUTTONDOWN);
|
||||
/* 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 */
|
||||
nlohmann::json pudding = get_configuration()["pudding"];
|
||||
set_pudding_model(pudding["top-radius"], pudding["base-radius"], pudding["ring-vertex-count"], pudding["layer-count"],
|
||||
pudding["y-range"][0], pudding["y-range"][1], pudding["gradient-position"]);
|
||||
/* use gl context so we can draw 3D */
|
||||
/* loading GL context instead of SDL context for 3D */
|
||||
load_gl_context();
|
||||
load_tiles();
|
||||
glm::vec3 w = glm::mat3({{1, 0, 0}, {0, 1, 0}, {-0.6739, -0.74, 1}}) * glm::mat3({{.1, 0, 0}, {0, .1 * (460.0 / 768.0), 0}, {0, 0, 1}}) *
|
||||
glm::vec3({-1, -1, 1});
|
||||
std::cout << w << std::endl << glm::translate(glm::vec3{-0.6739, -0.74, 0}) *
|
||||
glm::scale(glm::vec3{.1, .1 * (460.0 / 768.0), 1}) * glm::vec4{-1, -1, 0, 1} << std::endl;
|
||||
Pad p {background.current(), {-0.6739f, -0.74f}, 0.1f, get_display().window_box().aspect(), std::function<void()>()};
|
||||
const std::vector<glm::vec2>& p_position = *p.attributes("position");
|
||||
glm::vec4 final_position = p.transformation() * glm::vec4{p_position[2].x, p_position[2].y, 0, 1};
|
||||
std::cout << p.transformation() << std::endl << final_position << std::endl;
|
||||
assert(final_position == glm::vec4({w.x, w.y, 0, 1}));
|
||||
sb::Texture label {"local/button/scan.png"};
|
||||
label.load();
|
||||
pad.texture(label);
|
||||
pad.transform({-0.6739f, -0.74f}, 0.25f, get_display().window_box().aspect());
|
||||
}
|
||||
|
||||
/* Assign vertices, colors and texture UV coordinates to the pudding model */
|
||||
|
@ -204,12 +218,16 @@ void Pudding::load_gl_context()
|
|||
uniform["flat"]["time"] = glGetUniformLocation(flat_program, "time");
|
||||
uniform["flat"]["scroll"] = glGetUniformLocation(flat_program, "scroll");
|
||||
uniform["flat"]["blend"] = glGetUniformLocation(flat_program, "blend_min_hsv");
|
||||
uniform["flat"]["transformation"] = glGetUniformLocation(flat_program, "transformation");
|
||||
uniform["mvp"]["mvp"] = glGetUniformLocation(mvp_program, "mvp");
|
||||
uniform["mvp"]["time"] = glGetUniformLocation(mvp_program, "time");
|
||||
uniform["mvp"]["effect"] = glGetUniformLocation(mvp_program, "effect");
|
||||
uniform["mvp"]["uv transformation"] = glGetUniformLocation(mvp_program, "uv_transformation");
|
||||
uniform["mvp"]["coordinate bound"] = glGetUniformLocation(mvp_program, "coordinate_bound");
|
||||
uniform["mvp"]["pudding texture"] = glGetUniformLocation(mvp_program, "pudding_texture");
|
||||
/* enable alpha rendering */
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable( GL_BLEND );
|
||||
sb::Log::gl_errors("after uniform locations");
|
||||
}
|
||||
|
||||
|
@ -294,6 +312,17 @@ void Pudding::respond(SDL_Event& event)
|
|||
{
|
||||
background.next();
|
||||
}
|
||||
else if (event.type == SDL_MOUSEBUTTONDOWN)
|
||||
{
|
||||
glm::vec2 gl_coordinates {
|
||||
float(event.button.x) / window_box().width() * 2.0f - 1.0f,
|
||||
(1.0f - float(event.button.y) / window_box().height()) * 2.0f - 1.0f
|
||||
};
|
||||
if (pad.collide(gl_coordinates))
|
||||
{
|
||||
camera_switch.toggle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Build an Item object by submitting the upc parameter to multiple APIs and taking
|
||||
|
@ -729,6 +758,7 @@ int Pudding::capture_frame(void* game)
|
|||
frame.release();
|
||||
}
|
||||
SDL_GL_MakeCurrent(pudding->window, nullptr);
|
||||
sb::Log::gl_errors("in capture thread, after capturing frame");
|
||||
}
|
||||
pudding->reading_capture_frame = false;
|
||||
return 0;
|
||||
|
@ -752,6 +782,7 @@ void Pudding::update()
|
|||
reading_capture_frame = true;
|
||||
}
|
||||
}
|
||||
sb::Log::gl_errors("in main thread, after capturing frame");
|
||||
/* if the config is set to refresh automatically, there may be a new barcode available */
|
||||
if (current_config_barcode != get_configuration()["scan"]["barcode"])
|
||||
{
|
||||
|
@ -768,7 +799,7 @@ void Pudding::update()
|
|||
{
|
||||
viewport_box.drag_bottom(0.3f * viewport_box.height());
|
||||
}
|
||||
glViewport(viewport_box.left(), viewport_box.bottom(), viewport_box.width(), viewport_box.height());
|
||||
glViewport(viewport_box);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glClearColor(0, 0, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
@ -780,22 +811,25 @@ void Pudding::update()
|
|||
glUniform1i(uniform["flat"]["texture"], 0);
|
||||
glUniform3f(uniform["flat"]["blend"], 0.0f, 0.0f, 1.0f);
|
||||
glUniform1i(uniform["flat"]["scroll"], true);
|
||||
glUniformMatrix4fv(uniform["flat"]["transformation"], 1, GL_FALSE, &glm::mat4(1)[0][0]);
|
||||
/* disable pudding attributes and enable background attributes */
|
||||
pudding_model.disable();
|
||||
background.enable();
|
||||
background.current().bind();
|
||||
/* draws bg vertices and texture */
|
||||
glDrawArrays(GL_TRIANGLES, 0, background.attributes("position")->count());
|
||||
/* turn off scrolling */
|
||||
glUniform1i(uniform["flat"]["scroll"], false);
|
||||
sb::Log::gl_errors("after background, before pudding");
|
||||
/* draw pudding model using MVP shader */
|
||||
glUseProgram(mvp_program);
|
||||
glUniform1f(uniform["mvp"]["time"], time_seconds);
|
||||
/* 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(40.0f * 1 / viewport_box.aspect()), viewport_box.aspect(), 0.1f, 100.0f);
|
||||
mvp = projection * VIEW_MATRIX * model;
|
||||
/* pass the mvp matrix to the shader */
|
||||
/* uniforms */
|
||||
glUniform1f(uniform["mvp"]["time"], time_seconds);
|
||||
glUniformMatrix4fv(uniform["mvp"]["mvp"], 1, GL_FALSE, &mvp[0][0]);
|
||||
/* disable bg attributes and enable pudding attributes */
|
||||
background.disable();
|
||||
|
@ -803,12 +837,12 @@ void Pudding::update()
|
|||
if (items.size() == 0)
|
||||
{
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
pudding_model.attributes("color")->enable();
|
||||
// pudding_model.attributes("color")->enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
pudding_model.attributes("color")->enable();
|
||||
// pudding_model.attributes("color")->enable();
|
||||
pudding_model.attributes("uv")->enable();
|
||||
glUniform1i(uniform["mvp"]["pudding texture"], 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
@ -818,6 +852,7 @@ void Pudding::update()
|
|||
glEnable(GL_DEPTH_TEST);
|
||||
/* draw the sides of the pudding */
|
||||
glDrawArrays(GL_TRIANGLES, 0, pudding_triangle_vertex_count);
|
||||
sb::Log::gl_errors("after pudding sides, before pudding top/bottom");
|
||||
/* enable squircling and draw the top and bottom of pudding */
|
||||
glUniform1i(uniform["mvp"]["uv transformation"], UV_SQUIRCLE);
|
||||
glUniform1f(uniform["mvp"]["coordinate bound"], get_configuration()["pudding"]["top-radius"]);
|
||||
|
@ -828,6 +863,7 @@ void Pudding::update()
|
|||
glUniform1i(uniform["mvp"]["uv transformation"], UV_NONE);
|
||||
/* regular fill mode enabled for all other drawing */
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
sb::Log::gl_errors("after pudding, before item or camera view");
|
||||
/* only do more drawing if items are downloaded or camera is enabled */
|
||||
if (item_display_active() || capture.isOpened())
|
||||
{
|
||||
|
@ -851,7 +887,7 @@ void Pudding::update()
|
|||
{
|
||||
viewport_box.left(viewport_box.cx(), true);
|
||||
}
|
||||
glViewport(viewport_box.left(), viewport_box.bottom(), viewport_box.width(), viewport_box.height());
|
||||
glViewport(viewport_box);
|
||||
current_item().current_texture().bind();
|
||||
plane.enable();
|
||||
/* draws rectangle vertices and rectangle texture using UV coords */
|
||||
|
@ -861,7 +897,7 @@ void Pudding::update()
|
|||
if (capture.isOpened())
|
||||
{
|
||||
viewport_box.left(window_box(true).left());
|
||||
glViewport(viewport_box.left(), viewport_box.bottom(), viewport_box.width(), viewport_box.height());
|
||||
glViewport(viewport_box);
|
||||
/* bind texture for drawing */
|
||||
camera_view.current().bind();
|
||||
camera_view.enable();
|
||||
|
@ -869,8 +905,16 @@ void Pudding::update()
|
|||
glDrawArrays(GL_TRIANGLES, 0, camera_view.attributes("position")->count());
|
||||
}
|
||||
}
|
||||
sb::Log::gl_errors("after capture, before test pad");
|
||||
/* Test Pad */
|
||||
glUseProgram(flat_program);
|
||||
glUniformMatrix4fv(uniform["flat"]["transformation"], 1, GL_FALSE, &pad.transformation()[0][0]);
|
||||
pad.texture().bind();
|
||||
plane.enable();
|
||||
glViewport(window_box(true));
|
||||
glDrawArrays(GL_TRIANGLES, 0, pad.attributes("position")->count());
|
||||
SDL_GL_SwapWindow(get_window());
|
||||
sb::Log::gl_errors("after update loop");
|
||||
sb::Log::gl_errors("after test pad");
|
||||
/* add a new item if a new barcode was scanned or entered */
|
||||
if (current_barcode != previous_barcode)
|
||||
{
|
||||
|
@ -878,3 +922,57 @@ void Pudding::update()
|
|||
previous_barcode = current_barcode;
|
||||
}
|
||||
}
|
||||
|
||||
/* Construct a Pad using a texture, an offset, a scale, and a callback function. A Pad is a Plane which can be clicked
|
||||
* to launch an arbitrary user function. It can be sized and placed by setting the offset and scale values. The offset
|
||||
* is relative to (0.0, 0.0), and the scale is relative to the Plane, which has opposite corners at (-1.0, -1.0) and
|
||||
* (1.0, 1.0). * The texture is the graphic that displays in the Pad location. The callback must be a function that
|
||||
* doesn't return a value or accept any arguments. */
|
||||
Pad::Pad(sb::Texture texture, glm::vec2 offset, float scale, float ratio, std::function<void()> on_connect)
|
||||
{
|
||||
this->texture(texture);
|
||||
transform(offset, scale, ratio);
|
||||
this->on_connect(on_connect);
|
||||
box.gl(true);
|
||||
}
|
||||
|
||||
/* Set the Pad's transformation matrix based on an offset, a scale, and an aspect ratio. The offset is amount it will
|
||||
* be shifted in the (x, y) plane. The scale is a value relative to the (x, y) plane, but it is a single value because
|
||||
* the aspect ratio will determine how much each axis is scaled. If the aspect ratio is above one, the x-axis's scale
|
||||
* will be divided by the ratio. If the aspect ratio is below one, the y-axis's scale will be multiplied by the aspect
|
||||
* ratio. If the aspect ratio of the window is given, this will force the Pad to display as a square, and the ratio
|
||||
* will be relative to the shorter axis. */
|
||||
void Pad::transform(glm::vec2 offset, float scale, float ratio)
|
||||
{
|
||||
glm::vec3 scale_components { scale, scale, 1 };
|
||||
if (ratio > 1.0f)
|
||||
{
|
||||
scale_components.x /= ratio;
|
||||
}
|
||||
else if (ratio < 1.0f)
|
||||
{
|
||||
scale_components.y *= ratio;
|
||||
}
|
||||
box.size({scale_components.x * 2, scale_components.y * 2});
|
||||
box.center(offset);
|
||||
std::cout << "pad box is " << box << std::endl;
|
||||
Model::transform(glm::translate(glm::vec3{offset.x, offset.y, 0}) * glm::scale(scale_components));
|
||||
}
|
||||
|
||||
/* Set the function that will run when a pad object is clicked. */
|
||||
void Pad::on_connect(std::function<void()> on_connect)
|
||||
{
|
||||
connection.on_connect(on_connect);
|
||||
}
|
||||
|
||||
/* Returns true if the point at position collides with the box containing the pad object, which is the box the pad
|
||||
* object fits inside after the transform is applied. */
|
||||
bool Pad::collide(const glm::vec2& position) const
|
||||
{
|
||||
return box.collide(position);
|
||||
}
|
||||
|
||||
void glViewport(Box box)
|
||||
{
|
||||
glViewport(box.left(), box.bottom(), box.width(), box.height());
|
||||
}
|
||||
|
|
|
@ -42,6 +42,9 @@
|
|||
#include "Item.hpp"
|
||||
#include "Model.hpp"
|
||||
#include "utility.hpp"
|
||||
#include "Box.hpp"
|
||||
|
||||
void glViewport(Box);
|
||||
|
||||
/* A connection is an object containing a binary state of either on (connected) or off (not connected)
|
||||
* and user supplied functions that run automatically on each state change. The functions each have the
|
||||
|
@ -170,6 +173,33 @@ public:
|
|||
|
||||
};
|
||||
|
||||
/* Drawable class that is a plane containing a connection. Each instance:
|
||||
*
|
||||
* - Shares vertices and UV in VBO
|
||||
* - Has its own Texture representing the button on-screen
|
||||
* - Has its own response to click
|
||||
* - Shares mouse collision code
|
||||
* - Has its own translate + scale transformation
|
||||
*/
|
||||
class Pad : public Plane
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
using callback = std::function<void()>;
|
||||
Connection<> connection;
|
||||
Box box;
|
||||
|
||||
public:
|
||||
|
||||
Pad() {};
|
||||
Pad(sb::Texture, glm::vec2, float, float, callback);
|
||||
void transform(glm::vec2, float, float);
|
||||
void on_connect(callback);
|
||||
bool collide(const glm::vec2&) const;
|
||||
|
||||
};
|
||||
|
||||
class Pudding : public Game
|
||||
{
|
||||
|
||||
|
@ -202,11 +232,11 @@ private:
|
|||
const std::string NUTRONIX_NOT_FOUND = "resource not found";
|
||||
const std::string GOOGLE_BOOKS_API_URL = "https://www.googleapis.com/books/v1/volumes?q=isbn:";
|
||||
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, 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);
|
||||
const glm::vec3 ZERO_VECTOR_3D {0, 0, 0};
|
||||
const glm::vec3 Y_UNIT_NORMAL_3D {0, 1, 0};
|
||||
const glm::mat4 VIEW_MATRIX = glm::lookAt({4.0f, 2.0f, 1.0f}, {0.0f, -0.325f, 0.0f}, Y_UNIT_NORMAL_3D);
|
||||
const glm::vec3 PUDDING_BROWN {0.713f, 0.359f, 0.224f};
|
||||
const glm::vec3 PUDDING_YELLOW {0.878f, 0.859f, 0.122f};
|
||||
std::string current_barcode, previous_barcode, current_config_barcode, current_camera_barcode;
|
||||
std::vector<Item> items;
|
||||
Carousel item_carousel;
|
||||
|
@ -215,7 +245,7 @@ private:
|
|||
zbar::ImageScanner image_scanner;
|
||||
std::map<std::string, std::map<std::string, GLuint>> uniform;
|
||||
GLuint flat_program, mvp_program;
|
||||
glm::mat4 projection, model = glm::mat4(1.0f), mvp;
|
||||
glm::mat4 projection, model {1.0f}, mvp;
|
||||
Model pudding_model;
|
||||
Plane plane;
|
||||
Background background;
|
||||
|
@ -224,8 +254,9 @@ private:
|
|||
SDL_GLContext capture_frame_thread_context = nullptr;
|
||||
sb::VAO vao;
|
||||
sb::VBO vbo;
|
||||
Pad pad;
|
||||
|
||||
void set_pudding_model(float, float, int, int = 1, float = -1, float = 1, float = 0.3f);
|
||||
void set_pudding_model(float, float, int, int = 1, float = -1.0f, float = 1.0f, float = 0.3f);
|
||||
void load_gl_context();
|
||||
void load_tiles();
|
||||
void initialize_camera();
|
||||
|
@ -262,37 +293,19 @@ public:
|
|||
|
||||
/* Apply force until reaching a threshold. Use a connection object to run user functions
|
||||
* when force reaches threshold and when force goes below threshold. */
|
||||
template<typename return_type, typename ...arguments>
|
||||
class Button
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
Connection<> connection;
|
||||
|
||||
/* threshold */
|
||||
/* force */
|
||||
/* close */
|
||||
/* open */
|
||||
/* apply */
|
||||
/* remove */
|
||||
/* weighted depression rate */
|
||||
};
|
||||
|
||||
/* Drawable class that is a plane containing a button. Each instance:
|
||||
*
|
||||
* - Shares vertices and UV in VBO
|
||||
* - Has its own Texture representing the button on-screen
|
||||
* - Has its own response to click
|
||||
* - Shares mouse collision code
|
||||
* - Has its own translate + scale transformation
|
||||
*/
|
||||
class Pad : public Plane
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
Button button;
|
||||
Connection<return_type, arguments...> connection;
|
||||
|
||||
/* float threshold = 1.0f */
|
||||
/* float force = 0.0f */
|
||||
/* apply() */
|
||||
/* remove() */
|
||||
/* float weighted depression rate */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,5 +35,6 @@ void main(void)
|
|||
{
|
||||
gl_FragColor = texture(base_texture, uv);
|
||||
}
|
||||
gl_FragColor = min(gl_FragColor, vec4(hsv2rgb(blend_min_hsv), 1));
|
||||
/* apply blending, leaving alpha unchanged */
|
||||
gl_FragColor.xyz = min(gl_FragColor.xyz, hsv2rgb(blend_min_hsv));
|
||||
}
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
in vec2 in_position;
|
||||
in vec2 vertex_uv;
|
||||
out vec2 uv;
|
||||
uniform mat4 transformation;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = vec4(in_position, 0, 1);
|
||||
gl_Position = transformation * vec4(in_position, 0, 1);
|
||||
uv = vertex_uv;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue