using texture class to store texture data
This commit is contained in:
parent
b22302a021
commit
ea255f5247
|
@ -47,12 +47,12 @@
|
|||
"enabled": true,
|
||||
"json-save": true,
|
||||
"json-save-directory": "local/scans",
|
||||
"barcode": "",
|
||||
"barcode": "613008719548",
|
||||
"capture-device": "/dev/video0"
|
||||
},
|
||||
"api":
|
||||
{
|
||||
"user-agent": "Custom pudding creation game for http://shampoo.ooo",
|
||||
"user-agent": "Custom pudding creation game for http://nugget.fun",
|
||||
"nutronix-app-id": "ea0f2e7e",
|
||||
"nutronix-app-key": "39218dde526dd3349daa028deda518ae",
|
||||
"edamam-app-id": "c23b139f",
|
||||
|
|
2
lib/sb
2
lib/sb
|
@ -1 +1 @@
|
|||
Subproject commit 1f8de2f5f1b6a83a6c235d65030a709441f3cd37
|
||||
Subproject commit 1a4b8507e3886e02ab1b6589ed3823d7fafd1654
|
|
@ -22,17 +22,17 @@ void Item::set_text_property(const std::string& value, std::string& property, co
|
|||
}
|
||||
}
|
||||
|
||||
void Item::add_image_texture(std::shared_ptr<GLuint> texture_id)
|
||||
void Item::add_image_texture(Texture texture)
|
||||
{
|
||||
image_textures.push_back(texture_id);
|
||||
image_textures.push_back(texture);
|
||||
}
|
||||
|
||||
const std::vector<std::shared_ptr<GLuint>>& Item::get_image_textures() const
|
||||
const std::vector<Texture>& Item::get_image_textures() const
|
||||
{
|
||||
return image_textures;
|
||||
}
|
||||
|
||||
const std::shared_ptr<GLuint>& Item::get_active_image_texture() const
|
||||
const Texture& Item::get_active_image_texture() const
|
||||
{
|
||||
return get_image_textures()[current_image_index];
|
||||
}
|
||||
|
|
13
src/Item.hpp
13
src/Item.hpp
|
@ -2,11 +2,7 @@
|
|||
#define Item_h_
|
||||
|
||||
/* including so we can use GLuint type */
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#define GLEW_STATIC
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
#include <GL/glew.h>
|
||||
#else
|
||||
#include "glew/glew.h"
|
||||
|
@ -21,6 +17,7 @@
|
|||
#include <extension.hpp>
|
||||
#include "json/json.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Texture.hpp"
|
||||
|
||||
class Item : public Node
|
||||
{
|
||||
|
@ -28,7 +25,7 @@ class Item : public Node
|
|||
private:
|
||||
|
||||
nlohmann::json json = {};
|
||||
std::vector<std::shared_ptr<GLuint>> image_textures;
|
||||
std::vector<Texture> image_textures;
|
||||
std::string brand_name = "", product_name = "", upc = "";
|
||||
int current_image_index = 0;
|
||||
void set_text_property(const std::string&, std::string&, const std::string&);
|
||||
|
@ -41,9 +38,9 @@ private:
|
|||
public:
|
||||
|
||||
Item(Node*);
|
||||
void add_image_texture(std::shared_ptr<GLuint> SDL_Texture);
|
||||
const std::vector<std::shared_ptr<GLuint>>& get_image_textures() const;
|
||||
const std::shared_ptr<GLuint>& get_active_image_texture() const;
|
||||
void add_image_texture(Texture);
|
||||
const std::vector<Texture>& get_image_textures() const;
|
||||
const Texture& get_active_image_texture() const;
|
||||
void set_brand_name(const std::string&);
|
||||
const std::string& get_brand_name() const;
|
||||
void set_product_name(const std::string&);
|
||||
|
|
101
src/Pudding.cpp
101
src/Pudding.cpp
|
@ -239,22 +239,9 @@ 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);
|
||||
Texture texture = Texture(path);
|
||||
texture.load();
|
||||
tiles.push_back(texture);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,16 +262,10 @@ void Pudding::initialize_camera()
|
|||
"fps video capture device ID #" << device_id << " using " << capture.getBackendName();
|
||||
/* generate two textures that will store the video frames with the intention of double buffering them
|
||||
* for threaded texture loading */
|
||||
for (GLuint* buffer_id : {&capture_texture_front_buffer_id, &capture_texture_back_buffer_id})
|
||||
for (Texture* texture : {&capture_texture_front_buffer, &capture_texture_back_buffer})
|
||||
{
|
||||
glGenTextures(1, buffer_id);
|
||||
glBindTexture(GL_TEXTURE_2D, *buffer_id);
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, capture.get(cv::CAP_PROP_FRAME_WIDTH), capture.get(cv::CAP_PROP_FRAME_HEIGHT));
|
||||
// glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 320, 240);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
texture->generate({capture.get(cv::CAP_PROP_FRAME_WIDTH), capture.get(cv::CAP_PROP_FRAME_HEIGHT)});
|
||||
}
|
||||
capture_texture_id = capture_texture_front_buffer_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -390,10 +371,10 @@ void Pudding::incorporate_open_food_api(Item& item)
|
|||
if (json["product"].value("image_url", "") != "")
|
||||
{
|
||||
std::string url = json["product"]["image_url"];
|
||||
std::shared_ptr<GLuint> texture_id = texture_from_image_url(url);
|
||||
if (texture_id != nullptr)
|
||||
Texture texture = texture_from_image_url(url);
|
||||
if (texture.generated())
|
||||
{
|
||||
item.add_image_texture(texture_id);
|
||||
item.add_image_texture(texture);
|
||||
}
|
||||
}
|
||||
item.set_brand_name(json["product"].value("brands", ""));
|
||||
|
@ -425,10 +406,10 @@ void Pudding::incorporate_nutronix_api(Item& item)
|
|||
{
|
||||
std::string url = food["photo"]["thumb"];
|
||||
log("adding image listed in Nutronix API at " + url);
|
||||
std::shared_ptr<GLuint> texture_id = texture_from_image_url(url);
|
||||
if (texture_id != nullptr)
|
||||
Texture texture = texture_from_image_url(url);
|
||||
if (texture.generated())
|
||||
{
|
||||
item.add_image_texture(texture_id);
|
||||
item.add_image_texture(texture);
|
||||
}
|
||||
}
|
||||
item.set_brand_name(food.value("brand_name", ""));
|
||||
|
@ -459,10 +440,10 @@ void Pudding::incorporate_edamam_api(Item& item)
|
|||
if (food.value("image", "") != "")
|
||||
{
|
||||
std::string url = food["image"];
|
||||
std::shared_ptr<GLuint> texture_id = texture_from_image_url(url);
|
||||
if (texture_id != nullptr)
|
||||
Texture texture = texture_from_image_url(url);
|
||||
if (texture.generated())
|
||||
{
|
||||
item.add_image_texture(texture_id);
|
||||
item.add_image_texture(texture);
|
||||
}
|
||||
item.set_product_name(food.value("label", ""));
|
||||
}
|
||||
|
@ -494,10 +475,10 @@ void Pudding::incorporate_best_buy_api(Item& item)
|
|||
if (product.value(key, "") != "")
|
||||
{
|
||||
std::string url = product[key];
|
||||
std::shared_ptr<GLuint> texture_id = texture_from_image_url(url);
|
||||
if (texture_id != nullptr)
|
||||
Texture texture = texture_from_image_url(url);
|
||||
if (texture.generated())
|
||||
{
|
||||
item.add_image_texture(texture_id);
|
||||
item.add_image_texture(texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -558,7 +539,7 @@ nlohmann::json Pudding::json_from_url(const std::string& url, const std::vector<
|
|||
|
||||
/* Store the byte buffer from the submitted URL downloaded by cURL into the supplied storage vector
|
||||
*/
|
||||
void Pudding::curl_get_bytes(const std::string& url, std::vector<std::uint8_t>& storage, const std::vector<std::string>& headers)
|
||||
void Pudding::curl_get_bytes(const std::string& url, std::vector<std::uint8_t>& storage, const std::vector<std::string>& headers) const
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode result;
|
||||
|
@ -614,40 +595,26 @@ size_t Pudding::curl_write_response(std::uint8_t* buffer, size_t size, size_t co
|
|||
|
||||
/* Allocate storage for a texture, copy the cURL response data into the storage, and return the ID that corresponds to the GL texture
|
||||
*/
|
||||
std::shared_ptr<GLuint> Pudding::texture_from_image_url(const std::string& url)
|
||||
Texture Pudding::texture_from_image_url(const std::string& url) const
|
||||
{
|
||||
/* this texture will be returned whether we load pixels into it or not */
|
||||
Texture texture;
|
||||
log("looking up image at " + url);
|
||||
std::vector<std::uint8_t> storage;
|
||||
curl_get_bytes(url, storage);
|
||||
if (!storage.empty())
|
||||
{
|
||||
debug("received image data");
|
||||
/* load as an SDL surface to translate image format into pixel data, flip, and get dimensions */
|
||||
/* get a Texture by passing the bytes through an RW ops which will enable the Texture object to load a Surface */
|
||||
SDL_RWops* rw = SDL_RWFromConstMem(storage.data(), storage.size());
|
||||
SDL_Surface* surface = IMG_Load_RW(rw, 0);
|
||||
SDL_Surface* flipped_surface = rotozoomSurfaceXY(surface, 0, 1, -1, 0);
|
||||
std::ostringstream message;
|
||||
message << "image is " << flipped_surface->w << "x" << flipped_surface->h;
|
||||
log(message.str());
|
||||
/* generate a GL texture, allocate space and set properties */
|
||||
std::shared_ptr<GLuint> texture_id = std::shared_ptr<GLuint>(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);
|
||||
/* copy image bytes into GL texture */
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surface->w, surface->h, GL_RGBA, GL_UNSIGNED_BYTE, flipped_surface->pixels);
|
||||
log_gl_errors();
|
||||
SDL_FreeSurface(surface);
|
||||
SDL_FreeSurface(flipped_surface);
|
||||
return texture_id;
|
||||
texture.load(rw);
|
||||
SDL_RWclose(rw);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_CUSTOM, "image url returned no data");
|
||||
return nullptr;
|
||||
}
|
||||
return texture;
|
||||
}
|
||||
|
||||
/* Call GL's delete texture function, and print a debug statement for testing. This is defined as a static member
|
||||
|
@ -701,13 +668,13 @@ int Pudding::capture_frame(void* game)
|
|||
/* rotate the opencv matrix 180 to work with opengl coords */
|
||||
cv::flip(frame, frame, -1);
|
||||
/* use whichever texture ID is not being used by the main rendering thread */
|
||||
GLuint texture_id = pudding->capture_texture_id == pudding->capture_texture_front_buffer_id ?
|
||||
pudding->capture_texture_back_buffer_id : pudding->capture_texture_front_buffer_id;
|
||||
Texture& texture = pudding->capture_texture == pudding->capture_texture_front_buffer ?
|
||||
pudding->capture_texture_back_buffer : pudding->capture_texture_front_buffer;
|
||||
/* bind texture for accepting pixel data */
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||
texture.bind();
|
||||
/* fill texture memory with last frame's pixels */
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, frame.cols, frame.rows, GL_BGR, GL_UNSIGNED_BYTE, frame.ptr());
|
||||
pudding->capture_texture_id = texture_id;
|
||||
texture.load(frame.ptr(), {frame.cols, frame.rows}, GL_BGR, GL_UNSIGNED_BYTE);
|
||||
pudding->capture_texture = texture;
|
||||
if (pudding->get_configuration()["scan"]["enabled"])
|
||||
{
|
||||
/* convert to gray and scan with zbar */
|
||||
|
@ -784,7 +751,7 @@ void Pudding::update()
|
|||
glEnableVertexAttribArray(1);
|
||||
glUniform1i(flat_texture_uniform_location, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, *tiles[current_tile_index]);
|
||||
tiles[current_tile_index].bind();
|
||||
/* 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");
|
||||
glUniform3f(blend_min_hsv_location, 0.0f, 0.0f, 1.0f);
|
||||
|
@ -819,7 +786,7 @@ void Pudding::update()
|
|||
GLuint pudding_texture_location = glGetUniformLocation(mvp_program, "pudding_texture");
|
||||
glUniform1i(pudding_texture_location, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, *get_current_item().get_active_image_texture().get());
|
||||
get_current_item().get_active_image_texture().bind();
|
||||
}
|
||||
/* draw pudding model */
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
@ -864,7 +831,7 @@ void Pudding::update()
|
|||
viewport_box.left(viewport_box.cx(), true);
|
||||
}
|
||||
glViewport(viewport_box.left(), viewport_box.bottom(), viewport_box.width(), viewport_box.height());
|
||||
glBindTexture(GL_TEXTURE_2D, *get_current_item().get_active_image_texture().get());
|
||||
get_current_item().get_active_image_texture().bind();
|
||||
/* draws rectangle vertices and rectangle texture using UV coords */
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
@ -874,7 +841,7 @@ void Pudding::update()
|
|||
viewport_box.left(window_box(true).left());
|
||||
glViewport(viewport_box.left(), viewport_box.bottom(), viewport_box.width(), viewport_box.height());
|
||||
/* bind texture for drawing */
|
||||
glBindTexture(GL_TEXTURE_2D, capture_texture_id);
|
||||
capture_texture.bind();
|
||||
/* draws rectangle vertices and rectangle texture using UV coords */
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include <filesystem>
|
||||
#include <curl/curl.h>
|
||||
#include "SDL.h"
|
||||
#include "SDL_image.h"
|
||||
#include "sdl2-gfx/SDL2_gfxPrimitives.h"
|
||||
#include "json/json.hpp"
|
||||
#include "glm/vec2.hpp"
|
||||
#include "opencv2/core.hpp"
|
||||
|
@ -23,6 +25,7 @@
|
|||
#include "extension.hpp"
|
||||
#include "Item.hpp"
|
||||
#include "Animation.hpp"
|
||||
#include "Texture.hpp"
|
||||
|
||||
class Pudding : public Game
|
||||
{
|
||||
|
@ -65,16 +68,17 @@ private:
|
|||
current_tile_index = 0;
|
||||
cv::VideoCapture capture;
|
||||
zbar::ImageScanner image_scanner;
|
||||
GLuint flat_program, mvp_program, capture_texture_front_buffer_id, capture_texture_back_buffer_id, capture_texture_id,
|
||||
mvp_uniform_location, time_uniform_location, effect_uniform_location, uv_transformation_uniform_location,
|
||||
flat_texture_uniform_location, coordinate_bound_uniform_location, flat_time_uniform_location,
|
||||
scroll_uniform_location;
|
||||
GLuint flat_program, mvp_program, mvp_uniform_location, time_uniform_location, effect_uniform_location,
|
||||
uv_transformation_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;
|
||||
std::vector<glm::vec3> pudding_vertices, pudding_colors;
|
||||
std::vector<glm::vec2> pudding_uv;
|
||||
bool show_item = false, reading_capture_frame = false;
|
||||
SDL_GLContext capture_frame_thread_context = nullptr;
|
||||
std::vector<std::shared_ptr<GLuint>> tiles;
|
||||
std::vector<Texture> tiles;
|
||||
Texture capture_texture_front_buffer, capture_texture_back_buffer;
|
||||
Texture& capture_texture = capture_texture_front_buffer;
|
||||
|
||||
void set_pudding_model(float, float, int, int = 1, float = -1, float = 1, float = 0.3f);
|
||||
void load_gl_context();
|
||||
|
@ -86,9 +90,9 @@ private:
|
|||
void incorporate_best_buy_api(Item&);
|
||||
void save_item_json(const nlohmann::json&, const Item&, const std::string&) const;
|
||||
nlohmann::json json_from_url(const std::string&, const std::vector<std::string>& = {});
|
||||
void curl_get_bytes(const std::string& url, std::vector<std::uint8_t>&, const std::vector<std::string>& = {});
|
||||
void curl_get_bytes(const std::string& url, std::vector<std::uint8_t>&, const std::vector<std::string>& = {}) const;
|
||||
static size_t curl_write_response(std::uint8_t*, size_t, size_t, std::vector<std::uint8_t>*);
|
||||
std::shared_ptr<GLuint> texture_from_image_url(const std::string&);
|
||||
Texture texture_from_image_url(const std::string&) const;
|
||||
static void destroy_texture(GLuint*);
|
||||
bool item_display_active() const;
|
||||
static int capture_frame(void*);
|
||||
|
|
Loading…
Reference in New Issue