diff --git a/Makefile b/Makefile index 48bdf14..b5bc88e 100644 --- a/Makefile +++ b/Makefile @@ -54,23 +54,24 @@ $(SDLGFX2_DIR)%.o: $(SDLGFX2_DIR)%.c $(SDLGFX2_DIR)%.h $(GLEW_DIR)%.o: $(GLEW_DIR)%.c $(GLEW_DIR)%.h $(CC) $(CFLAGS) $< -c -o $@ -$(SB_SRC_DIR)extension.o : $(addprefix $(SB_SRC_DIR),Box.hpp Segment.hpp Color.hpp filesystem.hpp Pixels.hpp) -$(SB_SRC_DIR)Node.o : $(addprefix $(SB_SRC_DIR),Game.hpp Configuration.hpp Delegate.hpp Display.hpp Input.hpp Box.hpp Audio.hpp) -$(SB_SRC_DIR)Sprite.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Box.hpp Animation.hpp Color.hpp extension.hpp Pixels.hpp) +$(SB_SRC_DIR)extension.o : $(addprefix $(SB_SRC_DIR),Box.hpp Segment.hpp Color.hpp filesystem.hpp Pixels.hpp Log.hpp) +$(SB_SRC_DIR)Node.o : $(addprefix $(SB_SRC_DIR),Game.hpp Configuration.hpp Delegate.hpp Display.hpp Input.hpp Box.hpp Audio.hpp Log.hpp) +$(SB_SRC_DIR)Sprite.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Box.hpp Animation.hpp Color.hpp extension.hpp Pixels.hpp Log.hpp) $(SB_SRC_DIR)Game.o : $(addprefix $(SB_SRC_DIR),extension.hpp Node.hpp Sprite.hpp Recorder.hpp Input.hpp Configuration.hpp \ - Delegate.hpp Audio.hpp) + Delegate.hpp Audio.hpp Log.hpp) $(SB_SRC_DIR)Animation.o : $(addprefix $(SB_SRC_DIR),Node.hpp Timer.hpp) $(SB_SRC_DIR)Recorder.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Configuration.hpp Delegate.hpp Animation.hpp extension.hpp) $(SB_SRC_DIR)Input.o : $(addprefix $(SB_SRC_DIR),Node.hpp Animation.hpp Configuration.hpp Delegate.hpp) -$(SB_SRC_DIR)Configuration.o : $(addprefix $(SB_SRC_DIR),Node.hpp Animation.hpp) +$(SB_SRC_DIR)Configuration.o : $(addprefix $(SB_SRC_DIR),Node.hpp Animation.hpp Log.hpp) $(SB_SRC_DIR)Delegate.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Input.hpp) -$(SB_SRC_DIR)Display.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Box.hpp Configuration.hpp Delegate.hpp) +$(SB_SRC_DIR)Display.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Box.hpp Configuration.hpp Delegate.hpp Log.hpp) $(SB_SRC_DIR)Box.o : $(addprefix $(SB_SRC_DIR),extension.hpp Segment.hpp) $(SB_SRC_DIR)Segment.o : $(addprefix $(SB_SRC_DIR),extension.hpp Box.hpp) -$(SB_SRC_DIR)Pixels.o : $(addprefix $(SB_SRC_DIR),Box.hpp extension.hpp) +$(SB_SRC_DIR)Pixels.o : $(addprefix $(SB_SRC_DIR),Box.hpp extension.hpp Log.hpp) $(SB_SRC_DIR)Audio.o : $(addprefix $(SB_SRC_DIR),Node.hpp Display.hpp Configuration.hpp Box.hpp filesystem.hpp extension.hpp) -$(SB_SRC_DIR)Texture.o : $(addprefix $(SB_SRC_DIR),GLObject.hpp filesystem.hpp Game.hpp) -$(SRC_DIR)Item.o : $(addprefix $(SB_SRC_DIR),extension.hpp Node.hpp Texture.hpp) +$(SB_SRC_DIR)Texture.o : $(addprefix $(SB_SRC_DIR),GLObject.hpp filesystem.hpp Log.hpp) +$(SB_SRC_DIR)GLObject.o : $(addprefix $(SB_SRC_DIR),Log.hpp) +$(SRC_DIR)Item.o : $(addprefix $(SB_SRC_DIR),extension.hpp Node.hpp Texture.hpp Log.hpp) $(SRC_DIR)Pudding.o : $(SRC_H_FILES) $(SB_H_FILES) %.o : %.cpp %.hpp $(CPPC) $(CPP_FLAGS) $< -c -o $@ diff --git a/lib/sb b/lib/sb index f03d58d..f70ea1c 160000 --- a/lib/sb +++ b/lib/sb @@ -1 +1 @@ -Subproject commit f03d58dae13d673f4db26af88710e541a892cb77 +Subproject commit f70ea1c21595376ea8bc02d80140721eaf627520 diff --git a/src/Item.cpp b/src/Item.cpp index 4a765bd..6c1e2d0 100644 --- a/src/Item.cpp +++ b/src/Item.cpp @@ -9,16 +9,16 @@ void Item::set_text_property(const std::string& value, std::string& property, co if (value != "") { property = value; - log("set " + property_name + " to " + property + " in " + get_full_name()); + sb::Log::log("set " + property_name + " to " + property + " in " + get_full_name()); } else { - debug("empty string passed, not setting " + property_name + " in " + get_full_name()); + sb::Log::log("empty string passed, not setting " + property_name + " in " + get_full_name(), sb::Log::DEBUG); } } else { - debug(property_name + " already set to " + property + " in " + get_full_name() + ", not setting"); + sb::Log::log(property_name + " already set to " + property + " in " + get_full_name() + ", not setting", sb::Log::DEBUG); } } diff --git a/src/Item.hpp b/src/Item.hpp index ba46a6e..f6811c5 100644 --- a/src/Item.hpp +++ b/src/Item.hpp @@ -18,10 +18,11 @@ #include "extension.hpp" #include "Node.hpp" #include "Texture.hpp" +#include "Log.hpp" class Item : public Node { - + private: nlohmann::json json = {}; diff --git a/src/Pudding.cpp b/src/Pudding.cpp index fe66502..809dd45 100644 --- a/src/Pudding.cpp +++ b/src/Pudding.cpp @@ -159,7 +159,7 @@ void Pudding::load_gl_context() SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); if ((capture_frame_thread_context = SDL_GL_CreateContext(window)) == nullptr) { - log("could not create capture frame thread context"); + sb::Log::log("could not create capture frame thread context"); } /* Generate a vertex array object ID, bind it as current */ vao.generate(); @@ -178,6 +178,7 @@ void Pudding::load_gl_context() * will be copied in one after the other, offset to after the previous data location. The same buffer offset will * be passed to the vertex attributes for each data. */ vbo.generate(); + vbo.target(GL_ARRAY_BUFFER); vbo.bind(); /* allocate space for vertices, UV and colors, and copy rectangle vertices in at initialization */ GLsizeiptr vbo_size = (rectangle_vertices.size() + rectangle_uv.size() + pudding_uv.size()) * sizeof(glm::vec2) + @@ -229,7 +230,7 @@ void Pudding::load_gl_context() effect_uniform_location = glGetUniformLocation(mvp_program, "effect"); uv_transformation_uniform_location = glGetUniformLocation(mvp_program, "uv_transformation"); coordinate_bound_uniform_location = glGetUniformLocation(mvp_program, "coordinate_bound"); - log_gl_errors(); + sb::Log::gl_errors(); } /* Read every resource/tile/.*.jpg into a GL texture, storing the texture pointer and file name in a std::map */ @@ -252,7 +253,7 @@ void Pudding::initialize_camera() /* initialize an opencv capture device for getting images from an attached camera */ int device_id = 0; capture.open(device_id); - std::stringstream message; + std::ostringstream message; if (capture.isOpened()) { message << "opened and initialized " << capture.get(cv::CAP_PROP_FRAME_WIDTH) << "x" << @@ -269,7 +270,7 @@ void Pudding::initialize_camera() { message << "failed to open video capture device ID #" << device_id; } - log(message.str()); + sb::Log::log(message); } /* Respond to command events */ @@ -353,7 +354,7 @@ void Pudding::add_item(const std::string& upc) { std::ostringstream message; message << "discarding item, no images found for " << upc; - log(message.str()); + sb::Log::log(message); } } @@ -361,7 +362,7 @@ void Pudding::add_item(const std::string& upc) */ void Pudding::incorporate_open_food_api(Item& item) { - log("checking Open Food API"); + sb::Log::log("checking Open Food API"); nlohmann::json json = json_from_url(OPEN_FOOD_API_URL + item.get_upc()); /* test that should determine if an Open Food API response is not empty */ if (json.value("status", 0) && json.contains("product")) @@ -381,7 +382,7 @@ void Pudding::incorporate_open_food_api(Item& item) } else { - log("no results from Open Food"); + sb::Log::log("no results from Open Food"); } } @@ -389,7 +390,7 @@ void Pudding::incorporate_open_food_api(Item& item) */ void Pudding::incorporate_nutronix_api(Item& item) { - log("checking Nutronix API"); + sb::Log::log("checking Nutronix API"); /* Nutronix requires API keys in headers for validation */ nlohmann::json json = json_from_url( NUTRONIX_API_URL + item.get_upc(), { @@ -403,7 +404,7 @@ void Pudding::incorporate_nutronix_api(Item& item) if (food.contains("photo") && food["photo"].value("thumb", "") != "") { std::string url = food["photo"]["thumb"]; - log("adding image listed in Nutronix API at " + url); + sb::Log::log("adding image listed in Nutronix API at " + url); Texture texture = texture_from_image_url(url); if (texture.generated()) { @@ -416,7 +417,7 @@ void Pudding::incorporate_nutronix_api(Item& item) } else { - log("no results from Nutronix"); + sb::Log::log("no results from Nutronix"); } } @@ -424,7 +425,7 @@ void Pudding::incorporate_nutronix_api(Item& item) */ void Pudding::incorporate_edamam_api(Item& item) { - log("checking Edamam API"); + sb::Log::log("checking Edamam API"); /* build API url by concatenating relevant values into query string */ std::stringstream url; url << "https://api.edamam.com/api/food-database/v2/parser?upc=" << item.get_upc() << "&app_id=" << @@ -449,7 +450,7 @@ void Pudding::incorporate_edamam_api(Item& item) } else { - log("no results from Edamam"); + sb::Log::log("no results from Edamam"); } } @@ -457,7 +458,7 @@ void Pudding::incorporate_edamam_api(Item& item) */ void Pudding::incorporate_best_buy_api(Item& item) { - log("checking Best Buy API"); + sb::Log::log("checking Best Buy API"); /* build API url by concatenating relevant values into query string */ std::stringstream url; url << "https://api.bestbuy.com/v1/products(upc=" << item.get_upc() << ")?format=json&apiKey=" << @@ -485,7 +486,7 @@ void Pudding::incorporate_best_buy_api(Item& item) } else { - log("no results from Best Buy"); + sb::Log::log("no results from Best Buy"); } } @@ -514,7 +515,7 @@ void Pudding::save_item_json(const nlohmann::json& json, const Item& item, const path /= prefix + "_" + item.get_upc() + ".json"; std::ofstream out(path); out << std::setw(4) << json << std::endl; - log("Saved JSON to " + path.string()); + sb::Log::log("Saved JSON to " + path.string()); } else { @@ -531,7 +532,7 @@ nlohmann::json Pudding::json_from_url(const std::string& url, const std::vector< nlohmann::json json = nlohmann::json::parse(storage); std::stringstream json_formatted; json_formatted << std::setw(4) << json << std::endl; - debug(json_formatted.str()); + sb::Log::log(json_formatted.str(), sb::Log::DEBUG); return json; } @@ -597,12 +598,12 @@ 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); + sb::Log::log("looking up image at " + url); std::vector storage; curl_get_bytes(url, storage); if (!storage.empty()) { - debug("received image data"); + sb::Log::log("received image data", sb::Log::DEBUG); /* 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()); texture.load(rw); @@ -622,7 +623,9 @@ Texture Pudding::texture_from_image_url(const std::string& url) const void Pudding::destroy_texture(GLuint* texture_id) { /* not sure why SDL_Log works here but SDL_LogDebug and SDL_LogInfo don't */ - SDL_Log("destroying texture ID %i", *texture_id); + std::ostringstream message; + message << "destroying texture ID " << *texture_id; + sb::Log::log(message); glDeleteTextures(1, texture_id); } @@ -653,7 +656,7 @@ int Pudding::capture_frame(void* game) * with the main rendering context) */ if (SDL_GL_MakeCurrent(pudding->window, pudding->capture_frame_thread_context) < 0) { - pudding->log("error making thread context current"); + sb::Log::log("error making thread context current"); } else { @@ -683,9 +686,9 @@ int Pudding::capture_frame(void* game) { for (zbar::Image::SymbolIterator symbol = query_image.symbol_begin(); symbol != query_image.symbol_end(); ++symbol) { - std::stringstream message; + std::ostringstream message; message << "camera scanned " << symbol->get_type_name() << " symbol " << symbol->get_data(); - pudding->log(message.str()); + sb::Log::log(message); pudding->current_camera_barcode = symbol->get_data(); pudding->current_barcode = pudding->current_camera_barcode; } @@ -712,7 +715,7 @@ void Pudding::update() SDL_Thread* capture_thread = SDL_CreateThread(Pudding::capture_frame, "capture frame", reinterpret_cast(this)); if (capture_thread == nullptr) { - log("could not create capture thread"); + sb::Log::log("could not create capture thread"); } else { @@ -724,9 +727,9 @@ void Pudding::update() { current_config_barcode = get_configuration()["scan"]["barcode"]; current_barcode = current_config_barcode; - std::stringstream message; + std::ostringstream message; message << "read new barcode from config " << current_barcode; - log(message.str()); + sb::Log::log(message); } /* viewport box will be used to tell GL where to draw */ Box viewport_box = window_box(true); @@ -845,7 +848,7 @@ void Pudding::update() } } SDL_GL_SwapWindow(get_window()); - log_gl_errors(); + sb::Log::gl_errors(); /* add a new item if a new barcode was scanned or entered */ if (current_barcode != previous_barcode) { @@ -868,6 +871,19 @@ void VAO::generate() GLObject::generate(glGenVertexArrays); } +/* Increment the count of attributes with properties stored in this VAO. This will be called if you + * pass this object to the Buffer when adding attribute data. */ +void VAO::increment() +{ + attributes_counted++; +} + +/* Return the number of attributes with properties stored in this VAO counted so far */ +std::uint32_t VAO::counted() const +{ + return attributes_counted; +} + /* This function gets passed to the abstract base class for deleting the VAO data when the ID * pointer goes out of scope (when all instances of this VAO and its copies are out of scope) */ void vao_deleter(GLuint* id) @@ -877,25 +893,37 @@ void vao_deleter(GLuint* id) glDeleteVertexArrays(1, id); } -VBO::VBO() : GLObject(vbo_deleter) {} +Buffer::Buffer() : GLObject(buffer_deleter) {} -/* Bind this VBO to the current GL context */ -void VBO::bind() const -{ - glBindBuffer(GL_ARRAY_BUFFER, id()); -} - -/* Forward the GL buffer generate function to the base class */ -void VBO::generate() +/* Forward the GL generate function to the base class */ +void Buffer::generate() { GLObject::generate(glGenBuffers); } -/* This function gets passed to the abstract base class for deleting the VBO data when the ID - * pointer goes out of scope (when all instances of this VBO and its copies are out of scope) */ -void vbo_deleter(GLuint* id) +/* Set the type of data being held in this buffer */ +void Buffer::target(GLenum target) +{ + buffer_target = target; +} + +/* Return the type of data being held in this buffer as a GLenum */ +GLenum Buffer::target() const +{ + return buffer_target; +} + +/* Bind this Buffer to the current GL context */ +void Buffer::bind() const +{ + glBindBuffer(target(), id()); +} + +/* This function gets passed to the abstract base class for deleting the Buffer data when the ID + * pointer goes out of scope (when all instances of this Buffer and its copies are out of scope) */ +void buffer_deleter(GLuint* id) { /* not sure why SDL_Log works here on program exit but SDL_LogDebug and SDL_LogInfo don't */ - SDL_Log("destroying VBO ID %i", *id); + SDL_Log("destroying buffer ID %i", *id); glDeleteBuffers(1, id); } diff --git a/src/Pudding.hpp b/src/Pudding.hpp index 215e69a..044e75c 100644 --- a/src/Pudding.hpp +++ b/src/Pudding.hpp @@ -10,11 +10,12 @@ #include #include #include +#include #include "SDL.h" #include "SDL_image.h" #include "sdl2-gfx/SDL2_gfxPrimitives.h" #include "json/json.hpp" -#include "glm/vec2.hpp" +#include "glm/glm.hpp" #include "opencv2/core.hpp" #include "opencv2/videoio.hpp" #include "opencv2/highgui.hpp" @@ -27,32 +28,79 @@ #include "Animation.hpp" #include "Texture.hpp" #include "GLObject.hpp" +#include "Log.hpp" class VAO : public GLObject { +private: + + std::uint32_t attributes_counted = 0; + public: VAO(); void generate(); void bind() const; + void increment(); + std::uint32_t counted() const; }; void vao_deleter(GLuint*); -class VBO : public GLObject +class Attributes { +private: + + using Vertices1D = std::vector>; + using Vertices2D = std::vector, glm::defaultp>>; + using Vertices3D = std::vector, glm::defaultp>>; + using Vertices4D = std::vector, glm::defaultp>>; + using Vertices = std::vector>; + std::vector vertices; + public: - VBO(); - void generate(); - void bind() const; + Attributes(); + Attributes(Vertices); + Attributes(std::vector); + void index(int); + int index() const; + void enable() const; }; -void vbo_deleter(GLuint*); +class Buffer : public GLObject +{ + +private: + + GLenum buffer_target, buffer_usage; + std::uint32_t buffer_add_use_count = 0, buffer_calculated_size = 0; + +public: + + Buffer(); + Buffer(GLenum, GLenum); + void generate(); + void target(GLenum); + GLenum target() const; + void bind() const; + void allocate(GLsizeiptr); + void allocate(GLenum, GLenum, GLsizeiptr); + + template + Attributes add(VAO& vao, std::vector vertex_attributes) + { + vao.increment(); + // glVertexAttribPointer(vao.counted(), + } + +}; + +void buffer_deleter(GLuint*); class Pudding : public Game { @@ -107,7 +155,7 @@ private: Texture capture_texture_front_buffer, capture_texture_back_buffer; Texture& capture_texture = capture_texture_front_buffer; VAO vao; - VBO vbo; + Buffer vbo; void set_pudding_model(float, float, int, int = 1, float = -1, float = 1, float = 0.3f); void load_gl_context(); @@ -138,10 +186,6 @@ public: }; -class Attributes -{ -}; - class Model { };