LearnGL - 09 - Include IMGUI - Dear ImGui - 添加Dashboard、Debugging Panel


LearnGL - 學習筆記目錄

本人才疏學淺,如有什麼錯誤,望不吝指出。

上些篇:

這一篇:將引入開源庫 Dear ImGui,來方便後續的調試工作。


在學習 OpenGL 過程,免不了需要有一些 GUI 來方便數據調試。

我之前取搜索過,發現 Dear ImGui 在製作 2D GUI 非常的適合,庫小,功能強大,GUI 還很舒服,因爲基本都是純色。

如果你想了解 Dear ImGui,可以查看我之前的一篇:IMGUI 系統 - Dear ImGUI,這裏不回去寫 ImGui 的教程,因爲內容說多不多,說少也不少(因爲如果要寫好一些通俗易通的教程,最好的還是錄製視頻,但我又不想錄制視頻)。

Dashboard - 儀表板

我們的 Dashboard 主要是用於顯示:

  • 這次的主題是什麼
  • 窗口大小是多少
  • 還有 fps,等信息的顯示就好了

目前就這些內容,後續按需添加其他功能就可以了

長下面圖片的樣式
在這裏插入圖片描述

Code

代碼比較簡單:

void showDashboardWin(bool* p_open) {
	const float DISTANCE = 10.0f;
	static int corner = 0;
	ImGuiIO& io = ImGui::GetIO();
	if (corner != -1) {
		// 0 : top-left
		// 1 : top-right
		// 2 : bottom-left
		// 3 : bottom-right
		// corner & 1 ==> (top-left || bottom-right)
		// corner & 2 ==> (bottom-left || bottom-right)
		ImVec2 window_pos = ImVec2((corner & 1) ? io.DisplaySize.x - DISTANCE : DISTANCE, (corner & 2) ? io.DisplaySize.y - DISTANCE : DISTANCE);
		ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f);
		ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot);
	}
	ImGui::SetNextWindowBgAlpha(0.35f);					// 背景透明 35% 的alpha值
	ImGuiWindowFlags window_flags = 
		ImGuiWindowFlags_NoDecoration |					// 不需要標題、不需要調整大小、不需要滾動條、不需要摺疊
		ImGuiWindowFlags_AlwaysAutoResize |				// 自動調整大小
		ImGuiWindowFlags_NoSavedSettings |				// 不需要保存會加載佈局信息
		ImGuiWindowFlags_NoFocusOnAppearing |			// 顯示時不需要獲取交點
		ImGuiWindowFlags_NoNav;							// 不需要 navigation 的操作交互
	if (corner != -1) {
		window_flags |= ImGuiWindowFlags_NoMove;		// 如果不是 -1 則不能移動
	}
	if (ImGui::Begin("jave's Dashboard", p_open, window_flags)) {
		ImGui::Text(" --- Dashboard --- ");
		ImGui::Separator();
		ImGui::Text(
			"Demo : 09_Add_GUI_System_Dear_ImGui\n" 
			"Window Size : %d x %d\n"
			"(right-click to change position)", 
			win_width, win_height);
		ImGui::Separator();
		ImGui::Text("FPS : %.1f (ds : %.3f ms/frame)", 1.0f / Timer::inst()->deltaTime, Timer::inst()->deltaTime * 1000);
		if (ImGui::BeginPopupContextWindow()) {
			if (ImGui::MenuItem("Custom", NULL, corner == -1)) corner = -1;
			if (ImGui::MenuItem("Top-left", NULL, corner == 0)) corner = 0;
			if (ImGui::MenuItem("Top-right", NULL, corner == 1)) corner = 1;
			if (ImGui::MenuItem("Bottom-left", NULL, corner == 2)) corner = 2;
			if (ImGui::MenuItem("Bottom-right", NULL, corner == 3)) corner = 3;
			if (p_open && ImGui::MenuItem("Close")) *p_open = false;
			ImGui::EndPopup();
		}
	}
	ImGui::End();
}

ContextMenu - 上下文菜單/右鍵菜單

從 Dashboard 中的 right-click to change position 文字提示,可以知道,鼠標右鍵可以調整位置

從代碼中可以看到我們喫根據一個 corner 來判斷處理的

弄個 GIF 看看:
在這裏插入圖片描述


Debugging Panel - 調試面板

目前長這個樣子
在這裏插入圖片描述

Shortcuts - 快捷鍵

提示一些快捷鍵信息

  • Exiting Application(Shift+F4) ,退出程序
  • Enabled Cursor(H),是否啓用鼠標/光標
    在這裏插入圖片描述

Informations - 其他信息

