mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-28 07:47:03 -05:00
fix: OpenGL textures not being cleaned up correctly
This commit is contained in:
@@ -31,27 +31,40 @@ enum ImGuiCustomCol {
|
||||
|
||||
namespace ImGui {
|
||||
|
||||
struct Texture {
|
||||
ImTextureID textureId = nullptr;
|
||||
int width = 0, height = 0;
|
||||
class Texture {
|
||||
public:
|
||||
Texture() = default;
|
||||
Texture(const ImU8 *buffer, int size);
|
||||
Texture(const char *path);
|
||||
Texture(const Texture&) = delete;
|
||||
Texture(Texture&& other) noexcept;
|
||||
|
||||
[[nodiscard]] constexpr bool valid() const noexcept {
|
||||
return this->textureId != nullptr;
|
||||
~Texture();
|
||||
|
||||
void operator=(const Texture&) = delete;
|
||||
void operator=(Texture&& other) noexcept;
|
||||
|
||||
[[nodiscard]] constexpr bool isValid() const noexcept {
|
||||
return this->m_textureId != nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr operator ImTextureID() {
|
||||
return this->textureId;
|
||||
return this->m_textureId;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto size() const noexcept {
|
||||
return ImVec2(this->width, this->height);
|
||||
[[nodiscard]] auto getSize() const noexcept {
|
||||
return ImVec2(this->m_width, this->m_height);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto aspectRatio() const noexcept {
|
||||
if (this->height == 0) return 1.0F;
|
||||
[[nodiscard]] constexpr auto getAspectRatio() const noexcept {
|
||||
if (this->m_height == 0) return 1.0F;
|
||||
|
||||
return float(this->width) / float(this->height);
|
||||
return float(this->m_width) / float(this->m_height);
|
||||
}
|
||||
|
||||
private:
|
||||
ImTextureID m_textureId = nullptr;
|
||||
int m_width = 0, m_height = 0;
|
||||
};
|
||||
|
||||
int UpdateStringSizeCallback(ImGuiInputTextCallbackData *data);
|
||||
@@ -82,10 +95,6 @@ namespace ImGui {
|
||||
return static_cast<ImU32>(ImGui::GetTime() * 100) % 100 <= static_cast<ImU32>(ImGui::GetIO().DeltaTime * 100);
|
||||
}
|
||||
|
||||
Texture LoadImageFromPath(const char *path);
|
||||
Texture LoadImageFromMemory(const ImU8 *buffer, int size);
|
||||
void UnloadImage(Texture &texture);
|
||||
|
||||
void OpenPopupInWindow(const char *window_name, const char *popup_name);
|
||||
|
||||
struct ImHexCustomData {
|
||||
|
||||
@@ -17,6 +17,74 @@
|
||||
|
||||
namespace ImGui {
|
||||
|
||||
Texture::Texture(const ImU8 *buffer, int size) {
|
||||
unsigned char *imageData = stbi_load_from_memory(buffer, size, &this->m_width, &this->m_height, nullptr, 4);
|
||||
if (imageData == nullptr)
|
||||
return;
|
||||
|
||||
GLuint texture;
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
#if defined(GL_UNPACK_ROW_LENGTH)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->m_width, this->m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
|
||||
stbi_image_free(imageData);
|
||||
|
||||
this->m_textureId = reinterpret_cast<ImTextureID>(static_cast<intptr_t>(texture));
|
||||
}
|
||||
|
||||
Texture::Texture(const char *path) {
|
||||
unsigned char *imageData = stbi_load(path, &this->m_width, &this->m_height, nullptr, 4);
|
||||
if (imageData == nullptr)
|
||||
return;
|
||||
|
||||
GLuint texture;
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
#if defined(GL_UNPACK_ROW_LENGTH)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->m_width, this->m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
|
||||
stbi_image_free(imageData);
|
||||
|
||||
this->m_textureId = reinterpret_cast<ImTextureID>(static_cast<intptr_t>(texture));
|
||||
}
|
||||
|
||||
Texture::Texture(Texture&& other) noexcept {
|
||||
this->m_textureId = other.m_textureId;
|
||||
this->m_width = other.m_width;
|
||||
this->m_height = other.m_height;
|
||||
|
||||
other.m_textureId = nullptr;
|
||||
}
|
||||
|
||||
void Texture::operator=(Texture&& other) noexcept {
|
||||
this->m_textureId = other.m_textureId;
|
||||
this->m_width = other.m_width;
|
||||
this->m_height = other.m_height;
|
||||
|
||||
other.m_textureId = nullptr;
|
||||
}
|
||||
|
||||
Texture::~Texture() {
|
||||
if (this->m_textureId == nullptr)
|
||||
return;
|
||||
|
||||
auto glTextureId = static_cast<GLuint>(reinterpret_cast<intptr_t>(this->m_textureId));
|
||||
glDeleteTextures(1, &glTextureId);
|
||||
}
|
||||
|
||||
int UpdateStringSizeCallback(ImGuiInputTextCallbackData *data) {
|
||||
if (data->EventFlag == ImGuiInputTextFlags_CallbackResize) {
|
||||
auto &string = *static_cast<std::string *>(data->UserData);
|
||||
@@ -298,66 +366,6 @@ namespace ImGui {
|
||||
colors[ImGuiCustomCol_Highlight] = ImColor(77, 198, 155);
|
||||
}
|
||||
|
||||
Texture LoadImageFromPath(const char *path) {
|
||||
int imageWidth = 0;
|
||||
int imageHeight = 0;
|
||||
|
||||
unsigned char *imageData = stbi_load(path, &imageWidth, &imageHeight, nullptr, 4);
|
||||
if (imageData == nullptr)
|
||||
return { nullptr, -1, -1 };
|
||||
|
||||
|
||||
GLuint texture;
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
#if defined(GL_UNPACK_ROW_LENGTH)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
#endif
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
|
||||
stbi_image_free(imageData);
|
||||
|
||||
return { reinterpret_cast<ImTextureID>(static_cast<intptr_t>(texture)), imageWidth, imageHeight };
|
||||
}
|
||||
|
||||
Texture LoadImageFromMemory(const ImU8 *buffer, int size) {
|
||||
int imageWidth = 0;
|
||||
int imageHeight = 0;
|
||||
|
||||
|
||||
unsigned char *imageData = stbi_load_from_memory(buffer, size, &imageWidth, &imageHeight, nullptr, 4);
|
||||
if (imageData == nullptr)
|
||||
return { nullptr, -1, -1 };
|
||||
|
||||
GLuint texture;
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
#if defined(GL_UNPACK_ROW_LENGTH)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
#endif
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
|
||||
stbi_image_free(imageData);
|
||||
|
||||
return { reinterpret_cast<ImTextureID>(static_cast<intptr_t>(texture)), imageWidth, imageHeight };
|
||||
}
|
||||
|
||||
void UnloadImage(Texture &texture) {
|
||||
if (texture.textureId == nullptr)
|
||||
return;
|
||||
|
||||
auto glTextureId = static_cast<GLuint>(reinterpret_cast<intptr_t>(texture.textureId));
|
||||
glDeleteTextures(1, &glTextureId);
|
||||
|
||||
texture = { nullptr, 0, 0 };
|
||||
}
|
||||
|
||||
void OpenPopupInWindow(const char *window_name, const char *popup_name) {
|
||||
if (ImGui::Begin(window_name)) {
|
||||
ImGui::OpenPopup(popup_name);
|
||||
|
||||
Reference in New Issue
Block a user