5.ImGui-按钮

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!

本次游戏没法给

内容参考于:微尘网络安全

上一个内容:4.ImGui-静态文本框

按钮的代码

ImGui::Button("anNiu")

修改按钮的颜色,鼠标放上去的颜色,鼠标点击的颜色,鼠标未放上去的颜色

  // ImGui中通过PushStyleColor()临时修改按钮在不同状态下的颜色
  // 注意:每次PushStyleColor()后必须用PopStyleColor()恢复默认样式,否则会影响后续UI元素

  // 1. 修改按钮"正常状态"(未被鼠标悬停、未被点击)的背景色
  // 参数1:ImGuiCol_Button - 指定修改"按钮正常状态"的颜色
  // 参数2:{1.0f, 1.0f, 0.0f, 1.0f} - RGBA颜色值(每个分量范围0.0f~1.0f)
  //   R=1.0f(红色满值)、G=1.0f(绿色满值)、B=0.0f(蓝色无)→ 混合为黄色
  //   A=1.0f(透明度100%,完全不透明)
  ImGui::PushStyleColor(ImGuiCol_Button, { 1.0f,1.0f,0.0f, 1.0f });

  // 2. 修改按钮"鼠标悬停状态"(鼠标放在按钮上但未点击)的背景色
  // 参数1:ImGuiCol_ButtonHovered - 指定修改"按钮被悬停时"的颜色
  // 参数2:{1.0f, 0.0f, 0.0f, 1.0f} → 红色(R满值,G、B无),完全不透明
  ImGui::PushStyleColor(ImGuiCol_ButtonHovered, { 1.0f,0.0f,0.0f, 1.0f });

  // 3. 修改按钮"激活状态"(鼠标按下按钮但未松开)的背景色
  // 参数1:ImGuiCol_ButtonActive - 指定修改"按钮被点击时"的颜色
  // 参数2:{0.0f, 1.0f, 0.0f, 1.0f} → 绿色(G满值,R、B无),完全不透明
  ImGui::PushStyleColor(ImGuiCol_ButtonActive, { 0.0f,1.0f,0.0f, 1.0f });

完整代码

#include "main.h"  // 包含程序所需的头文件(包含ImGui、DirectX等声明,具体内容在main.h中定义)


// 全局变量:存储DirectX 11核心资源和窗口状态(整个程序共享,方便各函数访问)
static UINT                     g_ResizeWidth = 0, g_ResizeHeight = 0; // 窗口调整大小时的新宽高(由消息处理函数记录,主循环处理)
static ID3D11Device* g_pd3dDevice = nullptr;                          // D3D11设备对象(核心!用于创建纹理、缓冲区等渲染资源)
static ID3D11DeviceContext* g_pd3dDeviceContext = nullptr;             // D3D11设备上下文(用于执行绘制、清空等渲染命令)
static IDXGISwapChain* g_pSwapChain = nullptr;                          // 交换链(双缓冲区机制,避免画面闪烁,负责显示渲染结果)
static ID3D11RenderTargetView* g_mainRenderTargetView = nullptr;        // 主渲染目标视图(绑定交换链的后台缓冲区,ImGui绘制的内容会输出到这里)
static bool                     g_SwapChainOccluded = false;           // 标记交换链是否被遮挡(如窗口被覆盖,用于优化性能)


// 声明ImGui的Win32消息处理函数(来自imgui_impl_win32.cpp,用于让ImGui处理鼠标/键盘输入)
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

static void HelpMarker(const char* desc)
{
    ImGui::TextDisabled("(?)");
    if (ImGui::BeginItemTooltip())
    {
        ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
        ImGui::TextUnformatted(desc);
        ImGui::PopTextWrapPos();
        ImGui::EndTooltip();
    }
}

