diff --git a/src/Log.cpp b/src/Log.cpp index 16ae684..16a7422 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -72,9 +72,10 @@ bool sb::Log::gl_errors(const std::string& heading) return error_logged; } -void sb::Log::sdl_error(const std::string& message) +std::ostringstream sb::Log::sdl_error(const std::string& message) { std::ostringstream full_message; full_message << message << " " << SDL_GetError(); log(full_message, Level::ERROR); + return full_message; } diff --git a/src/Log.hpp b/src/Log.hpp index b13c4ff..9696f21 100644 --- a/src/Log.hpp +++ b/src/Log.hpp @@ -81,11 +81,12 @@ namespace sb /*! * Log a message, adding the results of `SDL_GetError` to the end of the message. Should be used to add more information to - * an error statement when the error happened in SDL. The priority level will always be `Level::ERROR` + * an error statement when the error happened in SDL. The priority level will always be `Level::ERROR`. * * @param message text to log before the SDL error is appended + * @return a string stream containing the full message */ - static void sdl_error(const std::string& message); + static std::ostringstream sdl_error(const std::string& message = ""); }; diff --git a/src/Pad.hpp b/src/Pad.hpp index efa900a..38b5969 100644 --- a/src/Pad.hpp +++ b/src/Pad.hpp @@ -209,7 +209,7 @@ namespace sb { glUniform1i(texture_flag_uniform.value(), true); } - plane.bind_textures(); + plane.texture().bind(); } else if (texture_flag_uniform.has_value()) { diff --git a/src/Sprite.hpp b/src/Sprite.hpp index 853bd99..fb2d9f3 100644 --- a/src/Sprite.hpp +++ b/src/Sprite.hpp @@ -36,6 +36,9 @@ namespace sb * without having to set all the transformations every time one is changed. */ glm::mat4 _scale {1.0f}, _translation {1.0f}, _rotation {1.0f}; + /* A sprite by definition has only one texture per draw, so keep an index to the currently active texture. */ + int _texture_index = 0; + public: /*! @@ -145,14 +148,31 @@ namespace sb } /*! - * Get a constant reference to the texture attached to the sprite's plane object at the given index . If no index is given, - * get the texture at index 0. If there are no textures, an exception will be thrown. + * Get a constant reference to the texture attached to the sprite's plane object at the object's current texture index. * * @param index index of texture to get */ - const sb::Texture& texture(int index = 0) const + const sb::Texture& texture() const { - return plane.texture(index); + return plane.texture(_texture_index); + } + + /*! + * @param index set the object's texture index + * @return constant reference to the texture at the given index + */ + const sb::Texture& texture_index(int index) + { + _texture_index = index; + return texture(); + } + + /*! + * @return the object's current texture index value + */ + int texture_index() const + { + return _texture_index; } /*! @@ -178,12 +198,13 @@ namespace sb } /*! - * Bind all of this sprite's attributes and textures by calling each of their bind methods. Textures and attributes all must already + * Bind all of this sprite's attributes and its active texture by calling each of their bind methods. Textures and attributes all must already * have GL indices set, for example by calling Texture::generate() and Attributes::index(GLint) on each. */ void bind() { - plane.bind(); + plane.bind_attributes(); + texture().bind(); } /*! @@ -296,7 +317,7 @@ namespace sb { glUniform1i(texture_flag_uniform.value(), true); } - plane.bind_textures(); + texture().bind(); } else if (texture_flag_uniform.has_value()) { diff --git a/src/Text.hpp b/src/Text.hpp index 19845c3..a7cd2e2 100644 --- a/src/Text.hpp +++ b/src/Text.hpp @@ -7,6 +7,7 @@ #include "Model.hpp" #include "Color.hpp" +#include "Log.hpp" namespace sb { diff --git a/src/Texture.cpp b/src/Texture.cpp index e9e7cbc..2895611 100644 --- a/src/Texture.cpp +++ b/src/Texture.cpp @@ -75,10 +75,26 @@ void Texture::load(fs::path path) /* Load file path as a surface object to access pixel data and flip into OpenGL orientation. Attach a destructor so it will free * itself when it goes out of scope at the end of this function. */ std::unique_ptr surface(IMG_Load(path.c_str()), SDL_FreeSurface); - std::unique_ptr flipped_surface(rotozoomSurfaceXY(surface.get(), 0, 1, -1, 0), SDL_FreeSurface); - load(flipped_surface.get()); - message << "Loading image at " << path; - message_level = sb::Log::INFO; + if (surface.get() != nullptr) + { + std::unique_ptr flipped_surface(rotozoomSurfaceXY(surface.get(), 0, 1, -1, 0), SDL_FreeSurface); + if (flipped_surface.get() != nullptr) + { + load(flipped_surface.get()); + message << "Loading image at " << path; + message_level = sb::Log::INFO; + } + else + { + message << "Error flipping image surface at " << path; + throw std::runtime_error(sb::Log::sdl_error(message.str()).str()); + } + } + else + { + message << "Error opening image " << path; + throw std::runtime_error(sb::Log::sdl_error(message.str()).str()); + } } else {