#include "texture.h" #include "YBaseLib/Assert.h" #include "YBaseLib/Log.h" Log_SetChannel(GL); namespace GL { Texture::Texture() = default; Texture::Texture(Texture&& moved) : m_id(moved.m_id), m_width(moved.m_width), m_height(moved.m_height), m_fbo_id(moved.m_fbo_id) { moved.m_id = 0; moved.m_width = 0; moved.m_height = 0; moved.m_fbo_id = 0; } Texture::~Texture() { Destroy(); } bool Texture::Create(u32 width, u32 height, GLenum format, GLenum type, const void* data, bool linear_filter) { glGetError(); GLuint id; glGenTextures(1, &id); glBindTexture(GL_TEXTURE_2D, id); glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, type, data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); GLenum error = glGetError(); if (error != GL_NO_ERROR) { Log_ErrorPrintf("Failed to create texture: 0x%X", error); glDeleteTextures(1, &id); return false; } if (IsValid()) Destroy(); m_id = id; m_width = width; m_height = height; return true; } void Texture::SetLinearFilter(bool enabled) { Bind(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, enabled ? GL_LINEAR : GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, enabled ? GL_LINEAR : GL_NEAREST); } bool Texture::CreateFramebuffer() { if (!IsValid()) return false; glGetError(); GLuint fbo_id; glGenFramebuffers(1, &fbo_id); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_id, 0); if (glGetError() != GL_NO_ERROR || glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { glDeleteFramebuffers(1, &fbo_id); return false; } if (m_fbo_id != 0) glDeleteFramebuffers(1, &m_fbo_id); m_fbo_id = fbo_id; return true; } void Texture::Destroy() { if (m_fbo_id != 0) { glDeleteFramebuffers(1, &m_fbo_id); m_fbo_id = 0; } if (m_id != 0) { glDeleteTextures(1, &m_id); m_id = 0; } m_width = 0; m_height = 0; } void Texture::Bind() { glBindTexture(GL_TEXTURE_2D, m_id); } void Texture::BindFramebuffer(GLenum target /*= GL_DRAW_FRAMEBUFFER*/) { DebugAssert(m_fbo_id != 0); glBindFramebuffer(target, m_fbo_id); } void Texture::Unbind() { glBindTexture(GL_TEXTURE_2D, 0); } Texture& Texture::operator=(Texture&& moved) { Destroy(); m_id = moved.m_id; m_width = moved.m_width; m_height = moved.m_height; m_fbo_id = moved.m_fbo_id; moved.m_id = 0; moved.m_width = 0; moved.m_height = 0; moved.m_fbo_id = 0; return *this; } } // namespace GL