// 窗口消息处理函数:处理所有窗口事件(如点击、关闭、调整大小等)
// 参数:
// - hWnd:窗口句柄(标识当前窗口)
// - msg:消息类型(如WM_SIZE表示窗口大小改变)
// - wParam:消息附加参数(如WM_SIZE中表示 resize 类型)
// - lParam:消息附加参数(如WM_SIZE中存储新的宽高)
// 返回值:LRESULT类型(消息处理结果,0表示成功处理)
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    // 让ImGui先处理消息(如果是ImGui的UI控件触发的事件,优先由ImGui处理)
    if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
        return true;  // ImGui已处理,直接返回

    // 根据消息类型处理不同事件
    switch (msg)
    {
    case WM_SIZE:  // 窗口大小改变事件
        if (wParam == SIZE_MINIMIZED)  // 如果是窗口最小化,无需处理渲染相关
            return 0;
        // 从lParam中提取新的窗口尺寸:低16位是宽度,高16位是高度
        g_ResizeWidth = (UINT)LOWORD(lParam);  // 记录新宽度
        g_ResizeHeight = (UINT)HIWORD(lParam); // 记录新高度
        return 0;

    case WM_SYSCOMMAND:  // 系统命令事件(如ALT+空格调出窗口菜单)
        // 禁用ALT菜单(避免菜单遮挡ImGui控件,影响操作体验)
        if ((wParam & 0xfff0) == SC_KEYMENU)
            return 0;
        break;  // 其他系统命令交给默认处理

    case WM_DESTROY:  // 窗口销毁事件(如点击关闭按钮)
        ::PostQuitMessage(0);  // 发送退出消息,主循环会捕获并结束程序
        return 0;
    }

    // 其他未处理的消息,交给Windows系统默认处理
    return ::DefWindowProcW(hWnd, msg, wParam, lParam);
}


// 创建渲染目标视图:将交换链的后台缓冲区绑定为渲染目标(ImGui绘制的内容会输出到这里)
void CreateRenderTarget()
{
    ID3D11Texture2D* pBackBuffer = nullptr;  // 临时存储交换链的后台缓冲区

    // 从交换链获取后台缓冲区(参数0表示第一个缓冲区,IID_ID3D11Texture2D指定缓冲区类型)
    g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
    // 用D3D设备创建渲染目标视图(将后台缓冲区转换为可渲染的目标)
    g_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &g_mainRenderTargetView);
    // 释放临时缓冲区(渲染目标视图已引用它,无需保留此指针)
    pBackBuffer->Release();
}


// 清理渲染目标视图:释放资源,避免内存泄漏
void CleanupRenderTarget()
{
    // 释放渲染目标视图(COM对象需调用Release()减少引用计数,为0时自动释放内存)
    if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = nullptr; }
}


