texture: Use texture abstraction
This commit is contained in:
parent
c904055632
commit
a60def7a02
|
@ -3,6 +3,7 @@ add_executable(Exponent
|
|||
GLProgramLoader.cc
|
||||
Quad.cc
|
||||
Mesh.cc
|
||||
texture.cc
|
||||
)
|
||||
|
||||
target_link_libraries(Exponent PUBLIC glfw glm::glm ${PNG_LIBRARY})
|
||||
|
|
57
src/Quad.cc
57
src/Quad.cc
|
@ -3,6 +3,7 @@
|
|||
#include "glm/ext/matrix_transform.hpp"
|
||||
#include "glm/gtc/type_ptr.hpp"
|
||||
#include "glm/trigonometric.hpp"
|
||||
#include "src/texture.hh"
|
||||
#include <exception>
|
||||
#include <glm/ext.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
|
@ -23,59 +24,9 @@ Quad::Quad(std::span<float> verts, const Uniform &uniform_data)
|
|||
|
||||
color = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
png_uint_32 width = 0, height = 0;
|
||||
int interlace_type = 0, bit_depth = 0, color_type = 0;
|
||||
|
||||
FILE *fp = fopen("./res/tex/util/missing.png", "rb");
|
||||
png_const_bytep header[8] = {0};
|
||||
|
||||
if (fp == NULL) {
|
||||
spdlog::error("Can't find texture file!");
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
fread(header, 1, 8, fp);
|
||||
|
||||
png_structp png_ptr =
|
||||
png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
|
||||
setjmp(png_jmpbuf(png_ptr));
|
||||
|
||||
png_init_io(png_ptr, fp);
|
||||
png_set_sig_bytes(png_ptr, 8);
|
||||
|
||||
png_read_png(png_ptr, info_ptr,
|
||||
PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING |
|
||||
PNG_TRANSFORM_EXPAND,
|
||||
NULL);
|
||||
|
||||
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
|
||||
&interlace_type, NULL, NULL);
|
||||
|
||||
setjmp(png_jmpbuf(png_ptr));
|
||||
|
||||
png_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);
|
||||
size_t data_length = rowbytes * height;
|
||||
|
||||
png_byte *data = (png_byte *)malloc(data_length);
|
||||
|
||||
png_bytepp row_pointers = png_get_rows(png_ptr, info_ptr);
|
||||
|
||||
for (int x = 0; x < height; x++) {
|
||||
memcpy(data + (rowbytes * (height - x - 1)), row_pointers[x], rowbytes);
|
||||
}
|
||||
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
fclose(fp);
|
||||
|
||||
glGenTextures(1, &tex_id);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, tex_id);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,
|
||||
GL_UNSIGNED_BYTE, data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
tex_id = TextureLoader::get_instance()
|
||||
->load_texture("./res/tex/util/missing.png")
|
||||
->get_texture_id();
|
||||
}
|
||||
|
||||
glm::vec2 Quad::get_position_vector() { return glm::vec2(m_pos_x, m_pos_y); }
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
#include "texture.hh"
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <exception>
|
||||
#include <glad/gl.h>
|
||||
#include <png.h>
|
||||
#include <pngconf.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
TextureLoader *TextureLoader::m_instance = NULL;
|
||||
|
||||
TextureLoader *TextureLoader::get_instance() {
|
||||
if (m_instance == NULL) {
|
||||
m_instance = new TextureLoader();
|
||||
}
|
||||
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
TextureLoader::TextureLoader() { m_texture_cache.clear(); }
|
||||
|
||||
TextureLoader::~TextureLoader() {
|
||||
for (std::pair<std::string, Texture *> st : m_texture_cache) {
|
||||
delete (st.second);
|
||||
}
|
||||
}
|
||||
|
||||
Texture *TextureLoader::load_texture(const std::string &path) {
|
||||
// Cache Hit
|
||||
if (m_texture_cache.contains(path)) {
|
||||
return m_texture_cache.at(path);
|
||||
}
|
||||
|
||||
// Cache miss - we have to load it and create it
|
||||
m_texture_cache.emplace(std::make_pair(path, new Texture(path)));
|
||||
|
||||
return m_texture_cache.at(path);
|
||||
}
|
||||
|
||||
Texture::Texture(const std::string &path) {
|
||||
png_uint_32 width = 0, height = 0;
|
||||
int interlace_type = 0, bit_depth = 0, color_type = 0;
|
||||
|
||||
spdlog::trace("Creating texture with path {}");
|
||||
|
||||
// First - check the path actually exists
|
||||
FILE *fp = fopen(path.c_str(), "rb");
|
||||
|
||||
if (fp == NULL) {
|
||||
spdlog::error("Cant find texture at path {}", path);
|
||||
// TODO Make my own exception for this and log it upstream
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
png_byte header[4] = {0};
|
||||
|
||||
fread(header, 1, 4, fp);
|
||||
|
||||
// I'm not sure why this cast has to be there but clangd doesn't like it not
|
||||
// being there...
|
||||
// FIXME: for some reason, this fails.
|
||||
/*
|
||||
if (!png_sig_cmp(header, 0, 4)) {
|
||||
spdlog::error("Texture file {} does not appear to be a png file.", path);
|
||||
|
||||
throw std::exception();
|
||||
}
|
||||
*/
|
||||
|
||||
png_structp png_ptr =
|
||||
png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
|
||||
setjmp(png_jmpbuf(png_ptr));
|
||||
|
||||
png_init_io(png_ptr, fp);
|
||||
png_set_sig_bytes(png_ptr, 4);
|
||||
|
||||
png_read_png(png_ptr, info_ptr,
|
||||
PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING |
|
||||
PNG_TRANSFORM_EXPAND,
|
||||
NULL);
|
||||
|
||||
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
|
||||
&interlace_type, NULL, NULL);
|
||||
|
||||
setjmp(png_jmpbuf(png_ptr));
|
||||
|
||||
png_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);
|
||||
size_t data_length = rowbytes * height;
|
||||
|
||||
png_byte *data = (png_byte *)malloc(data_length);
|
||||
|
||||
png_bytepp row_pointers = png_get_rows(png_ptr, info_ptr);
|
||||
|
||||
for (int x = 0; x < height; x++) {
|
||||
memcpy(data + (rowbytes * (height - x - 1)), row_pointers[x], rowbytes);
|
||||
}
|
||||
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
fclose(fp);
|
||||
|
||||
glGenTextures(1, &m_gl_texture_id);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_gl_texture_id);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,
|
||||
GL_UNSIGNED_BYTE, data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
Texture::~Texture() {
|
||||
spdlog::trace("Deleting texture id {}", m_gl_texture_id);
|
||||
|
||||
glDeleteTextures(1, &m_gl_texture_id);
|
||||
}
|
||||
|
||||
GLuint Texture::get_texture_id() { return m_gl_texture_id; }
|
|
@ -0,0 +1,35 @@
|
|||
#pragma once
|
||||
|
||||
#include <glad/gl.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
class Texture {
|
||||
private:
|
||||
GLuint m_gl_texture_id;
|
||||
|
||||
public:
|
||||
Texture(const std::string &path);
|
||||
~Texture();
|
||||
Texture(const Texture &t) = delete;
|
||||
|
||||
GLuint get_texture_id();
|
||||
};
|
||||
|
||||
class TextureLoader {
|
||||
private:
|
||||
static TextureLoader *m_instance;
|
||||
|
||||
std::unordered_map<std::string, Texture *> m_texture_cache;
|
||||
|
||||
TextureLoader();
|
||||
~TextureLoader();
|
||||
|
||||
public:
|
||||
Texture *load_texture(const std::string &path);
|
||||
static TextureLoader *get_instance();
|
||||
|
||||
TextureLoader(const TextureLoader &tl) = delete;
|
||||
};
|
Loading…
Reference in New Issue