texture: Use texture abstraction
This commit is contained in:
parent
c904055632
commit
a60def7a02
|
@ -3,6 +3,7 @@ add_executable(Exponent
|
||||||
GLProgramLoader.cc
|
GLProgramLoader.cc
|
||||||
Quad.cc
|
Quad.cc
|
||||||
Mesh.cc
|
Mesh.cc
|
||||||
|
texture.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(Exponent PUBLIC glfw glm::glm ${PNG_LIBRARY})
|
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/ext/matrix_transform.hpp"
|
||||||
#include "glm/gtc/type_ptr.hpp"
|
#include "glm/gtc/type_ptr.hpp"
|
||||||
#include "glm/trigonometric.hpp"
|
#include "glm/trigonometric.hpp"
|
||||||
|
#include "src/texture.hh"
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <glm/ext.hpp>
|
#include <glm/ext.hpp>
|
||||||
#include <glm/glm.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);
|
color = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
png_uint_32 width = 0, height = 0;
|
tex_id = TextureLoader::get_instance()
|
||||||
int interlace_type = 0, bit_depth = 0, color_type = 0;
|
->load_texture("./res/tex/util/missing.png")
|
||||||
|
->get_texture_id();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 Quad::get_position_vector() { return glm::vec2(m_pos_x, m_pos_y); }
|
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