From 23150bd6d6014a55b125e7aeee2f042e52420f0e Mon Sep 17 00:00:00 2001 From: LD Date: Wed, 3 Mar 2021 22:04:29 +0100 Subject: [PATCH] pgraph: Add the shader attrib to the filled wireframe render state Fixes #1021 Closes #1124 --- panda/src/pgraph/config_pgraph.cxx | 7 ++++++ panda/src/pgraph/config_pgraph.h | 2 ++ panda/src/pgraph/cullResult.cxx | 38 +++++++++++++++++++++++++----- panda/src/pgraph/cullResult.h | 1 + samples/shader-terrain/main.py | 1 + 5 files changed, 43 insertions(+), 6 deletions(-) diff --git a/panda/src/pgraph/config_pgraph.cxx b/panda/src/pgraph/config_pgraph.cxx index 5729e22067..795300223a 100644 --- a/panda/src/pgraph/config_pgraph.cxx +++ b/panda/src/pgraph/config_pgraph.cxx @@ -373,6 +373,13 @@ ConfigVariableBool allow_live_flatten "only has an effect when Panda is not compiled for a release " "build.")); +ConfigVariableBool filled_wireframe_apply_shader +("filled-wireframe-apply-shader", false, + PRC_DESC("Set this true to apply any shader configured on nodes onto the " + "filled wireframe overlay. The wireframe color is multiplied with " + "the result of the fragment shader. This is helpful when the shader " + "alters the position of the vertices and makes the overlay wrong.")); + /** * Initializes the library. This must be called at least once before any of * the functions or classes in this library can be used. Normally it will be diff --git a/panda/src/pgraph/config_pgraph.h b/panda/src/pgraph/config_pgraph.h index 11094b9d16..f1bec0168e 100644 --- a/panda/src/pgraph/config_pgraph.h +++ b/panda/src/pgraph/config_pgraph.h @@ -74,6 +74,8 @@ extern ConfigVariableString default_model_extension; extern ConfigVariableBool allow_live_flatten; +extern ConfigVariableBool filled_wireframe_apply_shader; + extern EXPCL_PANDA_PGRAPH void init_libpgraph(); #endif diff --git a/panda/src/pgraph/cullResult.cxx b/panda/src/pgraph/cullResult.cxx index 65c9555bff..b6b238f838 100644 --- a/panda/src/pgraph/cullResult.cxx +++ b/panda/src/pgraph/cullResult.cxx @@ -28,6 +28,7 @@ #include "config_pgraph.h" #include "depthOffsetAttrib.h" #include "colorBlendAttrib.h" +#include "shaderAttrib.h" TypeHandle CullResult::_type_handle; @@ -133,7 +134,9 @@ add_object(CullableObject *object, const CullTraverser *traverser) { if (object->_state->get_attrib(rmode)) { if (rmode->get_mode() == RenderModeAttrib::M_filled_wireframe) { CullableObject *wireframe_part = new CullableObject(*object); - wireframe_part->_state = get_wireframe_overlay_state(rmode); + const ShaderAttrib *shader = nullptr; + object->_state->get_attrib(shader); + wireframe_part->_state = get_wireframe_overlay_state(rmode, shader); if (wireframe_part->munge_geom (_gsg, _gsg->get_geom_munger(wireframe_part->_state, current_thread), @@ -521,13 +524,36 @@ get_wireframe_filled_state() { */ CPT(RenderState) CullResult:: get_wireframe_overlay_state(const RenderModeAttrib *rmode) { - return RenderState::make( + return get_wireframe_overlay_state(rmode, nullptr); +} + +/** + * Returns a RenderState that renders only the wireframe part of an + * M_filled_wireframe model. + * If a shader attrib is provided, a constant color is used in ColorBlendAttrib + * to emulate the flat color. + */ +CPT(RenderState) CullResult:: +get_wireframe_overlay_state(const RenderModeAttrib *rmode, const ShaderAttrib *shader) { + CPT(RenderState) state = RenderState::make( DepthOffsetAttrib::make(1, 0, 0.99999f), - ColorAttrib::make_flat(rmode->get_wireframe_color()), - ColorBlendAttrib::make(ColorBlendAttrib::M_add, - ColorBlendAttrib::O_incoming_alpha, - ColorBlendAttrib::O_one_minus_incoming_alpha), RenderModeAttrib::make(RenderModeAttrib::M_wireframe, rmode->get_thickness(), rmode->get_perspective())); + if (filled_wireframe_apply_shader) { + state = state->add_attrib(ColorBlendAttrib::make(ColorBlendAttrib::M_add, + ColorBlendAttrib::O_zero, + ColorBlendAttrib::O_constant_color, + ColorBlendAttrib::M_add, + ColorBlendAttrib::O_one, + ColorBlendAttrib::O_one_minus_incoming_alpha, + rmode->get_wireframe_color())); + state = state->add_attrib(shader); + } else { + state = state->add_attrib(ColorBlendAttrib::make(ColorBlendAttrib::M_add, + ColorBlendAttrib::O_incoming_alpha, + ColorBlendAttrib::O_one_minus_incoming_alpha)); + state = state->add_attrib(ColorAttrib::make_flat(rmode->get_wireframe_color())); + } + return state; } diff --git a/panda/src/pgraph/cullResult.h b/panda/src/pgraph/cullResult.h index df1d166426..24c0df3d78 100644 --- a/panda/src/pgraph/cullResult.h +++ b/panda/src/pgraph/cullResult.h @@ -78,6 +78,7 @@ private: static const RenderState *get_dual_opaque_state(); static const RenderState *get_wireframe_filled_state(); static CPT(RenderState) get_wireframe_overlay_state(const RenderModeAttrib *rmode); + static CPT(RenderState) get_wireframe_overlay_state(const RenderModeAttrib *rmode, const ShaderAttrib *shader); GraphicsStateGuardianBase *_gsg; PStatCollector _draw_region_pcollector; diff --git a/samples/shader-terrain/main.py b/samples/shader-terrain/main.py index 10bffb3767..8d500b4d05 100644 --- a/samples/shader-terrain/main.py +++ b/samples/shader-terrain/main.py @@ -20,6 +20,7 @@ class ShaderTerrainDemo(ShowBase): textures-power-2 none gl-coordinate-system default window-title Panda3D ShaderTerrainMesh Demo + filled-wireframe-apply-shader true """) # Initialize the showbase