// 创建D3D11设备和交换链:初始化DirectX渲染环境
// 参数:hWnd - 窗口句柄(渲染结果会显示在这个窗口)
// 返回值:bool - 成功创建返回true,失败返回false
bool CreateDeviceD3D(HWND hWnd)
{
    // 初始化交换链描述(定义交换链的属性,告诉系统如何创建交换链)
    DXGI_SWAP_CHAIN_DESC sd;
    ZeroMemory(&sd, sizeof(sd));  // 清空结构体,避免随机值导致错误
    sd.BufferCount = 2;           // 缓冲区数量(2=双缓冲,避免画面闪烁)
    sd.BufferDesc.Width = 0;      // 缓冲区宽度(0=自动匹配窗口宽度)
    sd.BufferDesc.Height = 0;     // 缓冲区高度(0=自动匹配窗口高度)
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;  // 像素格式(32位色,含透明度)
    sd.BufferDesc.RefreshRate.Numerator = 60;  // 刷新率分子(60=60Hz)
    sd.BufferDesc.RefreshRate.Denominator = 1; // 刷新率分母(60/1=60Hz)
    sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;  // 允许切换显示模式(如全屏/窗口)
    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;   // 缓冲区用途(作为渲染目标)
    sd.OutputWindow = hWnd;       // 绑定的窗口(渲染结果显示到该窗口)
    sd.SampleDesc.Count = 1;      // 多重采样数量(1=无抗锯齿,性能优先)
    sd.SampleDesc.Quality = 0;    // 采样质量(0=默认)
    sd.Windowed = TRUE;           // 窗口模式(TRUE=窗口,FALSE=全屏)
    sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;  // 交换效果(交换后丢弃后台数据,性能最好)

    UINT createDeviceFlags = 0;   // 创建设备的标志(0=默认,调试时可加D3D11_CREATE_DEVICE_DEBUG)
    // createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;  // 调试模式(需安装DirectX SDK)

    D3D_FEATURE_LEVEL featureLevel;  // 存储实际支持的D3D版本(如11.0、10.0)
    // 支持的D3D版本列表(优先11.0,不支持则用10.0)
    const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, };

    // 创建设备、设备上下文和交换链(DirectX核心函数)
    HRESULT res = D3D11CreateDeviceAndSwapChain(
        nullptr, D3D_DRIVER_TYPE_HARDWARE,  // 使用硬件加速(显卡渲染)
        nullptr, createDeviceFlags,         // 无软件渲染模块,创建标志
        featureLevelArray, 2,               // 支持的D3D版本列表及数量
        D3D11_SDK_VERSION, &sd,             // SDK版本,交换链描述
        &g_pSwapChain, &g_pd3dDevice,       // 输出交换链和设备
        &featureLevel, &g_pd3dDeviceContext // 输出支持的版本和设备上下文
    );

    // 如果硬件加速失败(如显卡不支持D3D11),尝试软件渲染(WARP驱动)
    if (res == DXGI_ERROR_UNSUPPORTED)
        res = D3D11CreateDeviceAndSwapChain(
            nullptr, D3D_DRIVER_TYPE_WARP,   // 软件渲染(性能较差,兼容旧设备)
            nullptr, createDeviceFlags,
            featureLevelArray, 2,
            D3D11_SDK_VERSION, &sd,
            &g_pSwapChain, &g_pd3dDevice,
            &featureLevel, &g_pd3dDeviceContext
        );

    if (res != S_OK)  // 创建失败(S_OK表示成功)
        return false;

    CreateRenderTarget();  // 创建渲染目标视图
    return true;
}


// 清理D3D资源:释放所有DirectX相关对象,避免内存泄漏
void CleanupDeviceD3D()
{
    CleanupRenderTarget();  // 先清理渲染目标

    // 释放COM对象(按依赖顺序释放,避免资源冲突)
    if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = nullptr; }
    if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = nullptr; }
    if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = nullptr; }
}


