|
@@ -10,7 +10,7 @@ using namespace anki;
|
|
|
class TextureViewerUiNode : public SceneNode
|
|
class TextureViewerUiNode : public SceneNode
|
|
|
{
|
|
{
|
|
|
public:
|
|
public:
|
|
|
- ImageResourcePtr m_imageResource;
|
|
|
|
|
|
|
+ ImageViewerUi m_ui;
|
|
|
|
|
|
|
|
TextureViewerUiNode(CString name)
|
|
TextureViewerUiNode(CString name)
|
|
|
: SceneNode(name)
|
|
: SceneNode(name)
|
|
@@ -22,7 +22,7 @@ public:
|
|
|
},
|
|
},
|
|
|
this);
|
|
this);
|
|
|
|
|
|
|
|
- ANKI_CHECK_AND_IGNORE(ResourceManager::getSingleton().loadResource("ShaderBinaries/UiVisualizeImage.ankiprogbin", m_imageProgram));
|
|
|
|
|
|
|
+ m_ui.m_open = true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void frameUpdate([[maybe_unused]] Second prevUpdateTime, [[maybe_unused]] Second crntTime) override
|
|
void frameUpdate([[maybe_unused]] Second prevUpdateTime, [[maybe_unused]] Second crntTime) override
|
|
@@ -31,237 +31,22 @@ public:
|
|
|
|
|
|
|
|
private:
|
|
private:
|
|
|
ImFont* m_font = nullptr;
|
|
ImFont* m_font = nullptr;
|
|
|
- ShaderProgramResourcePtr m_imageProgram;
|
|
|
|
|
- ShaderProgramPtr m_imageGrProgram;
|
|
|
|
|
-
|
|
|
|
|
- U32 m_crntMip = 0;
|
|
|
|
|
- F32 m_zoom = 1.0f;
|
|
|
|
|
- F32 m_depth = 0.0f;
|
|
|
|
|
- Bool m_pointSampling = true;
|
|
|
|
|
- Array<Bool, 4> m_colorChannel = {true, true, true, true};
|
|
|
|
|
- F32 m_maxColorValue = 1.0f;
|
|
|
|
|
|
|
|
|
|
void draw(UiCanvas& canvas)
|
|
void draw(UiCanvas& canvas)
|
|
|
{
|
|
{
|
|
|
if(!m_font)
|
|
if(!m_font)
|
|
|
{
|
|
{
|
|
|
- m_font = canvas.addFont("EngineAssets/UbuntuMonoRegular.ttf");
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- const Texture& grTex = m_imageResource->getTexture();
|
|
|
|
|
- const U32 colorComponentCount = getFormatInfo(grTex.getFormat()).m_componentCount;
|
|
|
|
|
- ANKI_ASSERT(grTex.getTextureType() == TextureType::k2D || grTex.getTextureType() == TextureType::k3D);
|
|
|
|
|
-
|
|
|
|
|
- if(!m_imageGrProgram.isCreated())
|
|
|
|
|
- {
|
|
|
|
|
- ShaderProgramResourceVariantInitInfo variantInit(m_imageProgram);
|
|
|
|
|
- variantInit.addMutation("TEXTURE_TYPE", (grTex.getTextureType() == TextureType::k2D) ? 0 : 1);
|
|
|
|
|
-
|
|
|
|
|
- const ShaderProgramResourceVariant* variant;
|
|
|
|
|
- m_imageProgram->getOrCreateVariant(variantInit, variant);
|
|
|
|
|
- m_imageGrProgram.reset(&variant->getProgram());
|
|
|
|
|
|
|
+ m_font = canvas.addFont("EngineAssets/UbuntuRegular.ttf");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove;
|
|
|
|
|
- ImGui::Begin("Console", nullptr, windowFlags);
|
|
|
|
|
-
|
|
|
|
|
ImGui::PushFont(m_font, 16.0f);
|
|
ImGui::PushFont(m_font, 16.0f);
|
|
|
|
|
|
|
|
ImGui::SetWindowPos(Vec2(0.0f, 0.0f));
|
|
ImGui::SetWindowPos(Vec2(0.0f, 0.0f));
|
|
|
ImGui::SetWindowSize(canvas.getSizef());
|
|
ImGui::SetWindowSize(canvas.getSizef());
|
|
|
|
|
|
|
|
- ImGui::BeginChild("Tools", Vec2(-1.0f, 30.0f), ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeX, ImGuiWindowFlags_None);
|
|
|
|
|
-
|
|
|
|
|
- // Zoom
|
|
|
|
|
- if(ImGui::Button("-"))
|
|
|
|
|
- {
|
|
|
|
|
- m_zoom -= 0.1f;
|
|
|
|
|
- }
|
|
|
|
|
- ImGui::SameLine();
|
|
|
|
|
- ImGui::DragFloat("##Zoom", &m_zoom, 0.01f, 0.1f, 20.0f, "Zoom %.3f");
|
|
|
|
|
- ImGui::SameLine();
|
|
|
|
|
- if(ImGui::Button("+"))
|
|
|
|
|
- {
|
|
|
|
|
- m_zoom += 0.1f;
|
|
|
|
|
- }
|
|
|
|
|
- ImGui::SameLine();
|
|
|
|
|
- ImGui::Spacing();
|
|
|
|
|
- ImGui::SameLine();
|
|
|
|
|
-
|
|
|
|
|
- // Sampling
|
|
|
|
|
- ImGui::Checkbox("Point sampling", &m_pointSampling);
|
|
|
|
|
- ImGui::SameLine();
|
|
|
|
|
- ImGui::Spacing();
|
|
|
|
|
- ImGui::SameLine();
|
|
|
|
|
-
|
|
|
|
|
- // Colors
|
|
|
|
|
- ImGui::Checkbox("Red", &m_colorChannel[0]);
|
|
|
|
|
- ImGui::SameLine();
|
|
|
|
|
- ImGui::Checkbox("Green", &m_colorChannel[1]);
|
|
|
|
|
- ImGui::SameLine();
|
|
|
|
|
- ImGui::Checkbox("Blue", &m_colorChannel[2]);
|
|
|
|
|
- ImGui::SameLine();
|
|
|
|
|
- if(colorComponentCount == 4)
|
|
|
|
|
- {
|
|
|
|
|
- ImGui::Checkbox("Alpha", &m_colorChannel[3]);
|
|
|
|
|
- ImGui::SameLine();
|
|
|
|
|
- }
|
|
|
|
|
- ImGui::Spacing();
|
|
|
|
|
- ImGui::SameLine();
|
|
|
|
|
-
|
|
|
|
|
- // Mips combo
|
|
|
|
|
- {
|
|
|
|
|
- UiStringList mipLabels;
|
|
|
|
|
- for(U32 mip = 0; mip < grTex.getMipmapCount(); ++mip)
|
|
|
|
|
- {
|
|
|
|
|
- mipLabels.pushBackSprintf("Mip %u (%u x %u)", mip, grTex.getWidth() >> mip, grTex.getHeight() >> mip);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if(ImGui::BeginCombo("##Mipmap", (mipLabels.getBegin() + m_crntMip)->cstr(), ImGuiComboFlags_HeightLarge))
|
|
|
|
|
- {
|
|
|
|
|
- for(U32 mip = 0; mip < grTex.getMipmapCount(); ++mip)
|
|
|
|
|
- {
|
|
|
|
|
- const Bool isSelected = (m_crntMip == mip);
|
|
|
|
|
- if(ImGui::Selectable((mipLabels.getBegin() + mip)->cstr(), isSelected))
|
|
|
|
|
- {
|
|
|
|
|
- m_crntMip = mip;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if(isSelected)
|
|
|
|
|
- {
|
|
|
|
|
- ImGui::SetItemDefaultFocus();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- ImGui::EndCombo();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- ImGui::SameLine();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Depth
|
|
|
|
|
- if(grTex.getTextureType() == TextureType::k3D)
|
|
|
|
|
- {
|
|
|
|
|
- UiStringList labels;
|
|
|
|
|
- for(U32 d = 0; d < grTex.getDepth(); ++d)
|
|
|
|
|
- {
|
|
|
|
|
- labels.pushBackSprintf("Depth %u", d);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if(ImGui::BeginCombo("##Depth", (labels.getBegin() + U32(m_depth))->cstr(), ImGuiComboFlags_HeightLarge))
|
|
|
|
|
- {
|
|
|
|
|
- for(U32 d = 0; d < grTex.getDepth(); ++d)
|
|
|
|
|
- {
|
|
|
|
|
- const Bool isSelected = (m_depth == F32(d));
|
|
|
|
|
- if(ImGui::Selectable((labels.getBegin() + d)->cstr(), isSelected))
|
|
|
|
|
- {
|
|
|
|
|
- m_depth = F32(d);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if(isSelected)
|
|
|
|
|
- {
|
|
|
|
|
- ImGui::SetItemDefaultFocus();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- ImGui::EndCombo();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- ImGui::SameLine();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Max color slider
|
|
|
|
|
- ImGui::SliderFloat("##Max color", &m_maxColorValue, 0.0f, 5.0f, "Max color = %.3f");
|
|
|
|
|
- ImGui::SameLine();
|
|
|
|
|
-
|
|
|
|
|
- // Avg color
|
|
|
|
|
- {
|
|
|
|
|
- const Vec4 avgColor = m_imageResource->getAverageColor();
|
|
|
|
|
-
|
|
|
|
|
- ImGui::Text("Average Color %.2f %.2f %.2f %.2f", avgColor.x(), avgColor.y(), avgColor.z(), avgColor.w());
|
|
|
|
|
- ImGui::SameLine();
|
|
|
|
|
-
|
|
|
|
|
- ImGui::ColorButton("Average color", avgColor);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Next
|
|
|
|
|
- ImGui::EndChild();
|
|
|
|
|
-
|
|
|
|
|
- ImGui::BeginChild("Image", Vec2(-1.0f, -1.0f), ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeX,
|
|
|
|
|
- ImGuiWindowFlags_HorizontalScrollbar
|
|
|
|
|
- | (Input::getSingleton().getKey(KeyCode::kLeftCtrl) > 0 ? ImGuiWindowFlags_NoScrollWithMouse : 0));
|
|
|
|
|
-
|
|
|
|
|
- // Image
|
|
|
|
|
- {
|
|
|
|
|
- // Center image
|
|
|
|
|
- const Vec2 imageSize = Vec2(F32(grTex.getWidth()), F32(grTex.getHeight())) * m_zoom;
|
|
|
|
|
-
|
|
|
|
|
- class ExtraPushConstants
|
|
|
|
|
- {
|
|
|
|
|
- public:
|
|
|
|
|
- Vec4 m_colorScale;
|
|
|
|
|
- Vec4 m_depth;
|
|
|
|
|
- } pc;
|
|
|
|
|
- pc.m_colorScale.x() = F32(m_colorChannel[0]) / m_maxColorValue;
|
|
|
|
|
- pc.m_colorScale.y() = F32(m_colorChannel[1]) / m_maxColorValue;
|
|
|
|
|
- pc.m_colorScale.z() = F32(m_colorChannel[2]) / m_maxColorValue;
|
|
|
|
|
- pc.m_colorScale.w() = F32(m_colorChannel[3]);
|
|
|
|
|
-
|
|
|
|
|
- pc.m_depth = Vec4((m_depth + 0.5f) / F32(grTex.getDepth()));
|
|
|
|
|
-
|
|
|
|
|
- ImTextureID texid;
|
|
|
|
|
- texid.m_texture = &m_imageResource->getTexture();
|
|
|
|
|
- texid.m_textureSubresource = TextureSubresourceDesc::surface(m_crntMip, 0, 0, DepthStencilAspectBit::kNone);
|
|
|
|
|
- texid.m_customProgram = m_imageGrProgram.get();
|
|
|
|
|
- texid.m_extraFastConstantsSize = U8(sizeof(pc));
|
|
|
|
|
- texid.setExtraFastConstants(&pc, sizeof(pc));
|
|
|
|
|
- texid.m_pointSampling = m_pointSampling;
|
|
|
|
|
- ImGui::Image(texid, imageSize);
|
|
|
|
|
-
|
|
|
|
|
- if(ImGui::IsItemHovered())
|
|
|
|
|
- {
|
|
|
|
|
- if(Input::getSingleton().getKey(KeyCode::kLeftCtrl) > 0)
|
|
|
|
|
- {
|
|
|
|
|
- // Zoom
|
|
|
|
|
- const F32 zoomSpeed = 0.05f;
|
|
|
|
|
- if(Input::getSingleton().getMouseButton(MouseButton::kScrollDown) > 0)
|
|
|
|
|
- {
|
|
|
|
|
- m_zoom *= 1.0f - zoomSpeed;
|
|
|
|
|
- }
|
|
|
|
|
- else if(Input::getSingleton().getMouseButton(MouseButton::kScrollUp) > 0)
|
|
|
|
|
- {
|
|
|
|
|
- m_zoom *= 1.0f + zoomSpeed;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Pan
|
|
|
|
|
- if(Input::getSingleton().getMouseButton(MouseButton::kLeft) > 0)
|
|
|
|
|
- {
|
|
|
|
|
- auto toWindow = [](Vec2 in) {
|
|
|
|
|
- in = in * 0.5f + 0.5f;
|
|
|
|
|
- in.y() = 1.0f - in.y();
|
|
|
|
|
- in *= Vec2(UVec2(NativeWindow::getSingleton().getWidth(), NativeWindow::getSingleton().getHeight()));
|
|
|
|
|
- return in;
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- const Vec2 delta =
|
|
|
|
|
- toWindow(Input::getSingleton().getMousePositionNdc()) - toWindow(Input::getSingleton().getMousePreviousPositionNdc());
|
|
|
|
|
-
|
|
|
|
|
- if(delta.x() != 0.0f)
|
|
|
|
|
- {
|
|
|
|
|
- ImGui::SetScrollX(ImGui::GetScrollX() - delta.x());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if(delta.y() != 0.0f)
|
|
|
|
|
- {
|
|
|
|
|
- ImGui::SetScrollY(ImGui::GetScrollY() - delta.y());
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- ImGui::EndChild();
|
|
|
|
|
|
|
+ m_ui.drawWindow(canvas, Vec2(0.0f), canvas.getSizef(), ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove);
|
|
|
|
|
|
|
|
ImGui::PopFont();
|
|
ImGui::PopFont();
|
|
|
- ImGui::End();
|
|
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -307,7 +92,7 @@ public:
|
|
|
|
|
|
|
|
// Create the node
|
|
// Create the node
|
|
|
TextureViewerUiNode* node = SceneGraph::getSingleton().newSceneNode<TextureViewerUiNode>("TextureViewer");
|
|
TextureViewerUiNode* node = SceneGraph::getSingleton().newSceneNode<TextureViewerUiNode>("TextureViewer");
|
|
|
- node->m_imageResource = std::move(image);
|
|
|
|
|
|
|
+ node->m_ui.m_image = std::move(image);
|
|
|
|
|
|
|
|
return Error::kNone;
|
|
return Error::kNone;
|
|
|
}
|
|
}
|