DirectX11学习笔记十 imGUI入坑

下载地址
  Immediate Mode Graphical User interface,Immediate模式,不保存UI对象,用静态方法每帧创建,Unity里的GUI就是这种模式,适合小游戏或快速开发,如果要做动画或者保存状态,可能需要自己额外封装一层,好处就是好写,虽然我还是喜欢UGUI的那种。

入坑方法:

  进入github官网下载源码,将DirectX11学习笔记十 imGUI入坑_第1张图片这些文件拖入自己的项目,比如单独弄一个imGUI文件夹。

实操样例:

一.显示demo窗口

1.准备工作
  1. 创建一个imgui管理类,并在GameApp类中添加其public对象imgui
.h
#pragma once
class ImguiManager
{
public:
	ImguiManager();
	~ImguiManager();
};

.cpp
#include "ImguiManager.h"
#include "imGUI\imgui.h"

ImguiManager::ImguiManager()
{
	IMGUI_CHECKVERSION();
	ImGui::CreateContext();
	ImGui::StyleColorsDark();
}

ImguiManager::~ImguiManager()
{
	ImGui::DestroyContext();
}
  1. imgui_impl_win32.h文件里添加#include "imgui.h"和,要不会报错
    IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame();的下面添加上LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);,这样后面调用这个函数就不用include cpp了
  2. bool D3DApp::InitMainWindow()里添加imgui初始化ImGui_ImplWin32_Init(m_hMainWnd);
  3. D3DApp::~D3DApp()里添加imgui析构ImGui_ImplWin32_Shutdown();
  4. GameApp::~GameApp()里添加ImGui_ImplDX11_Shutdown();
  5. LRESULT D3DApp::MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)定义的开头添加
	if (ImGui_ImplWin32_WndProcHandler(hwnd, msg, wParam, lParam))
	{
		return true;
	}

6.在bool D3DApp::InitDirect3D()最下面添加
ImGui_ImplDX11_Init(m_pd3dDevice.Get(), m_pd3dImmediateContext.Get());

2.调用

  添加void GameApp::DrawImgui() noexcept方法,于DrawScene方法里Present之前调用。

void GameApp::DrawImgui() noexcept
{
	ImGui_ImplDX11_NewFrame();
	ImGui_ImplWin32_NewFrame();
	ImGui::NewFrame();

	static bool show_demo_window = true;
	if (show_demo_window)
	{
		ImGui::ShowDemoWindow(&show_demo_window);
	}
	ImGui::Render();
	ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
}
3.更改鼠标控制模式

  将MODE_RELATIVE改为MODE_ABSOLUTE,在UpdateScene中通过当前帧和上一帧的坐标做差获得相对位移,赋给摄像机的控制接口,并设置显示Cursor。

	Mouse::State mouseState = m_pMouse->GetState();
	Mouse::State lastMouseState = m_MouseTracker.GetLastState();
	int dx = mouseState.x - lastMouseState.x;
	int dy = mouseState.y - lastMouseState.y;

DirectX11学习笔记十 imGUI入坑_第2张图片

二.用法测试

  代码改一下,其中speedFactor在UpdateScene()中与dt做乘法。

void GameApp::DrawImgui() noexcept
{
	ImGui_ImplDX11_NewFrame();
	ImGui_ImplWin32_NewFrame();
	ImGui::NewFrame();

	static char buffer[1024];
	if (ImGui::Begin("Simulation Speed"))
	{
		ImGui::SliderFloat("Speed Factor", &speedFactor, 0.0f, 4.0f);
		ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
		ImGui::InputText("InputText", buffer, sizeof(buffer));
	}
	ImGui::End();
	ImGui::Render();
	ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
}

  但是运行后会发现,InputText的接收和摄像机的运动是同时进行的,加个if就解决了:

if (!ImGui::GetIO().WantCaptureKeyboard)
		{
			// 方向移动
			if (keyState.IsKeyDown(Keyboard::W))
			{
				if (m_CameraMode == CameraMode::FirstPerson)
					cam1st->Walk(dt * 3.0f);
				else
					cam1st->MoveForward(dt * 3.0f);
			}
			if (keyState.IsKeyDown(Keyboard::S))
			{
				if (m_CameraMode == CameraMode::FirstPerson)
					cam1st->Walk(dt * -3.0f);
				else
					cam1st->MoveForward(dt * -3.0f);
			}
			if (keyState.IsKeyDown(Keyboard::A))
				cam1st->Strafe(dt * -3.0f);
			if (keyState.IsKeyDown(Keyboard::D))
				cam1st->Strafe(dt * 3.0f);
		}

DirectX11学习笔记十 imGUI入坑_第3张图片
  鉴于只是个UI库,不打算深入研究,能出效果即可。如果需要实现什么效果,查github上提供的example就好了。

你可能感兴趣的:(DirectX)