argument checking for texture load function input

This commit is contained in:
frank 2022-09-19 22:14:31 -04:00
parent 60acb11d41
commit 24f6d3ed3d
2 changed files with 102 additions and 24 deletions

View File

@ -44,51 +44,90 @@ void Texture::generate(glm::vec2 size)
sb::Log::gl_errors();
}
/* When called with no parameters, use the stored path variable */
void Texture::load()
{
load(path);
if (!path.empty())
{
load(path);
}
else
{
std::ostringstream message;
message << "Cannot load, no path has been specified yet for texture " << id();
sb::Log::log(message, sb::Log::WARN);
}
}
/* Create an SDL Surface from the supplied path and forward it to the loading function which accepts
* a surface pointer */
void Texture::load(fs::path path)
{
/* open path as surface which will free itself when it goes out of scope (at the end of this function) */
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);
load(flipped_surface.get());
std::ostringstream message;
sb::Log::Level message_level;
if (path.has_filename())
{
/* 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<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);
load(flipped_surface.get());
message << "Loading image at " << path;
message_level = sb::Log::INFO;
}
else
{
message << "Cannot load, " << path << " is not a vaild path to a file";
message_level = sb::Log::WARN;
}
sb::Log::log(message, message_level);
}
/* Create an SDL Surface from the supplied RW pointer and forward it to the loading function which accepts
* a surface pointer */
void Texture::load(SDL_RWops* rw)
{
/* load RW as an SDL surface to translate image format into pixel data, flip, and get dimensions */
/* Load RW object as 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<SDL_Surface, decltype(&SDL_FreeSurface)> surface(IMG_Load_RW(rw, 0), SDL_FreeSurface);
std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> flipped_surface(rotozoomSurfaceXY(surface.get(), 0, 1, -1, 0), SDL_FreeSurface);
load(flipped_surface.get());
}
/* Forward pixels and size to the generic pixel loading function */
void Texture::load(SDL_Surface* surface)
{
load(surface->pixels, {surface->w, surface->h}, GL_RGBA, GL_UNSIGNED_BYTE);
std::ostringstream message;
message << "loaded " << path << " (" << surface->w << "x" << surface->h << ", " <<
SDL_GetPixelFormatName(surface->format->format) << ")";
sb::Log::log(message);
sb::Log::Level message_level;
if (surface->w > 0 && surface->h > 0)
{
message << "Loading image from SDL surface (" << surface->w << "×" << surface->h << ", " << SDL_GetPixelFormatName(surface->format->format) << ")";
load(surface->pixels, {surface->w, surface->h}, GL_RGBA, GL_UNSIGNED_BYTE);
message_level = sb::Log::INFO;
}
else
{
message << "Cannot load into texture, invalid image data without dimensions found";
message_level = sb::Log::WARN;
}
sb::Log::log(message, message_level);
}
/* Bind texture and load pixel data using this class's generated ID */
void Texture::load(void* pixels, glm::vec2 size, GLenum format, GLenum type)
{
if (!generated())
std::ostringstream message;
sb::Log::Level message_level;
if (size.x > 0 && size.y > 0)
{
generate(size);
if (!generated())
{
generate(size);
}
bind();
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size.x, size.y, format, type, pixels);
message << "Loaded " << size.x << "×" << size.y << " image into texture ID " << id();
message_level = sb::Log::INFO;
}
bind();
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size.x, size.y, format, type, pixels);
else
{
message << "Cannot load pixels with zero or negative size in either dimension";
message_level = sb::Log::WARN;
}
sb::Log::log(message, message_level);
sb::Log::gl_errors("after loading texture");
}

View File

@ -49,10 +49,49 @@ namespace sb
void associate(fs::path);
void generate();
void generate(glm::vec2);
/*!
* @overload load(fs::path path)
*
* Load a texture from the path that was set on this object at initialization.
*
* @see Texture(fs::path)
*/
void load();
void load(fs::path);
void load(SDL_RWops*);
void load(SDL_Surface*);
/*!
* @overload load(SDL_Surface* surface)
*
* Load a texture from a path to an image file. This will create an SDL Surface from the image file at a given path and forward it
* to the load overload which accepts a surface pointer.
*
* @param path Filesystem path to an image file
*/
void load(fs::path path);
/*!
* @overload load(SDL_Surface* surface)
*
* Load texture from an SDL RW stream
*/
void load(SDL_RWops* rw);
/*!
* @overload load(void* pixels, glm::vec2 size, GLenum format, GLenum type)
*
* Load texture from an SDL surface
*/
void load(SDL_Surface* surface);
/*!
* Load raw pixel data into texture using OpenGL's `glTexSubImage2D`. The format and type determine how the data will be loaded.
* The format is the pixel format, and the type is the type of the data.
*
* @param pixels Raw pointer to pixel data memory. The type of data pointed to should be given to the format argument.
* @param size Dimensions of the image
* @param format Format of each pixel
* @param type Type pointed to by the pixel data pointer
*/
void load(void* pixels, glm::vec2 size, GLenum format = GL_RGBA, GLenum type = GL_UNSIGNED_BYTE);
#ifndef __EMSCRIPTEN__