diff --git a/include/cinnabar-render/assets.hpp b/include/cinnabar-render/assets.hpp index e1708654..eaa19fa1 100644 --- a/include/cinnabar-render/assets.hpp +++ b/include/cinnabar-render/assets.hpp @@ -16,11 +16,11 @@ namespace ce { frag = ""; }; struct TextureFile { - unsigned char* data = NULL; - int + unsigned char* data = NULL; // TODO: what type should this actually be? this has been a void* in some areas + GLsizei width = 0, - height = 0, - channelCount = 0; + height = 0; + GLint internalColorSpace = 0; // TODO: is there a better value for this? GL_NONE exists but doesn't seem correct (also make changes in Texture) }; struct MaterialFile { glm::vec4 diff --git a/include/cinnabar-render/texture.hpp b/include/cinnabar-render/texture.hpp index afcc7ea5..dd71572c 100644 --- a/include/cinnabar-render/texture.hpp +++ b/include/cinnabar-render/texture.hpp @@ -7,18 +7,23 @@ namespace ce { class Texture { public: - Texture(std::string filename, GLenum type = GL_TEXTURE_2D) - : Texture(ce::assetManager::getTextureFile(filename), type){}; - Texture(TextureFile textureFile, GLenum type = GL_TEXTURE_2D); - Texture(const void* data, GLsizei width, GLsizei height, GLenum color_space = GL_RGBA, GLenum type = GL_TEXTURE_2D); + Texture(std::string filename, GLenum colorSpace = 0, GLenum target = GL_TEXTURE_2D) { + TextureFile textureFile = ce::assetManager::getTextureFile(filename); + init(textureFile, colorSpace, target); + ce::assetManager::freeTextureFile(textureFile); + }; + Texture(TextureFile textureFile, GLenum colorSpace = 0, GLenum target = GL_TEXTURE_2D) { + init(textureFile, colorSpace, target); + }; ~Texture(); void bind(), unbind(), activate(int slot); private: GLuint m_texture; - int m_width, m_height, m_channelCount; - GLenum m_type; - bool loadData(const void* data, GLsizei width, GLsizei height, GLenum color_space = GL_RGBA, GLenum type = GL_TEXTURE_2D); + GLenum m_target; + + void init(TextureFile textureFile, GLenum colorSpace = 0, GLenum target = GL_TEXTURE_2D); + bool loadData(TextureFile textureFile, GLenum colorSpace = 0, GLenum target = GL_TEXTURE_2D); }; } diff --git a/src/cinnabar-render-demo/main.cpp b/src/cinnabar-render-demo/main.cpp index 3d46fc82..62b62ab3 100644 --- a/src/cinnabar-render-demo/main.cpp +++ b/src/cinnabar-render-demo/main.cpp @@ -150,6 +150,16 @@ int main(int argc, char* argv[]) { window->swapBuffers(); + // error check + // TODO: make this into some function + while (true) { + GLenum tmp = glGetError(); + if (tmp == GL_NO_ERROR) + break; + else + LOG_ERROR("Uncaught GL error: 0x%04x", tmp); + } + // framerate cap time->waitUntilDelta(deltaTimeMin); } diff --git a/src/cinnabar-render/asset_manager.cpp b/src/cinnabar-render/asset_manager.cpp index b3880d1c..12e44fcc 100644 --- a/src/cinnabar-render/asset_manager.cpp +++ b/src/cinnabar-render/asset_manager.cpp @@ -43,12 +43,32 @@ ce::ShaderFile ce::assetManager::getShaderFile(std::string vert, std::string geo ce::TextureFile ce::assetManager::getTextureFile(std::string path) { // stbi_set_flip_vertically_on_load(1); TextureFile textureFile; + int channelCount; textureFile.data = stbi_load( (defaults::RESOURCE_FOLDER + "/" + defaults::TEXTURE_FOLDER + "/" + path).c_str(), &textureFile.width, &textureFile.height, - &textureFile.channelCount, + &channelCount, 0); + + switch (channelCount) { + case 1: + textureFile.internalColorSpace = GL_RED; + break; + case 2: + textureFile.internalColorSpace = GL_RG; + break; + case 3: + textureFile.internalColorSpace = GL_RGB; + break; + case 4: + textureFile.internalColorSpace = GL_RGBA; + break; + default: + LOG_WARN("Unsupported texture channel count: %i", channelCount); + textureFile.data == NULL; + } + if (textureFile.data == NULL) { LOG_WARN("Failed to load texture: %s", path.c_str()); if (path == defaults::TEXTURE_MISSING) @@ -57,6 +77,7 @@ ce::TextureFile ce::assetManager::getTextureFile(std::string path) { return getTextureFile(defaults::TEXTURE_MISSING); } else LOG_SUCCESS("Loaded texture: %s", path.c_str()); + return textureFile; } diff --git a/src/cinnabar-render/texture.cpp b/src/cinnabar-render/texture.cpp index 2538fb78..83e49d44 100644 --- a/src/cinnabar-render/texture.cpp +++ b/src/cinnabar-render/texture.cpp @@ -4,32 +4,15 @@ #include -ce::Texture::Texture(TextureFile textureFile, GLenum type) - : m_width(0), m_height(0), m_channelCount(0), m_type(type) { - m_width = textureFile.width; - m_height = textureFile.height; - m_channelCount = textureFile.channelCount; - +void ce::Texture::init(TextureFile textureFile, GLenum colorSpace, GLenum target) { glGenTextures(1, &m_texture); bind(); - glTexParameteri(type, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(type, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(type, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(type, GL_TEXTURE_MIN_FILTER, GL_REPEAT); - + glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT); // TODO: proper system for setting texture parameters + glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_REPEAT); - if (this->loadData(textureFile.data, textureFile.width, textureFile.height, textureFile.channelCount == 3 ? GL_RGB : GL_RGBA, type)) { - LOG_SUCCESS("Loaded texture"); - } else { - LOG_ERROR("Failed to load texture"); - } - ce::assetManager::freeTextureFile(textureFile); -} - -ce::Texture::Texture(const void* data, GLsizei width, GLsizei height, GLenum color_space, GLenum type) - : m_width(0), m_height(0), m_channelCount(0), m_type(type) { - - if (this->loadData(data, width, height, color_space, type)) { + if (this->loadData(textureFile, colorSpace, target)) { LOG_SUCCESS("Loaded texture"); } else { LOG_ERROR("Failed to load texture"); @@ -41,8 +24,8 @@ ce::Texture::~Texture() { } void ce::Texture::bind() { - glBindTexture(m_type, m_texture); - glEnable(m_type); + glBindTexture(m_target, m_texture); + glEnable(m_target); } void ce::Texture::activate(int slot = 0) { @@ -51,24 +34,34 @@ void ce::Texture::activate(int slot = 0) { } void ce::Texture::unbind() { - glDisable(m_type); + glDisable(m_target); glActiveTexture(0); - glBindTexture(m_type, 0); + glBindTexture(m_target, 0); } -bool ce::Texture::loadData(const void* data, GLsizei width, GLsizei height, GLenum color_space, GLenum type) { - m_width = width; - m_height = height; +bool ce::Texture::loadData(TextureFile textureFile, GLenum colorSpace, GLenum target) { + m_target = target; + if (!colorSpace) + switch (textureFile.internalColorSpace) { + case GL_RED: + case GL_RG: + case GL_RGB: + case GL_RGBA: + colorSpace = textureFile.internalColorSpace; + break; - bool out = false; - bind(); + // TODO: add formats GL_RED_INTEGER, GL_RG_INTEGER, GL_RGB_INTEGER, GL_RGBA_INTEGER, GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL + default: + LOG_WARN("Unrecognized internal color space: %i", textureFile.internalColorSpace); + } - if (data) { - glTexImage2D(type, 0, color_space, m_width, m_height, 0, color_space, - GL_UNSIGNED_BYTE, data); - glGenerateMipmap(type); - out = true; - } - unbind(); - return out; + if (textureFile.data) { + bind(); + glTexImage2D(m_target, 0, textureFile.internalColorSpace, textureFile.width, textureFile.height, 0, colorSpace, + GL_UNSIGNED_BYTE, textureFile.data); + glGenerateMipmap(m_target); + unbind(); + return true; + } else + return false; }