Browse Source

pgraph: Add the shader attrib to the filled wireframe render state

Fixes #1021
Closes #1124
LD 4 years ago
parent
commit
23150bd6d6

+ 7 - 0
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

+ 2 - 0
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

+ 32 - 6
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;
 }

+ 1 - 0
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;

+ 1 - 0
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