目前我是直接放到一些簡單的分欄中

後面還可以自己製作一個完全的 Console 或是 Log 面板,方便輸出日誌記錄用。
在這裏插入圖片描述

Time - 時間相關的

目前就:

  • ScaleTime 當前的時間縮放倍率,後續在調試一些動畫效果,比較有用
  • TargetFPS 設置的期望的 FPS 更新頻率
    在這裏插入圖片描述

Draw State - 繪製狀態

目前爲了代表性的添加 GUI 功能,象徵性的只添加一個:Clear Color,就是 glClear 值的 ClearColor 的顏色值

在這裏插入圖片描述

Camera - 相機

最後是我們的相機

Reset - 重置

重置相機的設置參數,下面就是我們本身的鏡頭參數,之前拉遠一些鏡頭方便其他 GUI 的效果查看
在這裏插入圖片描述

Enabled Camera Control - 啓用相機控制

開啓後(勾上覆選框)後,我們就可以用鼠標的左右上下來控制相機的:Yaw、Pitch,也可以用 W, S, A, D 按鍵來控制相機的左右上下的平移

可以用鼠標來勾選複選框,也可以用快捷鍵:C,來啓用或禁用相機的控制

GIF 效果如下:
在這裏插入圖片描述

Transform - 變換

  • Pos 相機的位置
  • Fov 全寫是:Field Of View 相機的視角(Frustum 的 Top 與 Bottom 的夾角)(單位:角度)
  • Near 近截面
  • Far 遠截面
  • Yaw 相機繞Y軸的旋轉量
  • Pitch 相機繞X軸的旋轉量
    在這裏插入圖片描述

Code

void showToolsPanel() {
	ImGui::Begin("Jave's Debugging Panel");
	if (ImGui::CollapsingHeader("Shortcuts")) {
		ImGui::Text("Exiting Application(Shift+F4)");
		ImGui::Text("Enabled Cursor(H) : %s", getEnabledCursor() ? "true" : "false");
	}
	if (ImGui::CollapsingHeader("Informations")) {
		ImGui::Text("IsAnyItemActive : %s", ImGui::IsAnyItemActive() ? "true" : "false");
		ImGui::Checkbox("ShowDashBoard", &show_dashboard);
	}
	if (ImGui::CollapsingHeader("Time")) {
		ImGui::SliderFloat("ScaleTime", &Timer::inst()->scaled, 0, 2);
		ImGui::SliderInt("TargetFPS", &targetFPS, 1, 120);
	}
	if (ImGui::CollapsingHeader("Draw State")) {
		ImGui::ColorEdit4("ClearColor", glm::value_ptr(clearCol));
	}
	if (ImGui::CollapsingHeader("Camera")) {
		if (ImGui::Button("Reset")) {									// 恢復相機
			memcpy(cam, backupCam, sizeof(Camera));
			memcpy(camCtrl, backupCamCtrl, sizeof(CameraController));
		}
		ImGui::Checkbox("Enabled Camera Control(C)", &enabledCamCtrl);
		ImGui::Separator();
		ImGui::Text("Transform:");
		ImGui::Separator();
		ImGui::Indent();
		//ImGui::InputFloat3("Pos", glm::value_ptr(cam->mPosition), 1); // 可以用輸入條
		//ImGui::SliderFloat3("Pos", glm::value_ptr(cam->mPosition), -100.0f, 100.0f); // 也可以使用滑動條
		ImGui::DragFloat3("Pos", glm::value_ptr(cam->mPosition), 0.01f, -100.0f, 100.0f); // 可以使用拖拽條,這個體驗就好,所以使用這個
		ImGui::DragFloat("Fov", &cam->mFov, 0.1f, 1.0f, 60.0f);
		ImGui::DragFloat("Near", &cam->mNear, 0.1f, 0.1f, 1000.0f);
		ImGui::DragFloat("Far", &cam->mFar, 0.1f, 0.1f, 1000.0f);
		ImGui::DragFloat("Yaw", &camCtrl->mYaw, 0.01f);
		ImGui::DragFloat("Pitch", &camCtrl->mPitch, 0.01f);
		camCtrl->updateCameraVectors();
		ImGui::Unindent();
	}
	ImGui::End();

	if (show_dashboard) {
		showDashboardWin(&show_dashboard);
	}
}

OK,就到這裏吧,這個 Dear ImGui 還有很多強大的功能,後續需要的時候再使用。

如果你要製作一個 3D Engine,GUI 截面可以考慮使用 Dear ImGui,至於場景的 3D IMGUI,也是可以使用另一些開源庫來實現(有現成的,真的太好了)


References

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章