tiling effect using original texture size

This commit is contained in:
frank 2021-09-14 20:14:15 -04:00
parent be7b750e89
commit b22302a021
10 changed files with 66 additions and 30 deletions

View File

@ -17,7 +17,8 @@
"print-frame-length-history": ["CTRL", "SHIFT", "h"], "print-frame-length-history": ["CTRL", "SHIFT", "h"],
"toggle-camera": ["CTRL", "c"], "toggle-camera": ["CTRL", "c"],
"toggle-item": ["CTRL", "i"], "toggle-item": ["CTRL", "i"],
"effect": ["CTRL", "e"] "effect": ["CTRL", "e"],
"tile": ["CTRL", "t"]
}, },
"recording": "recording":
{ {
@ -72,5 +73,9 @@
"layer-count": 12, "layer-count": 12,
"y-range": [-0.6, 0.6], "y-range": [-0.6, 0.6],
"gradient-position": 0.25 "gradient-position": 0.25
},
"resource":
{
"tile-path": "resource/tile"
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

BIN
resource/tile/teapot.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
resource/tile/utensil1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
resource/tile/vase.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -19,6 +19,7 @@
#include <functional> #include <functional>
#include <SDL.h> #include <SDL.h>
#include <extension.hpp> #include <extension.hpp>
#include "json/json.hpp"
#include "Node.hpp" #include "Node.hpp"
class Item : public Node class Item : public Node
@ -26,6 +27,7 @@ class Item : public Node
private: private:
nlohmann::json json = {};
std::vector<std::shared_ptr<GLuint>> image_textures; std::vector<std::shared_ptr<GLuint>> image_textures;
std::string brand_name = "", product_name = "", upc = ""; std::string brand_name = "", product_name = "", upc = "";
int current_image_index = 0; int current_image_index = 0;

View File

@ -38,6 +38,7 @@ Pudding::Pudding()
pudding["y-range"][0], pudding["y-range"][1], pudding["gradient-position"]); pudding["y-range"][0], pudding["y-range"][1], pudding["gradient-position"]);
/* use gl context so we can draw 3D */ /* use gl context so we can draw 3D */
load_gl_context(); load_gl_context();
load_tiles();
} }
/* Assign vertices, colors and texture UV coordinates to the pudding model */ /* Assign vertices, colors and texture UV coordinates to the pudding model */
@ -160,18 +161,6 @@ void Pudding::load_gl_context()
{ {
log("could not create capture frame thread context"); log("could not create capture frame thread context");
} }
/* load background as surface, generate texture to load pixel data into, allocate storage, bind and edit texture properties */
std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> surface(IMG_Load("local/tptile.jpg"), SDL_FreeSurface);
std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> flipped_surface(rotozoomSurfaceXY(surface.get(), 0, 1, -1, 0), SDL_FreeSurface);
glGenTextures(1, &background_texture_id);
glBindTexture(GL_TEXTURE_2D, background_texture_id);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, flipped_surface->w, flipped_surface->h);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, flipped_surface->w, flipped_surface->h, GL_RGBA, GL_UNSIGNED_BYTE, flipped_surface->pixels);
std::ostringstream message;
message << "loaded background image " << flipped_surface->w << "x" << flipped_surface->h;
log(message.str());
/* Allocate a vertex array object, bind it as current, doesn't need to be a member var because the same one is always bound */ /* Allocate a vertex array object, bind it as current, doesn't need to be a member var because the same one is always bound */
GLuint vao; GLuint vao;
glGenVertexArrays(1, &vao); glGenVertexArrays(1, &vao);
@ -225,6 +214,8 @@ void Pudding::load_gl_context()
glBindAttribLocation(flat_program, 1, "vertex_uv"); glBindAttribLocation(flat_program, 1, "vertex_uv");
link_shader(flat_program); link_shader(flat_program);
flat_texture_uniform_location = glGetUniformLocation(flat_program, "base_texture"); flat_texture_uniform_location = glGetUniformLocation(flat_program, "base_texture");
flat_time_uniform_location = glGetUniformLocation(flat_program, "time");
scroll_uniform_location = glGetUniformLocation(flat_program, "scroll");
/* load, configure and link the 3D world program */ /* load, configure and link the 3D world program */
vertex_shader = load_shader("src/mvp.vert", GL_VERTEX_SHADER); vertex_shader = load_shader("src/mvp.vert", GL_VERTEX_SHADER);
fragment_shader = load_shader("src/mvp.frag", GL_FRAGMENT_SHADER); fragment_shader = load_shader("src/mvp.frag", GL_FRAGMENT_SHADER);
@ -243,6 +234,30 @@ void Pudding::load_gl_context()
log_gl_errors(); log_gl_errors();
} }
/* Read every resource/tile/.*.jpg into a GL texture, storing the texture pointer and file name in a std::map */
void Pudding::load_tiles()
{
for (fs::path path : sb::glob(get_configuration()["resource"]["tile-path"].get<fs::path>() / ".*.jpg"))
{
/* load background as surface */
std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> surface(IMG_Load(path.c_str()), SDL_FreeSurface);
std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> flipped_surface(rotozoomSurfaceXY(surface.get(), 0, 1, -1, 0), SDL_FreeSurface);
/* generate a GL texture, allocate space and set properties */
std::shared_ptr<GLuint> texture_id(new GLuint, Pudding::destroy_texture);
glGenTextures(1, texture_id.get());
glBindTexture(GL_TEXTURE_2D, *texture_id);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, flipped_surface->w, flipped_surface->h);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, flipped_surface->w, flipped_surface->h, GL_RGBA, GL_UNSIGNED_BYTE, flipped_surface->pixels);
log_gl_errors();
std::ostringstream message;
message << "loaded background image " << path.stem() << " from " << path << "(" << flipped_surface->w << "x" << flipped_surface->h << ")";
log(message.str());
tiles.push_back(texture_id);
}
}
/* Try to create cv::VideoCapture object using device ID #0. If successful, this will create GL texture IDs and storage /* Try to create cv::VideoCapture object using device ID #0. If successful, this will create GL texture IDs and storage
* for the camera frames, so it must be called after GL context has been created. Two textures will be created, so they * for the camera frames, so it must be called after GL context has been created. Two textures will be created, so they
* can be used as a double buffer. * can be used as a double buffer.
@ -319,6 +334,10 @@ void Pudding::respond(SDL_Event& event)
glUseProgram(mvp_program); glUseProgram(mvp_program);
glUniform1i(effect_uniform_location, effect_id); glUniform1i(effect_uniform_location, effect_id);
} }
else if (get_delegate().compare(event, "tile"))
{
current_tile_index = ++current_tile_index % tiles.size();
}
} }
/* Build an Item object by submitting the upc parameter to multiple APIs and taking /* Build an Item object by submitting the upc parameter to multiple APIs and taking
@ -720,6 +739,8 @@ int Pudding::capture_frame(void* game)
/* Update parameters and draw the screen */ /* Update parameters and draw the screen */
void Pudding::update() void Pudding::update()
{ {
/* number of seconds we've been running for */
float time_seconds = SDL_GetTicks() / 1000.0f;
/* launch the camera capture thread if it is not currently running */ /* launch the camera capture thread if it is not currently running */
if (capture.isOpened() && !reading_capture_frame) if (capture.isOpened() && !reading_capture_frame)
{ {
@ -755,6 +776,7 @@ void Pudding::update()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* switch to flat shader for background */ /* switch to flat shader for background */
glUseProgram(flat_program); glUseProgram(flat_program);
glUniform1f(flat_time_uniform_location, time_seconds);
/* disable pudding attributes and enable rectangle attributes */ /* disable pudding attributes and enable rectangle attributes */
glDisableVertexAttribArray(2); glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3); glDisableVertexAttribArray(3);
@ -762,16 +784,17 @@ void Pudding::update()
glEnableVertexAttribArray(1); glEnableVertexAttribArray(1);
glUniform1i(flat_texture_uniform_location, 0); glUniform1i(flat_texture_uniform_location, 0);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, background_texture_id); glBindTexture(GL_TEXTURE_2D, *tiles[current_tile_index]);
/* set blend to modify white part of background, color passed is in HSV format */ /* set blend to modify white part of background, color passed is in HSV format */
GLint blend_min_hsv_location = glGetUniformLocation(flat_program, "blend_min_hsv"); GLint blend_min_hsv_location = glGetUniformLocation(flat_program, "blend_min_hsv");
/* blend min with black will create a black blackground regardless of texture */ glUniform3f(blend_min_hsv_location, 0.0f, 0.0f, 1.0f);
glUniform3f(blend_min_hsv_location, 0, 0, 0); glUniform1i(scroll_uniform_location, true);
/* draws rectangle vertices and rectangle texture using UV coords */ /* draws rectangle vertices and rectangle texture using UV coords */
glDrawArrays(GL_TRIANGLES, 0, 6); glDrawArrays(GL_TRIANGLES, 0, 6);
glUniform1i(scroll_uniform_location, false);
/* draw pudding model using MVP shader */ /* draw pudding model using MVP shader */
glUseProgram(mvp_program); glUseProgram(mvp_program);
glUniform1f(time_uniform_location, SDL_GetTicks() / 1000.0f); glUniform1f(time_uniform_location, time_seconds);
/* calculate the transformation matrix for displaying pudding in viewport */ /* 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); model = glm::rotate(model, weight(get_configuration()["pudding"]["rotation-speed"].get<float>()), Y_UNIT_NORMAL_3D);
projection = glm::perspective( projection = glm::perspective(

View File

@ -61,20 +61,24 @@ private:
const glm::vec3 PUDDING_YELLOW = glm::vec3(0.878f, 0.859f, 0.122f); 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; std::string current_barcode, previous_barcode, current_config_barcode, current_camera_barcode;
std::vector<Item> items; std::vector<Item> items;
int current_item_index = 0, effect_id = EFFECT_NONE, pudding_triangle_vertex_count = 0, pudding_fan_vertex_count = 0; int current_item_index = 0, effect_id = EFFECT_NONE, pudding_triangle_vertex_count = 0, pudding_fan_vertex_count = 0,
current_tile_index = 0;
cv::VideoCapture capture; cv::VideoCapture capture;
zbar::ImageScanner image_scanner; zbar::ImageScanner image_scanner;
GLuint flat_program, mvp_program, capture_texture_front_buffer_id, capture_texture_back_buffer_id, capture_texture_id, GLuint flat_program, mvp_program, capture_texture_front_buffer_id, capture_texture_back_buffer_id, capture_texture_id,
mvp_uniform_location, background_texture_id, time_uniform_location, effect_uniform_location, uv_transformation_uniform_location, mvp_uniform_location, time_uniform_location, effect_uniform_location, uv_transformation_uniform_location,
flat_texture_uniform_location, coordinate_bound_uniform_location; flat_texture_uniform_location, coordinate_bound_uniform_location, flat_time_uniform_location,
scroll_uniform_location;
glm::mat4 projection, model = glm::mat4(1.0f), mvp; glm::mat4 projection, model = glm::mat4(1.0f), mvp;
std::vector<glm::vec3> pudding_vertices, pudding_colors; std::vector<glm::vec3> pudding_vertices, pudding_colors;
std::vector<glm::vec2> pudding_uv; std::vector<glm::vec2> pudding_uv;
bool show_item = false, reading_capture_frame = false; bool show_item = false, reading_capture_frame = false;
SDL_GLContext capture_frame_thread_context = nullptr; SDL_GLContext capture_frame_thread_context = nullptr;
std::vector<std::shared_ptr<GLuint>> tiles;
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, float = 1, float = 0.3f);
void load_gl_context(); void load_gl_context();
void load_tiles();
void initialize_camera(); void initialize_camera();
void incorporate_open_food_api(Item&); void incorporate_open_food_api(Item&);
void incorporate_nutronix_api(Item&); void incorporate_nutronix_api(Item&);

View File

@ -3,6 +3,8 @@
in vec2 uv; in vec2 uv;
uniform sampler2D base_texture; uniform sampler2D base_texture;
uniform vec3 blend_min_hsv; uniform vec3 blend_min_hsv;
uniform float time;
uniform bool scroll = false;
/* from http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl, licensed under WTFPL */ /* from http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl, licensed under WTFPL */
vec3 hsv2rgb(vec3 c) vec3 hsv2rgb(vec3 c)
@ -14,6 +16,15 @@ vec3 hsv2rgb(vec3 c)
void main(void) void main(void)
{ {
gl_FragColor = texture(base_texture, uv); if (scroll)
{
ivec2 texture_size = textureSize(base_texture, 0);
float speed = time * 35.0;
gl_FragColor = texelFetch(base_texture, ivec2(mod(vec2(gl_FragCoord.x + speed, gl_FragCoord.y - speed), texture_size)), 0);
}
else
{
gl_FragColor = texture(base_texture, uv);
}
gl_FragColor = min(gl_FragColor, vec4(hsv2rgb(blend_min_hsv), 1)); gl_FragColor = min(gl_FragColor, vec4(hsv2rgb(blend_min_hsv), 1));
} }

View File

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