From 46221e936fc08af06060619e995b1c80ad082931 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Sun, 22 Jan 2023 16:17:10 +0100 Subject: [PATCH] feat: Allow the 3d visualizer to use index buffers --- .../builtin/source/content/pl_visualizers.cpp | 56 ++++++++++++++++--- plugins/builtin/source/ui/pattern_drawer.cpp | 7 ++- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/plugins/builtin/source/content/pl_visualizers.cpp b/plugins/builtin/source/content/pl_visualizers.cpp index 1f4da6ce8..27e145e08 100644 --- a/plugins/builtin/source/content/pl_visualizers.cpp +++ b/plugins/builtin/source/content/pl_visualizers.cpp @@ -121,14 +121,49 @@ namespace hex::plugin::builtin { } } - void draw3DVisualizer(pl::ptrn::Pattern &pattern, pl::ptrn::Iteratable &, bool shouldReset, const std::vector &) { + template + static auto readValues(pl::ptrn::Pattern *pattern){ + std::vector result; + + if (pattern->getSize() == 0) + return result; + + if (auto iteratable = dynamic_cast(pattern); iteratable != nullptr) { + result.reserve(iteratable->getEntryCount()); + iteratable->forEachEntry(0, iteratable->getEntryCount(), [&](u64, pl::ptrn::Pattern *entry) { + for (auto [offset, child] : entry->getChildren()) { + child->setOffset(offset); + + T value; + if (std::floating_point) + value = pl::core::Token::literalToFloatingPoint(child->getValue()); + else + value = pl::core::Token::literalToUnsigned(child->getValue()); + + result.push_back(value); + } + }); + } else { + result.reserve(pattern->getSize() / sizeof(float)); + pattern->getEvaluator()->readData(pattern->getOffset(), result.data(), result.size() * sizeof(float), pattern->getSection()); + } + + return result; + }; + + void draw3DVisualizer(pl::ptrn::Pattern &, pl::ptrn::Iteratable &, bool shouldReset, const std::vector &arguments) { + auto verticesPattern = pl::core::Token::literalToPattern(arguments[1]); + auto indicesPattern = pl::core::Token::literalToPattern(arguments[2]); + static ImGui::Texture texture; static float scaling = 0.5F; static gl::Vector rotation = { { 1.0F, -1.0F, 0.0F } }; static std::vector vertices, normals; + static std::vector indices; static gl::Shader shader; static gl::VertexArray vertexArray; static gl::Buffer vertexBuffer, normalBuffer; + static gl::Buffer indexBuffer; { auto dragDelta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Middle); @@ -144,13 +179,12 @@ namespace hex::plugin::builtin { } if (shouldReset) { - vertices.clear(); - vertices.resize(pattern.getSize() / sizeof(float)); - pattern.getEvaluator()->readData(pattern.getOffset(), vertices.data(), vertices.size() * sizeof(float), pattern.getSection()); + vertices = readValues(verticesPattern); + indices = readValues(indicesPattern); normals.clear(); normals.resize(vertices.size()); - for (u32 i = 0; i < normals.size(); i += 9) { + for (u32 i = 0; i < normals.size() && normals.size() >= 9; i += 9) { auto v1 = gl::Vector({ vertices[i + 0], vertices[i + 1], vertices[i + 2] }); auto v2 = gl::Vector({ vertices[i + 3], vertices[i + 4], vertices[i + 5] }); auto v3 = gl::Vector({ vertices[i + 6], vertices[i + 7], vertices[i + 8] }); @@ -174,10 +208,14 @@ namespace hex::plugin::builtin { vertexBuffer = gl::Buffer (gl::BufferType::Vertex, vertices); normalBuffer = gl::Buffer(gl::BufferType::Vertex, normals); + indexBuffer = gl::Buffer(gl::BufferType::Index, indices); vertexArray.addBuffer(0, vertexBuffer); vertexArray.addBuffer(1, normalBuffer); + if (!indices.empty()) + vertexArray.addBuffer(2, indexBuffer); + vertexBuffer.unbind(); vertexArray.unbind(); } @@ -201,7 +239,11 @@ namespace hex::plugin::builtin { glViewport(0, 0, renderTexture.getWidth(), renderTexture.getHeight()); glClearColor(0.00F, 0.00F, 0.00F, 0.00f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - vertexBuffer.draw(); + + if (indices.empty()) + vertexBuffer.draw(); + else + indexBuffer.draw(); vertexArray.unbind(); shader.unbind(); @@ -220,7 +262,7 @@ namespace hex::plugin::builtin { ContentRegistry::PatternLanguage::addVisualizer("image", drawImageVisualizer, 0); ContentRegistry::PatternLanguage::addVisualizer("bitmap", drawBitmapVisualizer, 3); ContentRegistry::PatternLanguage::addVisualizer("disassembler", drawDisassemblyVisualizer, 4); - ContentRegistry::PatternLanguage::addVisualizer("3d", draw3DVisualizer, 0); + ContentRegistry::PatternLanguage::addVisualizer("3d", draw3DVisualizer, 2); } } \ No newline at end of file diff --git a/plugins/builtin/source/ui/pattern_drawer.cpp b/plugins/builtin/source/ui/pattern_drawer.cpp index f7deb166d..d4de87ae7 100644 --- a/plugins/builtin/source/ui/pattern_drawer.cpp +++ b/plugins/builtin/source/ui/pattern_drawer.cpp @@ -123,7 +123,12 @@ namespace hex::plugin::builtin::ui { if (visualizer.parameterCount != arguments.size() - 1) { ImGui::TextUnformatted("hex.builtin.pattern_drawer.visualizer.invalid_parameter_count"_lang); } else { - visualizer.callback(pattern, iteratable, reset, arguments); + try { + visualizer.callback(pattern, iteratable, reset, arguments); + } catch (std::exception &e) { + ImGui::TextUnformatted(e.what()); + } + } } else { ImGui::TextUnformatted("hex.builtin.pattern_drawer.visualizer.unknown"_lang);