Browse Source

More work on the texture viewer

Panagiotis Christopoulos Charitos 4 years ago
parent
commit
ace1bba1a7

+ 4 - 4
AnKi/Core/App.cpp

@@ -682,8 +682,8 @@ void App::injectUiElements(DynamicArrayAuto<UiQueueElement>& newUiElementArr, Re
 	if(m_displayStats)
 	if(m_displayStats)
 	{
 	{
 		newUiElementArr[count].m_userData = m_statsUi;
 		newUiElementArr[count].m_userData = m_statsUi;
-		newUiElementArr[count].m_drawCallback = [](CanvasPtr& canvas, const void* userData) -> void {
-			static_cast<StatsUi*>(const_cast<void*>(userData))->build(canvas);
+		newUiElementArr[count].m_drawCallback = [](CanvasPtr& canvas, void* userData) -> void {
+			static_cast<StatsUi*>(userData)->build(canvas);
 		};
 		};
 		++count;
 		++count;
 	}
 	}
@@ -691,8 +691,8 @@ void App::injectUiElements(DynamicArrayAuto<UiQueueElement>& newUiElementArr, Re
 	if(m_consoleEnabled)
 	if(m_consoleEnabled)
 	{
 	{
 		newUiElementArr[count].m_userData = m_console.get();
 		newUiElementArr[count].m_userData = m_console.get();
-		newUiElementArr[count].m_drawCallback = [](CanvasPtr& canvas, const void* userData) -> void {
-			static_cast<DeveloperConsole*>(const_cast<void*>(userData))->build(canvas);
+		newUiElementArr[count].m_drawCallback = [](CanvasPtr& canvas, void* userData) -> void {
+			static_cast<DeveloperConsole*>(userData)->build(canvas);
 		};
 		};
 		++count;
 		++count;
 	}
 	}

+ 2 - 2
AnKi/Renderer/RenderQueue.h

@@ -309,13 +309,13 @@ public:
 static_assert(std::is_trivially_destructible<DecalQueueElement>::value == true, "Should be trivially destructible");
 static_assert(std::is_trivially_destructible<DecalQueueElement>::value == true, "Should be trivially destructible");
 
 
 /// Draw callback for drawing.
 /// Draw callback for drawing.
-using UiQueueElementDrawCallback = void (*)(CanvasPtr& canvas, const void* userData);
+using UiQueueElementDrawCallback = void (*)(CanvasPtr& canvas, void* userData);
 
 
 /// UI element render queue element.
 /// UI element render queue element.
 class UiQueueElement final
 class UiQueueElement final
 {
 {
 public:
 public:
-	const void* m_userData;
+	void* m_userData;
 	UiQueueElementDrawCallback m_drawCallback;
 	UiQueueElementDrawCallback m_drawCallback;
 
 
 	UiQueueElement()
 	UiQueueElement()

+ 2 - 2
AnKi/Scene/Components/UiComponent.h

@@ -25,7 +25,7 @@ public:
 	{
 	{
 	}
 	}
 
 
-	void init(UiQueueElementDrawCallback callback, const void* userData)
+	void init(UiQueueElementDrawCallback callback, void* userData)
 	{
 	{
 		ANKI_ASSERT(callback != nullptr);
 		ANKI_ASSERT(callback != nullptr);
 		ANKI_ASSERT(userData != nullptr);
 		ANKI_ASSERT(userData != nullptr);
@@ -43,7 +43,7 @@ public:
 
 
 private:
 private:
 	UiQueueElementDrawCallback m_drawCallback = nullptr;
 	UiQueueElementDrawCallback m_drawCallback = nullptr;
-	const void* m_userData = nullptr;
+	void* m_userData = nullptr;
 };
 };
 /// @}
 /// @}
 
 

+ 84 - 8
Tools/Texture/TextureViewerMain.cpp

@@ -10,6 +10,8 @@ using namespace anki;
 class TextureViewerUiNode : public SceneNode
 class TextureViewerUiNode : public SceneNode
 {
 {
 public:
 public:
+	TextureResourcePtr m_textureResource;
+
 	TextureViewerUiNode(SceneGraph* scene, CString name)
 	TextureViewerUiNode(SceneGraph* scene, CString name)
 		: SceneNode(scene, name)
 		: SceneNode(scene, name)
 	{
 	{
@@ -17,28 +19,91 @@ public:
 		spatialc->setAlwaysVisible(true);
 		spatialc->setAlwaysVisible(true);
 
 
 		UiComponent* uic = newComponent<UiComponent>();
 		UiComponent* uic = newComponent<UiComponent>();
-		uic->init([](CanvasPtr& canvas, const void* ud) { static_cast<const TextureViewerUiNode*>(ud)->draw(canvas); },
-				  this);
+		uic->init([](CanvasPtr& canvas, void* ud) { static_cast<TextureViewerUiNode*>(ud)->draw(canvas); }, this);
 
 
 		ANKI_CHECK_AND_IGNORE(getSceneGraph().getUiManager().newInstance(m_font, "EngineAssets/UbuntuMonoRegular.ttf",
 		ANKI_CHECK_AND_IGNORE(getSceneGraph().getUiManager().newInstance(m_font, "EngineAssets/UbuntuMonoRegular.ttf",
-																		 Array<U32, 1>{32}));
+																		 Array<U32, 1>{16}));
+	}
+
+	Error frameUpdate(Second prevUpdateTime, Second crntTime)
+	{
+		if(!m_textureView.isCreated())
+		{
+			m_textureView = m_textureResource->getGrTextureView();
+		}
+
+		return Error::NONE;
 	}
 	}
 
 
 private:
 private:
 	FontPtr m_font;
 	FontPtr m_font;
+	TextureViewPtr m_textureView;
+	U32 m_crntMip = 0;
+	F32 m_zoom = 1.0f;
 
 
-	void draw(CanvasPtr& canvas) const
+	void draw(CanvasPtr& canvas)
 	{
 	{
+		const Texture& grTex = *m_textureResource->getGrTexture().get();
+
 		ImGui::Begin("Console", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoTitleBar);
 		ImGui::Begin("Console", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoTitleBar);
 
 
-		canvas->pushFont(m_font, 32);
+		canvas->pushFont(m_font, 16);
 
 
 		ImGui::SetWindowPos(Vec2(0.0f, 0.0f));
 		ImGui::SetWindowPos(Vec2(0.0f, 0.0f));
 		ImGui::SetWindowSize(Vec2(F32(canvas->getWidth()), F32(canvas->getHeight())));
 		ImGui::SetWindowSize(Vec2(F32(canvas->getWidth()), F32(canvas->getHeight())));
 
 
-		ImGui::PushStyleColor(ImGuiCol_Text, Vec4(0.0f, 0.0f, 0.0f, 1.0f));
-		ImGui::TextWrapped("Test");
-		ImGui::PopStyleColor();
+		ImGui::BeginChild("Tools", ImVec2(ImGui::GetWindowContentRegionWidth() * 0.25f, -1.0f), false, 0);
+
+		// Info
+		ImGui::TextWrapped("Size %ux%u Mips %u", grTex.getWidth(), grTex.getHeight(), grTex.getMipmapCount());
+
+		// Zoom
+		ImGui::DragFloat("Zoom", &m_zoom, 0.01f, 0.1f, 10.0f, "%.3f");
+
+		// Mips combo
+		{
+			Array<CString, 8> mipTexts = {"0", "1", "2", "3", "4", "5", "6", "7"};
+			CString comboLevel = mipTexts[m_crntMip];
+			const U32 lastCrntMip = m_crntMip;
+			if(ImGui::BeginCombo("Mipmap", comboLevel.cstr(), 0))
+			{
+				for(U32 mip = 0; mip < grTex.getMipmapCount(); ++mip)
+				{
+					const Bool isSelected = (m_crntMip == mip);
+					if(ImGui::Selectable(mipTexts[mip].cstr(), isSelected))
+					{
+						m_crntMip = mip;
+					}
+
+					if(isSelected)
+					{
+						ImGui::SetItemDefaultFocus();
+					}
+				}
+				ImGui::EndCombo();
+			}
+
+			if(lastCrntMip != m_crntMip)
+			{
+				// Re-create the image view
+				TextureViewInitInfo viewInitInf(m_textureResource->getGrTexture());
+				viewInitInf.m_firstMipmap = m_crntMip;
+				m_textureView = getSceneGraph().getGrManager().newTextureView(viewInitInf);
+			}
+		}
+
+		ImGui::EndChild();
+
+		ImGui::SameLine();
+
+		ImGui::BeginChild("Image", ImVec2(ImGui::GetWindowContentRegionWidth() * 0.75f, -1.0f), false,
+						  ImGuiWindowFlags_HorizontalScrollbar);
+
+		ImGui::Image(const_cast<TextureView*>(m_textureView.get()),
+					 ImVec2(F32(grTex.getWidth()) * m_zoom, F32(grTex.getHeight()) * m_zoom), ImVec2(0.0f, 0.0f),
+					 ImVec2(1.0f, 1.0f), Vec4(1.0f), Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+		ImGui::EndChild();
 
 
 		canvas->popFont();
 		canvas->popFont();
 		ImGui::End();
 		ImGui::End();
@@ -61,9 +126,20 @@ public:
 
 
 		ANKI_CHECK(App::init(config, allocAligned, nullptr));
 		ANKI_CHECK(App::init(config, allocAligned, nullptr));
 
 
+		// Load the texture
+		if(argc < 2)
+		{
+			ANKI_LOGE("Wrong number of arguments");
+			return Error::USER_DATA;
+		}
+		TextureResourcePtr tex;
+		ANKI_CHECK(getResourceManager().loadResource(argv[1], tex, false));
+
+		// Create the node
 		SceneGraph& scene = getSceneGraph();
 		SceneGraph& scene = getSceneGraph();
 		TextureViewerUiNode* node;
 		TextureViewerUiNode* node;
 		ANKI_CHECK(scene.newSceneNode("TextureViewer", node));
 		ANKI_CHECK(scene.newSceneNode("TextureViewer", node));
+		node->m_textureResource = tex;
 
 
 		return Error::NONE;
 		return Error::NONE;
 	}
 	}