mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
Shader generation should be done in cull, not in draw
This commit is contained in:
parent
a56f722c09
commit
7ba0469148
@ -1360,9 +1360,9 @@ cull_and_draw_together(const GraphicsEngine::Windows &wlist,
|
||||
Thread *current_thread) {
|
||||
PStatTimer timer(_cull_pcollector, current_thread);
|
||||
|
||||
Windows::const_iterator wi;
|
||||
for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
|
||||
GraphicsOutput *win = (*wi);
|
||||
size_t wlist_size = wlist.size();
|
||||
for (size_t wi = 0; wi < wlist_size; ++wi) {
|
||||
GraphicsOutput *win = wlist[wi];
|
||||
if (win->is_active() && win->get_gsg()->is_active()) {
|
||||
if (win->flip_ready()) {
|
||||
{
|
||||
@ -1486,9 +1486,9 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
||||
typedef pmap<NodePath, DisplayRegion *> AlreadyCulled;
|
||||
AlreadyCulled already_culled;
|
||||
|
||||
Windows::const_iterator wi;
|
||||
for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
|
||||
GraphicsOutput *win = (*wi);
|
||||
size_t wlist_size = wlist.size();
|
||||
for (size_t wi = 0; wi < wlist_size; ++wi) {
|
||||
GraphicsOutput *win = wlist[wi];
|
||||
if (win->is_active() && win->get_gsg()->is_active()) {
|
||||
PStatTimer timer(win->get_cull_window_pcollector(), current_thread);
|
||||
int num_display_regions = win->get_num_active_display_regions();
|
||||
@ -1997,6 +1997,14 @@ setup_scene(GraphicsStateGuardian *gsg, DisplayRegionPipelineReader *dr) {
|
||||
CPT(TransformState) cs_world_transform = cs_transform->compose(world_transform);
|
||||
scene_setup->set_cs_world_transform(cs_world_transform);
|
||||
|
||||
// Make sure that the GSG has a ShaderGenerator for the munger
|
||||
// to use. We have to do this here because the ShaderGenerator
|
||||
// needs a host window pointer. Hopefully we'll be able to
|
||||
// eliminate that requirement in the future.
|
||||
if (gsg->get_shader_generator() == NULL) {
|
||||
gsg->set_shader_generator(new ShaderGenerator(gsg, window));
|
||||
}
|
||||
|
||||
return scene_setup;
|
||||
}
|
||||
|
||||
|
@ -214,6 +214,28 @@ get_loader() const {
|
||||
return _loader;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::set_shader_generator
|
||||
// Access: Public
|
||||
// Description: Sets the ShaderGenerator object that will be used
|
||||
// by this GSG to generate shaders when necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsStateGuardian::
|
||||
set_shader_generator(ShaderGenerator *shader_generator) {
|
||||
_shader_generator = shader_generator;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_shader_generator
|
||||
// Access: Public
|
||||
// Description: Returns the ShaderGenerator object that will be used
|
||||
// by this GSG to generate shaders when necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ShaderGenerator *GraphicsStateGuardian::
|
||||
get_shader_generator() const {
|
||||
return _shader_generator;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_pipe
|
||||
// Access: Published
|
||||
|
@ -266,8 +266,6 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
|
||||
|
||||
_gamma = 1.0f;
|
||||
_texture_quality_override = Texture::QL_default;
|
||||
|
||||
_shader_generator = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -278,12 +276,6 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
|
||||
GraphicsStateGuardian::
|
||||
~GraphicsStateGuardian() {
|
||||
remove_gsg(this);
|
||||
|
||||
if (_shader_generator) {
|
||||
delete _shader_generator;
|
||||
_shader_generator = 0;
|
||||
}
|
||||
|
||||
GeomMunger::unregister_mungers_for_gsg(this);
|
||||
}
|
||||
|
||||
|
@ -49,10 +49,10 @@
|
||||
#include "shaderAttrib.h"
|
||||
#include "texGenAttrib.h"
|
||||
#include "textureAttrib.h"
|
||||
#include "shaderGenerator.h"
|
||||
|
||||
class DrawableRegion;
|
||||
class GraphicsEngine;
|
||||
class ShaderGenerator;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GraphicsStateGuardian
|
||||
@ -104,6 +104,9 @@ PUBLISHED:
|
||||
INLINE void set_loader(Loader *loader);
|
||||
INLINE Loader *get_loader() const;
|
||||
|
||||
INLINE void set_shader_generator(ShaderGenerator *shader_generator);
|
||||
INLINE ShaderGenerator *get_shader_generator() const;
|
||||
|
||||
INLINE GraphicsPipe *get_pipe() const;
|
||||
GraphicsEngine *get_engine() const;
|
||||
INLINE const GraphicsThreadingModel &get_threading_model() const;
|
||||
@ -546,7 +549,7 @@ protected:
|
||||
PN_stdfloat _gamma;
|
||||
Texture::QualityLevel _texture_quality_override;
|
||||
|
||||
ShaderGenerator* _shader_generator;
|
||||
PT(ShaderGenerator) _shader_generator;
|
||||
|
||||
#ifndef NDEBUG
|
||||
PT(Texture) _flash_texture;
|
||||
|
@ -43,15 +43,18 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
|
||||
|
||||
_munge_color = false;
|
||||
_munge_color_scale = false;
|
||||
_auto_shader = false;
|
||||
|
||||
if (!get_gsg()->get_runtime_color_scale()) {
|
||||
// We might need to munge the colors.
|
||||
CPT(ColorAttrib) color_attrib = DCAST(ColorAttrib, state->get_attrib(ColorAttrib::get_class_slot()));
|
||||
CPT(ColorScaleAttrib) color_scale_attrib = DCAST(ColorScaleAttrib, state->get_attrib(ColorScaleAttrib::get_class_slot()));
|
||||
const ColorAttrib *color_attrib = (const ColorAttrib *)
|
||||
state->get_attrib(ColorAttrib::get_class_slot());
|
||||
const ColorScaleAttrib *color_scale_attrib = (const ColorScaleAttrib *)
|
||||
state->get_attrib(ColorScaleAttrib::get_class_slot());
|
||||
|
||||
if (color_attrib != (ColorAttrib *)NULL &&
|
||||
color_attrib->get_color_type() == ColorAttrib::T_flat) {
|
||||
|
||||
|
||||
if (!get_gsg()->get_color_scale_via_lighting()) {
|
||||
// We only need to munge the color directly if the GSG says it
|
||||
// can't cheat the color via lighting (presumably, in this case,
|
||||
@ -72,15 +75,16 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
|
||||
color_scale_attrib->has_scale()) {
|
||||
_color_scale = color_scale_attrib->get_scale();
|
||||
|
||||
CPT(TextureAttrib) tex_attrib = DCAST(TextureAttrib, state->get_attrib(TextureAttrib::get_class_slot()));
|
||||
|
||||
const TextureAttrib *tex_attrib = (const TextureAttrib *)
|
||||
state->get_attrib(TextureAttrib::get_class_slot());
|
||||
|
||||
// If the GSG says it can't cheat this RGB or alpha scale, we have
|
||||
// to apply the color scale directly.
|
||||
if ((color_scale_attrib->has_rgb_scale() && !get_gsg()->get_color_scale_via_lighting()) ||
|
||||
(color_scale_attrib->has_alpha_scale() && !get_gsg()->get_alpha_scale_via_texture(tex_attrib))) {
|
||||
_munge_color_scale = true;
|
||||
}
|
||||
|
||||
|
||||
// Known bug: if there is a material on an object that would
|
||||
// obscure the effect of color_scale, we scale the lighting
|
||||
// anyway, thus applying the effect even if it should be obscured.
|
||||
@ -88,6 +92,12 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
|
||||
// situation and handle it correctly.
|
||||
}
|
||||
}
|
||||
|
||||
const ShaderAttrib *shader_attrib = (const ShaderAttrib *)
|
||||
state->get_attrib_def(ShaderAttrib::get_class_slot());
|
||||
if (shader_attrib->auto_shader()) {
|
||||
_auto_shader = true;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -297,6 +307,10 @@ compare_to_impl(const GeomMunger *other) const {
|
||||
}
|
||||
}
|
||||
|
||||
if (_auto_shader != om->_auto_shader) {
|
||||
return (int)_auto_shader - (int)om->_auto_shader;
|
||||
}
|
||||
|
||||
return StateMunger::compare_to_impl(other);
|
||||
}
|
||||
|
||||
@ -351,5 +365,20 @@ munge_state_impl(const RenderState *state) {
|
||||
munged_state = munged_state->remove_attrib(ColorScaleAttrib::get_class_slot());
|
||||
}
|
||||
|
||||
if (_auto_shader) {
|
||||
CPT(RenderState) shader_state = munged_state->get_auto_shader_state();
|
||||
ShaderGenerator *shader_generator = get_gsg()->get_shader_generator();
|
||||
if (shader_generator == NULL) {
|
||||
pgraph_cat.error()
|
||||
<< "auto_shader enabled, but GSG has no shader generator assigned!\n";
|
||||
return munged_state;
|
||||
}
|
||||
if (shader_state->_generated_shader == NULL) {
|
||||
// Cache the generated ShaderAttrib on the shader state.
|
||||
shader_state->_generated_shader = shader_generator->synthesize_shader(shader_state);
|
||||
}
|
||||
munged_state = munged_state->set_attrib(shader_state->_generated_shader);
|
||||
}
|
||||
|
||||
return munged_state;
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ private:
|
||||
|
||||
bool _munge_color;
|
||||
bool _munge_color_scale;
|
||||
bool _auto_shader;
|
||||
|
||||
LColor _color;
|
||||
LVecBase4 _color_scale;
|
||||
|
@ -3194,16 +3194,6 @@ set_state_and_transform(const RenderState *target,
|
||||
_target_rs = target;
|
||||
|
||||
_target_shader = DCAST(ShaderAttrib, _target_rs->get_attrib_def(ShaderAttrib::get_class_slot()));
|
||||
if (_target_shader->auto_shader()) {
|
||||
// If we don't have a generated shader, make sure we have a ShaderGenerator, then generate the shader.
|
||||
if (_target_rs->_generated_shader == NULL) {
|
||||
if (_shader_generator == NULL) {
|
||||
_shader_generator = new ShaderGenerator(this, _scene_setup->get_display_region()->get_window());
|
||||
}
|
||||
const_cast<RenderState*>(_target_rs.p())->_generated_shader = DCAST(ShaderAttrib, _shader_generator->synthesize_shader(_target_rs));
|
||||
}
|
||||
_target_shader = DCAST(ShaderAttrib, _target_rs->_generated_shader);
|
||||
}
|
||||
|
||||
int alpha_test_slot = AlphaTestAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(alpha_test_slot) != _state_rs->get_attrib(alpha_test_slot) ||
|
||||
|
@ -215,7 +215,7 @@ public:
|
||||
// ShaderAttrib will be synthesized by the runtime and stored here.
|
||||
// I can't declare this as a ShaderAttrib because that would create
|
||||
// a circular include-file dependency problem. Aaargh.
|
||||
CPT(RenderAttrib) _generated_shader;
|
||||
mutable CPT(RenderAttrib) _generated_shader;
|
||||
|
||||
private:
|
||||
// This mutex protects _states. It also protects any modification
|
||||
|
@ -53,8 +53,8 @@ TypeHandle ShaderGenerator::_type_handle;
|
||||
// which the shader generator belongs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ShaderGenerator::
|
||||
ShaderGenerator(PT(GraphicsStateGuardianBase) gsg, PT(GraphicsOutputBase) host) :
|
||||
_gsg (gsg), _host (host) {
|
||||
ShaderGenerator(GraphicsStateGuardianBase *gsg, GraphicsOutputBase *host) :
|
||||
_gsg(gsg), _host(host) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -566,7 +566,7 @@ update_shadow_buffer(NodePath light_np) {
|
||||
}
|
||||
|
||||
// See if we already have a buffer. If not, create one.
|
||||
PT(Texture) tex;
|
||||
Texture *tex;
|
||||
if (light->_sbuffers.count(_gsg) == 0) {
|
||||
// Nope, the light doesn't have a buffer for our GSG. Make one.
|
||||
tex = _gsg->make_shadow_buffer(light_np, _host);
|
||||
@ -612,7 +612,7 @@ update_shadow_buffer(NodePath light_np) {
|
||||
// - omit attenuation calculations if attenuation off
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ShaderGenerator::
|
||||
CPT(ShaderAttrib) ShaderGenerator::
|
||||
synthesize_shader(const RenderState *rs) {
|
||||
analyze_renderstate(rs);
|
||||
reset_register_allocator();
|
||||
@ -1462,7 +1462,7 @@ synthesize_shader(const RenderState *rs) {
|
||||
}
|
||||
clear_analysis();
|
||||
reset_register_allocator();
|
||||
return shattr;
|
||||
return DCAST(ShaderAttrib, shattr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -1636,4 +1636,3 @@ texture_type_as_string(Texture::TextureType ttype) {
|
||||
return "2D";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,12 +63,11 @@ class LightAttrib;
|
||||
// Thanks to them!
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
class EXPCL_PANDA_PGRAPHNODES ShaderGenerator : public TypedObject {
|
||||
class EXPCL_PANDA_PGRAPHNODES ShaderGenerator : public TypedReferenceCount {
|
||||
PUBLISHED:
|
||||
ShaderGenerator(PT(GraphicsStateGuardianBase) gsg, PT(GraphicsOutputBase) host);
|
||||
ShaderGenerator(GraphicsStateGuardianBase *gsg, GraphicsOutputBase *host);
|
||||
virtual ~ShaderGenerator();
|
||||
virtual CPT(RenderAttrib) synthesize_shader(const RenderState *rs);
|
||||
virtual CPT(ShaderAttrib) synthesize_shader(const RenderState *rs);
|
||||
|
||||
protected:
|
||||
CPT(RenderAttrib) create_shader_attrib(const string &txt);
|
||||
@ -152,9 +151,9 @@ protected:
|
||||
void analyze_renderstate(const RenderState *rs);
|
||||
void clear_analysis();
|
||||
|
||||
PT(GraphicsStateGuardianBase) _gsg;
|
||||
PT(GraphicsOutputBase) _host;
|
||||
pmap<WCPT(RenderState), CPT(ShaderAttrib)> _generated_shaders;
|
||||
// This is not a PT() to prevent a circular reference.
|
||||
GraphicsStateGuardianBase *_gsg;
|
||||
GraphicsOutputBase *_host;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
@ -177,4 +176,3 @@ public:
|
||||
#include "shaderGenerator.I"
|
||||
|
||||
#endif // SHADERGENERATOR_H
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user