// 主函数:程序入口,控制整个程序的生命周期
int main() {
    // -------------------------- 步骤1:DPI适配(解决高分辨率屏幕UI模糊问题) --------------------------
    ImGui_ImplWin32_EnableDpiAwareness();  // 开启ImGui对系统DPI的感知
    // 获取主显示器的DPI缩放比例(如4K屏幕可能为2.0,1080P可能为1.0)
    float main_scale = ImGui_ImplWin32_GetDpiScaleForMonitor(
        ::MonitorFromPoint(POINT{ 0, 0 }, MONITOR_DEFAULTTOPRIMARY)  // 获取主显示器
    );


    // -------------------------- 步骤2:创建Windows窗口(ImGui需要依附的窗口载体) --------------------------
    // 定义窗口类(描述窗口的基本属性,如消息处理函数、图标等)
    WNDCLASSEXW wc = {
        sizeof(wc),                  // 结构体大小
        CS_CLASSDC,                  // 窗口类风格(使用专属设备上下文,避免绘图冲突)
        WndProc,                     // 消息处理函数
        0L, 0L,                      // 额外数据(未使用)
        GetModuleHandle(nullptr),    // 程序实例句柄
        nullptr, nullptr, nullptr, nullptr,  // 图标、光标、背景等(用默认)
        L"ImGui Example",            // 窗口类名(自定义,后续创建窗口需使用)
        nullptr                      // 小图标(默认)
    };
    ::RegisterClassExW(&wc);  // 注册窗口类(向系统注册这个窗口类型)

    // 创建窗口(生成实际窗口)
    HWND hwnd = ::CreateWindowW(
        wc.lpszClassName,            // 窗口类名(对应注册的类)
        L"Dear ImGui DirectX11 Example",  // 窗口标题
        WS_OVERLAPPEDWINDOW,         // 窗口风格(标准窗口,带标题栏、关闭按钮等)
        100, 100,                    // 初始位置(屏幕左上角x=100,y=100)
        (int)(1280 * main_scale),    // 宽度(1280 * DPI缩放,适配高分辨率)
        (int)(800 * main_scale),     // 高度(800 * DPI缩放)
        nullptr, nullptr,            // 父窗口、菜单(无)
        wc.hInstance, nullptr        // 程序实例、额外参数
    );


    // -------------------------- 步骤3:初始化DirectX 11(创建渲染环境) --------------------------
    if (!CreateDeviceD3D(hwnd))  // 调用函数创建D3D设备和交换链,失败则清理资源并退出
    {
        CleanupDeviceD3D();
        ::UnregisterClassW(wc.lpszClassName, wc.hInstance);
        return 1;  // 返回1表示程序异常退出
    }

    // 显示窗口(创建后默认隐藏,需手动显示)
    ::ShowWindow(hwnd, SW_SHOWDEFAULT);
    ::UpdateWindow(hwnd);  // 刷新窗口,确保立即显示


    // -------------------------- 步骤4:初始化ImGui(配置UI环境) --------------------------
    IMGUI_CHECKVERSION();  // 检查ImGui版本(确保编译版本与运行时一致)
    ImGui::CreateContext(); // 创建ImGui上下文(UI的"全局环境")
    ImGuiIO& io = ImGui::GetIO(); (void)io;  // 获取IO对象(管理输入输出,如键盘、帧率)
    io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // 开启键盘导航(方向键、Tab操作UI)
    io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;   // 开启手柄导航(支持游戏手柄操作)


    // -------------------------- 步骤5:设置UI缩放(适配DPI,避免高分辨率下UI过小) --------------------------
    ImGuiStyle& style = ImGui::GetStyle();
    style.ScaleAllSizes(main_scale);  // 缩放所有UI元素(按钮、文本等)
    style.FontScaleDpi = main_scale;  // 缩放字体大小


    // -------------------------- 步骤6:初始化ImGui后端(连接ImGui与系统/渲染API) --------------------------
    ImGui_ImplWin32_Init(hwnd);       // 初始化Win32后端(处理窗口消息、输入)
    ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);  // 初始化DX11后端(负责渲染UI)


    // -------------------------- 步骤7:程序状态变量(控制UI显示) --------------------------
    bool show_demo_window = true;    // 是否显示ImGui演示窗口
    bool show_another_window = false; // 是否显示"另一个窗口"
    ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // 窗口背景色(浅蓝色)


    // -------------------------- 步骤8:主循环(程序的核心,持续运行直到退出) --------------------------
    bool done = false;  // 控制循环是否结束(true=退出)
    while (!done)
    {
        // -------------------------- 8.1 处理窗口消息(如关闭、点击等) --------------------------
        MSG msg;  // 存储消息的结构体
        // 从消息队列中获取消息(PM_REMOVE表示获取后移除,避免重复处理)
        while (::PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE))
        {
            ::TranslateMessage(&msg);  // 翻译消息(如键盘按键转字符)
            ::DispatchMessage(&msg);   // 分发消息到WndProc处理
            if (msg.message == WM_QUIT)  // 收到退出消息(如点击关闭按钮)
                done = true;  // 标记循环结束
        }
        if (done)
            break;  // 退出循环


        // -------------------------- 8.2 处理窗口遮挡(优化性能) --------------------------
        // 如果交换链被遮挡(如窗口被覆盖),且确认遮挡状态:
        if (g_SwapChainOccluded && g_pSwapChain->Present(0, DXGI_PRESENT_TEST) == DXGI_STATUS_OCCLUDED)
        {
            ::Sleep(10);  // 休眠10ms,减少CPU占用
            continue;     // 跳过本次循环,不渲染
        }
        g_SwapChainOccluded = false;  // 重置遮挡状态


        // -------------------------- 8.3 处理窗口大小调整(避免画面拉伸) --------------------------
        if (g_ResizeWidth != 0 && g_ResizeHeight != 0)  // 如果有新的窗口尺寸
        {
            CleanupRenderTarget();  // 先清理旧的渲染目标
            // 调整交换链缓冲区大小(匹配新窗口尺寸)
            g_pSwapChain->ResizeBuffers(0, g_ResizeWidth, g_ResizeHeight, DXGI_FORMAT_UNKNOWN, 0);
            g_ResizeWidth = g_ResizeHeight = 0;  // 重置尺寸变量
            CreateRenderTarget();  // 创建新的渲染目标(适配新尺寸)
        }


        // -------------------------- 8.4 开始ImGui新帧(准备绘制UI) --------------------------
        ImGui_ImplDX11_NewFrame();  // DX11后端准备新帧
        ImGui_ImplWin32_NewFrame(); // Win32后端准备新帧
        ImGui::NewFrame();          // ImGui核心准备(通知ImGui可以开始定义UI了)


        // -------------------------- 8.5 定义UI界面(核心:这里是你要显示的UI) --------------------------
        /**
            ImGui::Begin()函数说明:
            函数声明:bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0);
            参数:
            - name:窗口标题(唯一标识,相同标题会合并窗口)
            - p_open:控制窗口是否显示的指针(关闭窗口时会将其设为false)
            - flags:窗口标志(组合使用,如禁用标题栏、禁止移动等)
        */
        bool i = true;  // 控制窗口是否显示(true=显示)
        // 创建一个自定义窗口:标题为"我的IMGui",禁止标题栏(NoTitleBar)和移动(NoMove)
        ImGui::Begin("我的IMGui", &i);

        // 这里可以添加其他UI控件(如按钮、文本等),目前是空窗口
        // 例如:ImGui::Text("这是我的第一个ImGui窗口!");
        // 长文本
        ImGui::TextWrapped(
            "This 521 "
            "aiamaiamaiamaiamaiamaiamaiamaiamaiamaiamaiam");

        ImGui::TextColored(ImVec4(1.0f, 0.0f, 1.0f, 1.0f), "Pink");
        ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "Yellow");

        // 带颜色的文本框
        ImGui::TextColored(ImVec4(1.0f, 0.0f, 1.0f, 1.0f), "Pink2");
        ImGui::SameLine();
        ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "Yellow2");
        ImGui::SameLine();
        // 鼠标悬浮上去会显示悬浮文本框,悬浮文本框会显示52am
        HelpMarker("52am");


        // ImGui中通过PushStyleColor()临时修改按钮在不同状态下的颜色
        // 注意:每次PushStyleColor()后必须用PopStyleColor()恢复默认样式,否则会影响后续UI元素

        // 1. 修改按钮"正常状态"(未被鼠标悬停、未被点击)的背景色
        // 参数1:ImGuiCol_Button - 指定修改"按钮正常状态"的颜色
        // 参数2:{1.0f, 1.0f, 0.0f, 1.0f} - RGBA颜色值(每个分量范围0.0f~1.0f)
        //   R=1.0f(红色满值)、G=1.0f(绿色满值)、B=0.0f(蓝色无)→ 混合为黄色
        //   A=1.0f(透明度100%,完全不透明)
        ImGui::PushStyleColor(ImGuiCol_Button, { 1.0f,1.0f,0.0f, 1.0f });

        // 2. 修改按钮"鼠标悬停状态"(鼠标放在按钮上但未点击)的背景色
        // 参数1:ImGuiCol_ButtonHovered - 指定修改"按钮被悬停时"的颜色
        // 参数2:{1.0f, 0.0f, 0.0f, 1.0f} → 红色(R满值,G、B无),完全不透明
        ImGui::PushStyleColor(ImGuiCol_ButtonHovered, { 1.0f,0.0f,0.0f, 1.0f });

        // 3. 修改按钮"激活状态"(鼠标按下按钮但未松开)的背景色
        // 参数1:ImGuiCol_ButtonActive - 指定修改"按钮被点击时"的颜色
        // 参数2:{0.0f, 1.0f, 0.0f, 1.0f} → 绿色(G满值,R、B无),完全不透明
        ImGui::PushStyleColor(ImGuiCol_ButtonActive, { 0.0f,1.0f,0.0f, 1.0f });
        
        if (ImGui::Button("anNiu")) {
            // 点击按钮执行的代码
            ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "dianjianniu");
        }

        ImGui::PopStyleColor(3);

        ImGui::End();  // 结束窗口定义(必须与Begin配对,否则崩溃)


        // -------------------------- 8.6 渲染UI(将定义的UI绘制到屏幕) --------------------------
        ImGui::Render();  // 生成绘制命令(将UI转换为显卡可执行的指令)

        // 计算背景色(考虑透明度:clear_color.w是透明度,乘以RGB值)
        const float clear_color_with_alpha[4] = {
            clear_color.x * clear_color.w,
            clear_color.y * clear_color.w,
            clear_color.z * clear_color.w,
            clear_color.w
        };

        // 设置渲染目标(告诉显卡:接下来的绘制输出到主渲染目标)
        g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, nullptr);
        // 清空屏幕(用背景色填充,避免上一帧画面残留)
        g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha);
        // 渲染ImGui的UI(执行绘制命令,将UI画到屏幕)
        ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());


        // -------------------------- 8.7 显示画面(交换前后缓冲区,展示渲染结果) --------------------------
        // Present函数:交换前后缓冲区(后台缓冲区是刚渲染的画面,前台是正在显示的)
        // 参数1:1=开启垂直同步(VSync,防止画面撕裂,帧率与显示器一致);0=关闭(帧率更高)
        HRESULT hr = g_pSwapChain->Present(1, 0);   // 开启垂直同步
        // HRESULT hr = g_pSwapChain->Present(0, 0); // 关闭垂直同步

        // 检查交换链是否被遮挡(用于后续优化)
        g_SwapChainOccluded = (hr == DXGI_STATUS_OCCLUDED);
    }


    // -------------------------- 步骤9:程序退出,清理资源 --------------------------
    // 关闭ImGui后端
    ImGui_ImplDX11_Shutdown();
    ImGui_ImplWin32_Shutdown();
    ImGui::DestroyContext();  // 销毁ImGui上下文

    // 清理D3D资源
    CleanupDeviceD3D();
    // 销毁窗口和窗口类
    ::DestroyWindow(hwnd);
    ::UnregisterClassW(wc.lpszClassName, wc.hInstance);

    return 0;  // 程序正常退出
}


