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

Fixes #1021
Closes #1124
This commit is contained in:
LD 2021-03-03 22:04:29 +01:00 committed by rdb
parent 94806801e3
commit 23150bd6d6
5 changed files with 43 additions and 6 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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