From aefcf9e90b465185b35e317aadad08cdc489558c Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Mon, 25 Sep 2023 19:49:43 +0800 Subject: [PATCH] only-draw-polygon-edge --- zenovis/src/bate/GraphicPrimitive.cpp | 101 +++++++++++++++++++++++--- zenovis/src/bate/shader/edge.frag | 16 ++++ zenovis/src/bate/shader/edge.vert | 21 ++++++ 3 files changed, 129 insertions(+), 9 deletions(-) create mode 100644 zenovis/src/bate/shader/edge.frag create mode 100644 zenovis/src/bate/shader/edge.vert diff --git a/zenovis/src/bate/GraphicPrimitive.cpp b/zenovis/src/bate/GraphicPrimitive.cpp index df73a75548..4a3650bbed 100644 --- a/zenovis/src/bate/GraphicPrimitive.cpp +++ b/zenovis/src/bate/GraphicPrimitive.cpp @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include #include #include @@ -354,12 +356,63 @@ struct ZhxxGraphicPrimitive final : IGraphicDraw { std::shared_ptr primUnique; zeno::PrimitiveObject *prim; + ZhxxDrawObject polyEdgeObj = {}; + explicit ZhxxGraphicPrimitive(Scene *scene_, zeno::PrimitiveObject *primArg) : scene(scene_), primUnique(std::make_shared(*primArg)) { prim = primUnique.get(); invisible = prim->userData().get2("invisible", 0); zeno::log_trace("rendering primitive size {}", prim->size()); + { + bool any_not_triangle = false; + for (const auto &[b, c]: prim->polys) { + if (c > 3) { + any_not_triangle = true; + } + } + if (any_not_triangle) { + std::map> edges; + auto add_edge = [&](int a, int b) { + zeno::log_info("a:{}, b: {}", a, b); + int p0 = prim->loops[a]; + int p1 = prim->loops[b]; + if (p0 > p1) { + std::swap(p0, p1); + } + if (!edges.count(p0)) { + edges[p0] = {}; + } + edges[p0].insert(p1); + }; + for (const auto &[b, c]: prim->polys) { + for (auto i = 2; i < c; i++) { + if (i == 2) { + add_edge(b, b + 1); + } + add_edge(b + i - 1, b + i); + if (i == c - 1) { + add_edge(b, b + i); + } + } + } + std::vector edge_list; + for (const auto& [a, s]: edges) { + for (const auto b: s) { + edge_list.push_back(a); + edge_list.push_back(b); + } + } + polyEdgeObj.count = edge_list.size(); + polyEdgeObj.ebo = std::make_unique(GL_ELEMENT_ARRAY_BUFFER); + polyEdgeObj.ebo->bind_data(edge_list.data(), edge_list.size() * sizeof(edge_list[0])); + auto vbo = std::make_unique(GL_ARRAY_BUFFER); + vbo->bind_data(prim->verts.data(), prim->verts.size() * sizeof(prim->verts[0])); + polyEdgeObj.vbos.push_back(std::move(vbo)); + polyEdgeObj.prog = get_edge_program(); + } + } + if (!prim->attr_is("pos")) { auto &pos = prim->add_attr("pos"); for (size_t i = 0; i < pos.size(); i++) { @@ -643,15 +696,34 @@ struct ZhxxGraphicPrimitive final : IGraphicDraw { bool selected = scene->selected.count(nameid) > 0; if (scene->drawOptions->render_wireframe || selected) { - CHECK_GL(glEnable(GL_POLYGON_OFFSET_LINE)); - CHECK_GL(glPolygonOffset(0, 0)); - CHECK_GL(glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)); - triObj.prog->set_uniformi("mRenderWireframe", true); - CHECK_GL(glDrawElements(GL_TRIANGLES, - /*count=*/triObj.count * 3, - GL_UNSIGNED_INT, /*first=*/0)); - CHECK_GL(glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); - CHECK_GL(glDisable(GL_POLYGON_OFFSET_LINE)); + if (polyEdgeObj.count) { + polyEdgeObj.prog->use(); + scene->camera->set_program_uniforms(polyEdgeObj.prog); + + polyEdgeObj.vbos[0]->bind(); + polyEdgeObj.vbos[0]->attribute(/*index=*/0, + /*offset=*/sizeof(float) * 0, + /*stride=*/sizeof(float) * 3, GL_FLOAT, + /*count=*/3); + polyEdgeObj.ebo->bind(); + + CHECK_GL(glDrawElements(GL_LINES, polyEdgeObj.count, GL_UNSIGNED_INT, 0)); + + polyEdgeObj.ebo->unbind(); + polyEdgeObj.vbos[0]->disable_attribute(0); + polyEdgeObj.vbos[0]->unbind(); + } + else { + CHECK_GL(glEnable(GL_POLYGON_OFFSET_LINE)); + CHECK_GL(glPolygonOffset(0, 0)); + CHECK_GL(glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)); + triObj.prog->set_uniformi("mRenderWireframe", true); + CHECK_GL(glDrawElements(GL_TRIANGLES, + /*count=*/triObj.count * 3, + GL_UNSIGNED_INT, /*first=*/0)); + CHECK_GL(glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); + CHECK_GL(glDisable(GL_POLYGON_OFFSET_LINE)); + } } triObj.ebo->unbind(); if (triObj.vbos.size()) { @@ -695,6 +767,17 @@ struct ZhxxGraphicPrimitive final : IGraphicDraw { return scene->shaderMan->compile_program(vert, frag); } + + Program *get_edge_program() { + auto vert = +#include "shader/edge.vert" + ; + + auto frag = +#include "shader/edge.frag" + ; + return scene->shaderMan->compile_program(vert, frag); + } }; } diff --git a/zenovis/src/bate/shader/edge.frag b/zenovis/src/bate/shader/edge.frag new file mode 100644 index 0000000000..ecd20cf189 --- /dev/null +++ b/zenovis/src/bate/shader/edge.frag @@ -0,0 +1,16 @@ +R"(#version 130 + +uniform mat4 mVP; +uniform mat4 mInvVP; +uniform mat4 mView; +uniform mat4 mProj; +uniform mat4 mInvView; +uniform mat4 mInvProj; + +in vec3 position; +out vec4 fColor; +void main() +{ + fColor = vec4(0.89, 0.57, 0.15, 1.0); +} +)" diff --git a/zenovis/src/bate/shader/edge.vert b/zenovis/src/bate/shader/edge.vert new file mode 100644 index 0000000000..a78ad397af --- /dev/null +++ b/zenovis/src/bate/shader/edge.vert @@ -0,0 +1,21 @@ +R"(#version 330 + +uniform mat4 mVP; +uniform mat4 mInvVP; +uniform mat4 mView; +uniform mat4 mProj; +uniform mat4 mInvView; +uniform mat4 mInvProj; + +in vec3 vPosition; + +out vec3 position; +out vec3 color; + +void main() +{ + position = vPosition; + + gl_Position = mVP * vec4(position, 1.0); +} +)"