GL texture class; logging functions changed to static
This commit is contained in:
parent
1f8de2f5f1
commit
1a4b8507e3
|
@ -364,7 +364,7 @@ bool Game::link_shader(GLuint program) const
|
||||||
/* Send an info priority message to SDL's log output function, which is overridden by our own member
|
/* Send an info priority message to SDL's log output function, which is overridden by our own member
|
||||||
* function. Category will default to SDL's custom category.
|
* function. Category will default to SDL's custom category.
|
||||||
*/
|
*/
|
||||||
void Game::log(const std::string& message, const int category) const
|
void Game::log(const std::string& message, const int category)
|
||||||
{
|
{
|
||||||
SDL_LogInfo(category, "%s", message.c_str());
|
SDL_LogInfo(category, "%s", message.c_str());
|
||||||
}
|
}
|
||||||
|
@ -373,7 +373,7 @@ void Game::log(const std::string& message, const int category) const
|
||||||
* function. Category will default to SDL's custom category. Using the default category will ensure
|
* function. Category will default to SDL's custom category. Using the default category will ensure
|
||||||
* that debug level statements are handled according to the options in the global configuration.
|
* that debug level statements are handled according to the options in the global configuration.
|
||||||
*/
|
*/
|
||||||
void Game::debug(const std::string& message, const int category) const
|
void Game::debug(const std::string& message, const int category)
|
||||||
{
|
{
|
||||||
SDL_LogDebug(category, "%s", message.c_str());
|
SDL_LogDebug(category, "%s", message.c_str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,10 +95,10 @@ public:
|
||||||
void load_gl_context();
|
void load_gl_context();
|
||||||
GLuint load_shader(const fs::path&, GLenum) const;
|
GLuint load_shader(const fs::path&, GLenum) const;
|
||||||
bool link_shader(GLuint program) const;
|
bool link_shader(GLuint program) const;
|
||||||
void log(const std::string&, const int = DEFAULT_SDL_LOG_CATEGORY) const;
|
static void log(const std::string&, const int = DEFAULT_SDL_LOG_CATEGORY);
|
||||||
void debug(const std::string&, const int = DEFAULT_SDL_LOG_CATEGORY) const;
|
static void debug(const std::string&, const int = DEFAULT_SDL_LOG_CATEGORY);
|
||||||
void log_renderer_info(SDL_RendererInfo&);
|
void log_renderer_info(SDL_RendererInfo&);
|
||||||
bool log_gl_errors(std::string = "");
|
static bool log_gl_errors(std::string = "");
|
||||||
void log_display_mode();
|
void log_display_mode();
|
||||||
void log_surface_format(SDL_Surface*, std::string = "surface");
|
void log_surface_format(SDL_Surface*, std::string = "surface");
|
||||||
std::string get_pixel_format_string(Uint32);
|
std::string get_pixel_format_string(Uint32);
|
||||||
|
|
|
@ -1,10 +1,3 @@
|
||||||
#include <algorithm>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include "Pixels.hpp"
|
|
||||||
#include "Game.hpp"
|
|
||||||
#include "extension.hpp"
|
|
||||||
#include "Game.hpp"
|
|
||||||
#include "Sprite.hpp"
|
#include "Sprite.hpp"
|
||||||
|
|
||||||
Sprite::Sprite() : Sprite(nullptr) {}
|
Sprite::Sprite() : Sprite(nullptr) {}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
#include "SDL_image.h"
|
#include "SDL_image.h"
|
||||||
|
@ -202,4 +203,8 @@ struct Frameset
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include "Pixels.hpp"
|
||||||
|
#include "Game.hpp"
|
||||||
|
#include "extension.hpp"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,144 @@
|
||||||
|
#include "Texture.hpp"
|
||||||
|
|
||||||
|
/* If an image path is passed at creation, the path will be stored in the class for later loading */
|
||||||
|
Texture::Texture(fs::path path)
|
||||||
|
{
|
||||||
|
associate(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store an image path as a member variable for loading later. Each texture should have one image
|
||||||
|
* path (support for multiple mipmap levels may be added later) */
|
||||||
|
void Texture::associate(fs::path path)
|
||||||
|
{
|
||||||
|
this->path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate a GL_TEXTURE_2D texture and allocate GL_RGB8 storage for the given size */
|
||||||
|
void Texture::generate(glm::vec2 size)
|
||||||
|
{
|
||||||
|
GLuint id;
|
||||||
|
glGenTextures(1, &id);
|
||||||
|
this->id(id);
|
||||||
|
bind();
|
||||||
|
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, size.x, size.y);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
Game::log_gl_errors();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns true if an ID has been generated for this Texture */
|
||||||
|
bool Texture::generated() const
|
||||||
|
{
|
||||||
|
return static_cast<bool>(texture_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When called with no parameters, use the stored path variable */
|
||||||
|
void Texture::load()
|
||||||
|
{
|
||||||
|
load(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
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 << ")";
|
||||||
|
Game::log(message.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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())
|
||||||
|
{
|
||||||
|
generate(size);
|
||||||
|
}
|
||||||
|
bind();
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size.x, size.y, format, type, pixels);
|
||||||
|
Game::log_gl_errors();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The texture must have been previously generated with a size to use this generic pixel data load function */
|
||||||
|
void Texture::load(void* pixels, GLenum format, GLenum type)
|
||||||
|
{
|
||||||
|
if (!generated())
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("This texture has not been generated and has no size property, so a size must be provided");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
load(pixels, size(), format, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the shared pointer to point to a new GLuint with specified ID value */
|
||||||
|
void Texture::id(GLuint id)
|
||||||
|
{
|
||||||
|
texture_id = std::shared_ptr<GLuint>(new GLuint, Texture::destroy);
|
||||||
|
*texture_id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the GL texture ID that was set for this texture */
|
||||||
|
GLuint Texture::id() const
|
||||||
|
{
|
||||||
|
return *texture_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::bind() const
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, this->id());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the size in pixels of mipmap level 0 (the only mipmap level supported by this class). If the texture hasn't been,
|
||||||
|
* generated, return {0, 0}. */
|
||||||
|
glm::vec2 Texture::size() const
|
||||||
|
{
|
||||||
|
if (generated())
|
||||||
|
{
|
||||||
|
bind();
|
||||||
|
int width, height;
|
||||||
|
int miplevel = 0;
|
||||||
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, miplevel, GL_TEXTURE_WIDTH, &width);
|
||||||
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, miplevel, GL_TEXTURE_HEIGHT, &height);
|
||||||
|
return {width, height};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return {0, 0};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete this texture, freeing the memory */
|
||||||
|
void Texture::destroy(GLuint* id)
|
||||||
|
{
|
||||||
|
/* not sure why SDL_Log works here but SDL_LogDebug and SDL_LogInfo don't */
|
||||||
|
SDL_Log("destroying texture ID %i", *id);
|
||||||
|
glDeleteTextures(1, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Textures are considered equal if they have the same ID */
|
||||||
|
bool Texture::operator==(const Texture& texture) const
|
||||||
|
{
|
||||||
|
return id() == texture.id();
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/* /\ +--------------------------------------------------------------+
|
||||||
|
____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
|
||||||
|
\ / / | copy, modify and sell without restriction |
|
||||||
|
+--\ ^__^ /--+ | |
|
||||||
|
| ~/ \~ | | - originally created at [http://nugget.fun] |
|
||||||
|
| ~~~~~~~~~~~~ | +--------------------------------------------------------------+
|
||||||
|
| SPACE ~~~~~ | /
|
||||||
|
| ~~~~~~~ BOX |/
|
||||||
|
+--------------+
|
||||||
|
|
||||||
|
[Texture.hpp]
|
||||||
|
|
||||||
|
The Texture class abstracts the file opening, data loading and binding steps of Open GL
|
||||||
|
texture creation. Currently it only supports loading GL_TEXTURE_2D with GL_RGB8 pixels
|
||||||
|
and automatic GL_NEAREST mipmapping. Support may be added for users to pass in their own
|
||||||
|
pixel data, to customize mipmapping, and more.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Texture_h_
|
||||||
|
#define Texture_h_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include "SDL.h"
|
||||||
|
#include "SDL_image.h"
|
||||||
|
#include "sdl2-gfx/SDL2_rotozoom.h"
|
||||||
|
#include "filesystem.hpp"
|
||||||
|
#include "Game.hpp"
|
||||||
|
|
||||||
|
/* include Open GL */
|
||||||
|
#if defined(__EMSCRIPTEN__)
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#else
|
||||||
|
#include "glew/glew.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class Texture
|
||||||
|
{
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
fs::path path = "";
|
||||||
|
std::shared_ptr<GLuint> texture_id = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Texture() {};
|
||||||
|
Texture(fs::path);
|
||||||
|
void associate(fs::path);
|
||||||
|
void generate(glm::vec2);
|
||||||
|
bool generated() const;
|
||||||
|
void load();
|
||||||
|
void load(fs::path);
|
||||||
|
void load(SDL_RWops*);
|
||||||
|
void load(SDL_Surface*);
|
||||||
|
void load(void*, GLenum = GL_RGBA, GLenum = GL_UNSIGNED_BYTE);
|
||||||
|
void load(void*, glm::vec2, GLenum = GL_RGBA, GLenum = GL_UNSIGNED_BYTE);
|
||||||
|
void id(GLuint);
|
||||||
|
GLuint id() const;
|
||||||
|
void bind() const;
|
||||||
|
glm::vec2 size() const;
|
||||||
|
static void destroy(GLuint*);
|
||||||
|
bool operator==(const Texture&) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue