Add a function for reading a sprite's translation. Add functions for reading a text object's foreground, background, and font. Log a warning when the draw function of a sprite containing textures is called but the currently active texture will not be drawn because it has not been generated yet. Line-length linting.
196 lines
7.7 KiB
C++
196 lines
7.7 KiB
C++
/* +=======================================================+
|
|
____/ \____ /: Open source game framework licensed to freely use, :
|
|
\ / / : copy, and modify - created for dank.game :
|
|
+==\ ^__^ /==+ : :
|
|
: ~/ \~ : : Download at https://open.shampoo.ooo/shampoo/spacebox :
|
|
: ~~~~~~~~~~~~ : +=======================================================+
|
|
: SPACE ~~~~~ : /
|
|
: ~~~~~~~ BOX :/
|
|
+=============*/
|
|
|
|
#pragma once
|
|
|
|
#include <sstream>
|
|
#include <stdexcept>
|
|
#include <optional>
|
|
|
|
#include "glm/vec2.hpp"
|
|
#include "SDL.h"
|
|
#include "SDL_image.h"
|
|
#include "sdl2-gfx/SDL2_rotozoom.h"
|
|
|
|
#include "filesystem.hpp"
|
|
#include "GLObject.hpp"
|
|
#include "Log.hpp"
|
|
|
|
namespace sb
|
|
{
|
|
|
|
/*!
|
|
* The Texture class abstracts the image file opening, data loading and binding steps of Open GL texture creation.
|
|
* Currently it supports only the GL_TEXTURE_2D target with one mipmap level. Support for other types of textures
|
|
* may be added in the future.
|
|
*
|
|
* The texture object's ID can be used to pass this texture directly to OpenGL functions.
|
|
*/
|
|
class Texture : public GLObject
|
|
{
|
|
|
|
private:
|
|
|
|
/* An image file path can be set with Texture::allocate(fs::path) and later loaded with Texture::load(). */
|
|
fs::path path = "";
|
|
|
|
/* Size and format are unset until memory for pixel data is allocated. */
|
|
std::optional<glm::vec2> _size;
|
|
std::optional<GLenum> _format;
|
|
|
|
/* The filter will be applied using glTexParameter whenever Texture::generate(glm::vec2, GLenum,
|
|
* std::optional<GLint>) is called without a filter specified. */
|
|
GLint _filter = GL_NEAREST;
|
|
|
|
public:
|
|
|
|
/*!
|
|
* Construct an empty Texture. The deleter will be passed to the base sb::GLObject class.
|
|
*/
|
|
Texture();
|
|
|
|
/*!
|
|
* If an image path is passed at creation, the path will be stored in the class for later loading.
|
|
*
|
|
* @param path path to an image to be used as the default texture, which will be loaded later with
|
|
* Texture::load()
|
|
*/
|
|
Texture(fs::path path);
|
|
|
|
/*!
|
|
* Store an image path as a member variable for loading later. Each texture can have only one image
|
|
* path (support for multiple paths to enable multiple texture mipmap levels may be added later).
|
|
*
|
|
* @param path path to an image that can be loaded by the SDL image library
|
|
*/
|
|
void associate(fs::path path);
|
|
|
|
/*!
|
|
* Set the resize filter of the texture. This must be set before Texture::generate(glm::vec2, GLenum,
|
|
* std::optional<GLint>) is called for it to be applied.
|
|
*
|
|
* @param value Resize filter to use (see `glTexParameter` for options)
|
|
*/
|
|
void filter(GLint value);
|
|
|
|
/*!
|
|
* Forward the GL texture generate function to the base class
|
|
*/
|
|
void generate();
|
|
|
|
/*!
|
|
* Generate a GL_TEXTURE_2D texture ID and allocate the specified format storage for the given size.
|
|
*
|
|
* @param size Width and height of the texture in texels
|
|
* @param format Sized internal format to be used to store texture data (for example, `GL_RGBA8`, `GL_RGB8`)
|
|
* @param filter Resize function to use (see `glTexParameter`). Overrides the value of Texture::filter.
|
|
*/
|
|
void generate(glm::vec2 size, GLenum format = GL_RGBA8, std::optional<GLint> filter = std::nullopt);
|
|
|
|
/*!
|
|
* Load a texture from the path that was previously set.
|
|
*
|
|
* @see ::Texture(fs::path)
|
|
* @see ::associate(fs::path)
|
|
* @see ::load(fs::path)
|
|
*/
|
|
void load();
|
|
|
|
/*!
|
|
* 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.
|
|
*
|
|
* Unless the texture has already been generated, the texture will be generated with storage for the size of the image.
|
|
*
|
|
* @param path Filesystem path to an image file
|
|
*/
|
|
void load(fs::path path);
|
|
|
|
/*!
|
|
* Load texture from an SDL read/write stream object.
|
|
*
|
|
* Unless the texture has already been generated, the texture will be generated with storage for the size of the image.
|
|
*
|
|
* @param rw an SDL read/write object pointing to an image file that will be read for pixel data
|
|
*/
|
|
void load(SDL_RWops* rw);
|
|
|
|
/*!
|
|
* Load texture from an SDL surface.
|
|
*
|
|
* Unless the texture has already been generated, the texture will be generated with storage for the size of the image.
|
|
*
|
|
* @param surface an SDL surface filled with texture pixel data
|
|
*/
|
|
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.
|
|
*
|
|
* Unless the texture has already been generated, the texture will be generated with storage for the size of the
|
|
* image.
|
|
*
|
|
* @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);
|
|
|
|
|
|
/*!
|
|
* @overload load(void* pixels, glm::vec2 size, GLenum format, GLenum type)
|
|
*
|
|
* The texture must have been previously generated with a size to use this generic pixel data load function.
|
|
*
|
|
* see OpenGL's `glTexSubImage2D`
|
|
*
|
|
* @param pixels pointer to pixel data
|
|
* @param format GL format of pixel data (for example, GL_RGBA)
|
|
* @param type data type of the pixel data (for example, GL_UNSIGNED_BYTE if each byte is one of the RGBA values)
|
|
*/
|
|
void load(void* pixels, GLenum format = GL_RGBA, GLenum type = GL_UNSIGNED_BYTE);
|
|
|
|
/*!
|
|
* Return the size in pixels of mipmap level 0 (the only mipmap level supported by this class). If the texture hasn't been
|
|
* generated or loaded with a size given, an exception will be thrown because it currently has no size.
|
|
*
|
|
* @return glm::vec2 A vector consisting of {TEXTURE_MIPMAP_WIDTH, TEXTURE_MIPMAP_HEIGHT}
|
|
*/
|
|
glm::vec2 size() const;
|
|
|
|
/*!
|
|
* Call `glBindTexture`, binding this texture's ID to the target `GL_TEXTURE_2D`. The texture must have previously been
|
|
* generated, using Texture::generate() or Texture::generate(glm::vec2, GLenum, GLint), otherwise an exception will be
|
|
* thrown.
|
|
*
|
|
* > While a texture is bound, GL operations on the target to which it is bound affect the bound texture, and queries of
|
|
* > the target to which it is bound return state from the bound texture. In effect, the texture targets become aliases for
|
|
* > the textures currently bound to them.
|
|
* >
|
|
* > - OpenGL Manual
|
|
*/
|
|
void bind() const override;
|
|
|
|
/*!
|
|
* Textures are considered equal if they have the same ID.
|
|
*
|
|
* @param texture texture to compare this texture to
|
|
*/
|
|
bool operator==(const Texture& texture) const;
|
|
|
|
};
|
|
|
|
void texture_deleter(GLuint*);
|
|
|
|
}
|