commit
						b80813c7ec
					
				
							
								
								
									
										51
									
								
								base/ui.hpp
								
								
								
								
							
							
						
						
									
										51
									
								
								base/ui.hpp
								
								
								
								
							| 
						 | 
					@ -241,24 +241,7 @@ public:
 | 
				
			||||||
		vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
 | 
							vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
 | 
				
			||||||
		vkDestroyDescriptorPool(device, descriptorPool, nullptr);
 | 
							vkDestroyDescriptorPool(device, descriptorPool, nullptr);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	std::string string_to_utf8(const std::string& str)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		int nwLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
 | 
					 | 
				
			||||||
		wchar_t* pwBuf = new wchar_t[nwLen + 1];
 | 
					 | 
				
			||||||
		memset(pwBuf, 0, nwLen * 2 + 2);
 | 
					 | 
				
			||||||
		MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), pwBuf, nwLen);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		int nLen = WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, NULL, NULL, NULL, NULL);
 | 
					 | 
				
			||||||
		char* pBuf = new char[nLen + 1];
 | 
					 | 
				
			||||||
		memset(pBuf, 0, nLen + 1);
 | 
					 | 
				
			||||||
		WideCharToMultiByte(CP_UTF8, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		std::string ret = pBuf;
 | 
					 | 
				
			||||||
		delete[]pwBuf;
 | 
					 | 
				
			||||||
		delete[]pBuf;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return ret;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	void draw(VkCommandBuffer cmdBuffer) {
 | 
						void draw(VkCommandBuffer cmdBuffer) {
 | 
				
			||||||
		vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
 | 
							vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
 | 
				
			||||||
		vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
 | 
							vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
 | 
				
			||||||
| 
						 | 
					@ -334,6 +317,40 @@ public:
 | 
				
			||||||
	bool button(const char *caption) {
 | 
						bool button(const char *caption) {
 | 
				
			||||||
		return ImGui::Button(caption);
 | 
							return ImGui::Button(caption);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						bool beginChild(const char* caption, ImVec2 size, bool border)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return ImGui::BeginChild(caption, size, border);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void endChild()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return ImGui::EndChild();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// menu GUI
 | 
				
			||||||
 | 
						bool beginMainMenuBar() {
 | 
				
			||||||
 | 
							return ImGui::BeginMainMenuBar();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool beginMenu(const char* caption)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return ImGui::BeginMenu(caption);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool menuItem(const char* caption)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return ImGui::MenuItem(caption);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						void endMenu()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return ImGui::EndMenu();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void endMainMenuBar() {
 | 
				
			||||||
 | 
							return ImGui::EndMainMenuBar();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void text(const char *formatstr, ...) {
 | 
						void text(const char *formatstr, ...) {
 | 
				
			||||||
		va_list args;
 | 
							va_list args;
 | 
				
			||||||
		va_start(args, formatstr);
 | 
							va_start(args, formatstr);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1675,93 +1675,137 @@ PlumageRender::PlumageRender()
 | 
				
			||||||
		bool updateShaderParams = false;
 | 
							bool updateShaderParams = false;
 | 
				
			||||||
		bool updateCBs = false;
 | 
							bool updateCBs = false;
 | 
				
			||||||
		float scale = 1.0f;
 | 
							float scale = 1.0f;
 | 
				
			||||||
 | 
							bool boolTitleWindowShow = false;
 | 
				
			||||||
		ImGui::NewFrame();
 | 
							ImGui::NewFrame();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ImGui::SetNextWindowPos(ImVec2(10, 10));
 | 
							ImGui::SetNextWindowPos(ImVec2(10000, 10000));
 | 
				
			||||||
		ImGui::SetNextWindowSize(ImVec2(200 * scale, (models.scene.animations.size() > 0 ? 440 : 360) * scale), ImGuiSetCond_Always);
 | 
							//ImGui::SetNextWindowSize(ImVec2(200 * scale, (models.scene.animations.size() > 0 ? 440 : 360) * scale), ImGuiSetCond_Always);
 | 
				
			||||||
		ImGui::Begin("Plumage Render", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove);
 | 
							ImGui::Begin("", nullptr, ImGuiWindowFlags_NoFocusOnAppearing|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoBringToFrontOnFocus);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
		ImGui::PushItemWidth(100.0f * scale);
 | 
							ImGui::PushItemWidth(100.0f * scale);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		gui->text("%.1d fps (%.2f ms)", lastFPS, (1000.0f / lastFPS));
 | 
							
 | 
				
			||||||
		// TO DO : language switch
 | 
					
 | 
				
			||||||
		if (gui->header(chineseUI.model)) {
 | 
							if(gui->beginMainMenuBar()) {
 | 
				
			||||||
			if (gui->button(chineseUI.openNewModel)) {
 | 
								if (gui->beginMenu(chineseUI.menuFile))
 | 
				
			||||||
				std::wstring filename = L"";
 | 
								{
 | 
				
			||||||
				wchar_t buffer[MAX_PATH];
 | 
									if (gui->menuItem(chineseUI.menuOpenNewModel))
 | 
				
			||||||
				OPENFILENAMEW ofn;
 | 
									{
 | 
				
			||||||
				ZeroMemory(&buffer, sizeof(buffer));
 | 
										std::wstring filename = L"";
 | 
				
			||||||
				ZeroMemory(&ofn, sizeof(ofn));
 | 
										wchar_t buffer[MAX_PATH];
 | 
				
			||||||
				ofn.lStructSize = sizeof(ofn);
 | 
										OPENFILENAMEW ofn;
 | 
				
			||||||
				ofn.lpstrFilter = L"glTF files\0*.gltf;*.glb\0";
 | 
										ZeroMemory(&buffer, sizeof(buffer));
 | 
				
			||||||
				ofn.lpstrFile = buffer;
 | 
										ZeroMemory(&ofn, sizeof(ofn));
 | 
				
			||||||
				ofn.nMaxFile = MAX_PATH;
 | 
										ofn.lStructSize = sizeof(ofn);
 | 
				
			||||||
				ofn.lpstrTitle = L"Select a glTF file to load";
 | 
										ofn.lpstrFilter = L"glTF files\0*.gltf;*.glb\0";
 | 
				
			||||||
				ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
 | 
										ofn.lpstrFile = buffer;
 | 
				
			||||||
				if (GetOpenFileNameW(&ofn)) {
 | 
										ofn.nMaxFile = MAX_PATH;
 | 
				
			||||||
					filename = buffer;
 | 
										ofn.lpstrTitle = L"Select a glTF file to load";
 | 
				
			||||||
					
 | 
										ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
 | 
				
			||||||
 | 
										if (GetOpenFileNameW(&ofn)) {
 | 
				
			||||||
 | 
											filename = buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										if (!filename.empty()) {
 | 
				
			||||||
 | 
											vkDeviceWaitIdle(device);
 | 
				
			||||||
 | 
											std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
 | 
				
			||||||
 | 
											std::string stringFilename = converter.to_bytes(filename);
 | 
				
			||||||
 | 
											loadScene(stringFilename);
 | 
				
			||||||
 | 
											setupDescriptors();
 | 
				
			||||||
 | 
											updateCBs = true;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									gui->endMenu();
 | 
				
			||||||
				if (!filename.empty()) {
 | 
								}
 | 
				
			||||||
					vkDeviceWaitIdle(device);
 | 
								if (gui->beginMenu(chineseUI.menuEnvironment))
 | 
				
			||||||
					std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
 | 
								{
 | 
				
			||||||
					std::string stringFilename = converter.to_bytes(filename);
 | 
									if (gui->beginMenu(chineseUI.menuEnvironmentConfig))
 | 
				
			||||||
					loadScene(stringFilename);
 | 
									{
 | 
				
			||||||
					setupDescriptors();
 | 
										if (gui->combo(chineseUI.environmentMap, selectedEnvironment, environments)) {
 | 
				
			||||||
					updateCBs = true;
 | 
											vkDeviceWaitIdle(device);
 | 
				
			||||||
 | 
											loadEnvironment(environments[selectedEnvironment]);
 | 
				
			||||||
 | 
											setupDescriptors();
 | 
				
			||||||
 | 
											updateCBs = true;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if (gui->checkbox(chineseUI.environmentBackGround, &displayBackground)) {
 | 
				
			||||||
 | 
											updateShaderParams = true;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if (gui->slider("Exposure", &shaderData.exposure, 0.1f, 10.0f)) {
 | 
				
			||||||
 | 
											updateShaderParams = true;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if (gui->slider("Gamma", &shaderData.gamma, 0.1f, 4.0f)) {
 | 
				
			||||||
 | 
											updateShaderParams = true;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if (gui->slider("IBL", &shaderData.scaleIBLAmbient, 0.0f, 1.0f)) {
 | 
				
			||||||
 | 
											updateShaderParams = true;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										gui->endMenu();
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									gui->endMenu();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (gui->combo(chineseUI.environmentMap, selectedEnvironment, environments)) {
 | 
								if (gui->beginMenu("debug")) 
 | 
				
			||||||
				vkDeviceWaitIdle(device);
 | 
								{
 | 
				
			||||||
				loadEnvironment(environments[selectedEnvironment]);
 | 
									if (gui->beginMenu(chineseUI.menuDebugInput))
 | 
				
			||||||
				setupDescriptors();
 | 
									{
 | 
				
			||||||
				updateCBs = true;
 | 
										const std::vector<std::string> debugNamesInputs = {
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (gui->header(chineseUI.environment)) {
 | 
					 | 
				
			||||||
			if (gui->checkbox("Background", &displayBackground)) {
 | 
					 | 
				
			||||||
				updateShaderParams = true;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (gui->slider("Exposure", &shaderData.exposure, 0.1f, 10.0f)) {
 | 
					 | 
				
			||||||
				updateShaderParams = true;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (gui->slider("Gamma", &shaderData.gamma, 0.1f, 4.0f)) {
 | 
					 | 
				
			||||||
				updateShaderParams = true;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (gui->slider("IBL", &shaderData.scaleIBLAmbient, 0.0f, 1.0f)) {
 | 
					 | 
				
			||||||
				updateShaderParams = true;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (gui->header("Debug ")) {
 | 
					 | 
				
			||||||
			const std::vector<std::string> debugNamesInputs = {
 | 
					 | 
				
			||||||
				"none", "Base color", "Normal", "Occlusion", "Emissive", "Metallic", "Roughness"
 | 
									"none", "Base color", "Normal", "Occlusion", "Emissive", "Metallic", "Roughness"
 | 
				
			||||||
			};
 | 
										};
 | 
				
			||||||
			if (gui->combo(chineseUI.debugInput, &debugViewInputs, debugNamesInputs)) {
 | 
										if (gui->combo(chineseUI.debugInput, &debugViewInputs, debugNamesInputs)) {
 | 
				
			||||||
				shaderData.debugViewInputs = static_cast<float>(debugViewInputs);
 | 
											shaderData.debugViewInputs = static_cast<float>(debugViewInputs);
 | 
				
			||||||
				updateShaderParams = true;
 | 
											updateShaderParams = true;
 | 
				
			||||||
			}
 | 
										}
 | 
				
			||||||
			const std::vector<std::string> debugNamesEquation = {
 | 
										gui->endMenu();
 | 
				
			||||||
				"none", "Diff (l,n)", "F (l,h)", "G (l,v,h)", "D (h)", "Specular"
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
			if (gui->combo(chineseUI.debugPBREquation, &debugViewEquation, debugNamesEquation)) {
 | 
					 | 
				
			||||||
				shaderData.debugViewEquation = static_cast<float>(debugViewEquation);
 | 
					 | 
				
			||||||
				updateShaderParams = true;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (models.scene.animations.size() > 0) {
 | 
					 | 
				
			||||||
			if (gui->header(chineseUI.animation)) {
 | 
					 | 
				
			||||||
				gui->checkbox(chineseUI.pauseAnimation, &animate);
 | 
					 | 
				
			||||||
				std::vector<std::string> animationNames;
 | 
					 | 
				
			||||||
				for (auto animation : models.scene.animations) {
 | 
					 | 
				
			||||||
					animationNames.push_back(animation.name);
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				gui->combo(chineseUI.animationSeq, &animationIndex, animationNames);
 | 
									if (gui->beginMenu("PBR"))
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										const std::vector<std::string> debugNamesEquation = {
 | 
				
			||||||
 | 
									"none", "Diff (l,n)", "F (l,h)", "G (l,v,h)", "D (h)", "Specular"
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
										if (gui->combo(chineseUI.debugPBREquation, &debugViewEquation, debugNamesEquation)) {
 | 
				
			||||||
 | 
											shaderData.debugViewEquation = static_cast<float>(debugViewEquation);
 | 
				
			||||||
 | 
											updateShaderParams = true;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										gui->endMenu();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									if (gui->beginMenu(chineseUI.menuDebugFrameRate))
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										gui->text("%.1d fps (%.2f ms)", lastFPS, (1000.0f / lastFPS));
 | 
				
			||||||
 | 
										gui->endMenu();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									gui->endMenu();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								if (gui->beginMenu(chineseUI.menuAnimation))
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (models.scene.animations.size() > 0) 
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										if (gui->beginMenu(chineseUI.menuAnimationActivation))
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											gui->checkbox(chineseUI.pauseAnimation, &animate);
 | 
				
			||||||
 | 
											gui->endMenu();
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if (gui->beginMenu(chineseUI.menuAnimationAnimationSequence))
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											std::vector<std::string> animationNames;
 | 
				
			||||||
 | 
											for (auto animation : models.scene.animations) {
 | 
				
			||||||
 | 
												animationNames.push_back(animation.name);
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											gui->combo(chineseUI.animationSeq, &animationIndex, animationNames);
 | 
				
			||||||
 | 
											gui->endMenu();
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										gui->text(chineseUI.menuAnimationNoAnimation);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									gui->endMenu();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								gui->endMainMenuBar();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ImGui::PopItemWidth();
 | 
							ImGui::PopItemWidth();
 | 
				
			||||||
		ImGui::End();
 | 
							ImGui::End();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,14 +65,27 @@ public:
 | 
				
			||||||
	struct ChinesesUI
 | 
						struct ChinesesUI
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		const char * model = "模型";
 | 
							const char * model = "模型";
 | 
				
			||||||
		const char* openNewModel = "打开新gltf模型";
 | 
							
 | 
				
			||||||
		const char* environmentMap = "环境贴图";
 | 
							const char* environmentMap = "环境贴图";
 | 
				
			||||||
		const char* environment = "环境光照";
 | 
							const char* environmentBackGround = "启用背景贴图";
 | 
				
			||||||
		const char* debugInput = "输入";
 | 
							const char* debugInput = "输入";
 | 
				
			||||||
		const char* debugPBREquation = "PBR计算参数";
 | 
							const char* debugPBREquation = "PBR计算参数";
 | 
				
			||||||
		const char* animation = "动画";
 | 
							const char* animation = "动画";
 | 
				
			||||||
		const char* pauseAnimation = "启用动画";
 | 
							const char* pauseAnimation = "启用动画";
 | 
				
			||||||
		const char* animationSeq = "动画序列";
 | 
							const char* animationSeq = "动画序列";
 | 
				
			||||||
 | 
					// menu item
 | 
				
			||||||
 | 
							const char* menuFile = "文件";
 | 
				
			||||||
 | 
							const char* menuOpenNewModel = "新模型..";
 | 
				
			||||||
 | 
							const char* menuEnvironment = "环境光照";
 | 
				
			||||||
 | 
							const char* menuEnvironmentConfig = "设置";
 | 
				
			||||||
 | 
							const char* menuAnimation = "动画";
 | 
				
			||||||
 | 
							const char* menuDebugFrameRate = "fps";
 | 
				
			||||||
 | 
							const char* menuDebugInput = "输入";
 | 
				
			||||||
 | 
							const char* menuAnimationNoAnimation = "当前模型没有动画!";
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							const char* menuAnimationActivation = "开关";
 | 
				
			||||||
 | 
							const char* menuAnimationAnimationSequence = "动画序列";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}chineseUI;
 | 
						}chineseUI;
 | 
				
			||||||
	struct UniformBufferSet {
 | 
						struct UniformBufferSet {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue