#include namespace ImGui { ImageDisplay::ImageDisplay(int width, int height) { _width = width; _height = height; buffer = malloc(_width * _height * 4); activeBuffer = malloc(_width * _height * 4); memset(buffer, 0, _width * _height * 4); memset(activeBuffer, 0, _width * _height * 4); glGenTextures(1, &textureId); } ImageDisplay::~ImageDisplay() { free(buffer); free(activeBuffer); } void ImageDisplay::draw(const ImVec2& size_arg) { std::lock_guard lck(bufferMtx); ImGuiWindow* window = GetCurrentWindow(); ImGuiStyle& style = GetStyle(); ImVec2 min = window->DC.CursorPos; // Calculate scale float width = CalcItemWidth(); float height = roundf((width / (float)_width) * (float)_height); ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), height); ImRect bb(min, ImVec2(min.x + size.x, min.y + size.y)); ItemSize(size, style.FramePadding.y); if (!ItemAdd(bb, 0)) { return; } if (newData) { newData = false; updateTexture(); } window->DrawList->AddImage((void*)(intptr_t)textureId, min, ImVec2(min.x + width, min.y + height)); } void ImageDisplay::swap() { std::lock_guard lck(bufferMtx); void* tmp = activeBuffer; activeBuffer = buffer; buffer = tmp; newData = true; memset(buffer, 0, _width * _height * 4); } void ImageDisplay::updateTexture() { glBindTexture(GL_TEXTURE_2D, textureId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _width, _height, 0, GL_RGBA, GL_UNSIGNED_BYTE, activeBuffer); } }