img

`imgui-master` 和 `imgui-docking` 是 [Dear ImGui](https://github.com/ocornut/imgui) 的不同分支,它们的主要区别在于功能支持和开发状态。以下是对这两个分支的详细解释: --- ### 1. `imgui-master` 这是 ImGui 的官方主分支,托管在 [GitHub](https://github.com/ocornut/imgui) 上。它代表了官方稳定版本的代码库,通常用于生产环境和正式项目。 #### 特点: - **稳定性高**:官方主分支经过测试,适合生产环境使用。 - **功能完整**:包括基本的 UI 控件(按钮、滑块、输入框等)、主题支持、绘图功能等。 - **更新频率适中**:官方更新较为保守,注重稳定性和兼容性。 #### 适用场景: - 项目需要稳定性和兼容性。 - 不需要高级功能(如分屏、拖拽窗口等)。 - 你希望使用官方支持的版本。 --- ### 2. `imgui-docking` `imgui-docking` 是由社区开发的一个分支,主要目标是为 ImGui 添加 **分屏(docking)** 和 **多窗口管理** 功能。这个分支最初由 Omar Cornut(ImGui 的作者)维护,但后来被社区接手并持续开发。 #### 特点: - **支持分屏和拖拽窗口**:这是 `imgui-docking` 最显著的功能。它允许用户将窗口拖动到屏幕的不同区域,并支持窗口的停靠(docking)。 - **更丰富的 UI 布局**:适合需要复杂 UI 布局的项目,例如编辑器、IDE、调试工具等。 - **更新频率高**:社区活跃,功能更新较快,但可能不如官方主分支稳定。 #### 适用场景: - 需要分屏或拖拽窗口功能。 - 开发复杂的 UI 工具(如游戏编辑器、调试器等)。 - 愿意接受一定的不稳定性以换取新功能。 --- ### 如何选择? - 如果你需要一个 **稳定且功能齐全的 UI 库**,并且不需要分屏或拖拽窗口功能,建议使用 `imgui-master`。 - 如果你需要 **高级的 UI 布局功能**(如分屏、拖拽窗口),并且愿意接受一定的不稳定性,建议使用 `imgui-docking`。 --- ### 示例代码 以下是一个简单的 ImGui 示例代码,展示了如何创建一个窗口并添加一些控件。这个代码可以在 `imgui-master` 和 `imgui-docking` 中运行。 ```cpp #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" #include <GLFW/glfw3.h> int main() { // 初始化 GLFW if (!glfwInit()) { return -1; } // 创建窗口 GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui Example", NULL, NULL); if (!window) { glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glfwSwapInterval(1); // 启用垂直同步 // 初始化 ImGui IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; ImGui::StyleColorsDark(); // 初始化平台/渲染器后端 ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplOpenGL3_Init("#version 130"); bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // 主循环 while (!glfwWindowShouldClose(window)) { glfwPollEvents(); // 开始 ImGuiImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); // 显示 ImGui 的示例窗口 if (show_demo_window) ImGui::ShowDemoWindow(&show_demo_window); // 创建一个自定义窗口 { static float f = 0.0f; static int counter = 0; ImGui::Begin("Hello, world!"); // 创建一个窗口 ImGui::Text("This is a simple ImGui window."); // 显示文本 ImGui::SliderFloat("Float", &f, 0.0f, 1.0f); // 显示滑块 if (ImGui::Button("Button")) // 显示按钮 counter++; ImGui::SameLine(); ImGui::Text("counter = %d", counter); ImGui::Checkbox("Demo Window", &show_demo_window); // 显示复选框 ImGui::Checkbox("Another Window", &show_another_window); ImGui::ColorEdit3("Clear Color", (float*)&clear_color); // 显示颜色编辑器 ImGui::End(); } // 如果需要显示另一个窗口 if (show_another_window) { ImGui::Begin("Another Window", &show_another_window); ImGui::Text("This is another window."); ImGui::End(); } // 渲染 ImGui::Render(); int display_w, display_h; glfwGetFramebufferSize(window, &display_w, &display_h); glViewport(0, 0, display_w, display_h); glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); glClear(GL_COLOR_BUFFER_BIT); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); glfwSwapBuffers(window); } // 清理 ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); glfwDestroyWindow(window); glfwTerminate(); return 0; } ``` --- ### 代码解释 - **初始化部分**:初始化 GLFW 和 ImGui,设置窗口和上下文。 - **主循环**:在每一帧中,处理输入事件,生成 ImGui 窗口,并渲染。 - **ImGui 窗口**:创建了两个窗口,一个用于显示简单的控件(如按钮、滑块),另一个用于显示额外的内容。 - **渲染部分**:使用 OpenGL 渲染 ImGui 的 UI。 --- ### 相关问题 1. 如何在 ImGui 中实现自定义主题? 2. 如何在 ImGui 中加载和显示图片? 3. 如何将 ImGui 集成到 OpenGL 或 Vulkan 项目中? 4. `imgui-docking` 中的分屏功能是如何实现的?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值