mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -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) {
|
Thread *current_thread) {
|
||||||
PStatTimer timer(_cull_pcollector, current_thread);
|
PStatTimer timer(_cull_pcollector, current_thread);
|
||||||
|
|
||||||
Windows::const_iterator wi;
|
size_t wlist_size = wlist.size();
|
||||||
for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
|
for (size_t wi = 0; wi < wlist_size; ++wi) {
|
||||||
GraphicsOutput *win = (*wi);
|
GraphicsOutput *win = wlist[wi];
|
||||||
if (win->is_active() && win->get_gsg()->is_active()) {
|
if (win->is_active() && win->get_gsg()->is_active()) {
|
||||||
if (win->flip_ready()) {
|
if (win->flip_ready()) {
|
||||||
{
|
{
|
||||||
@ -1486,9 +1486,9 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
|||||||
typedef pmap<NodePath, DisplayRegion *> AlreadyCulled;
|
typedef pmap<NodePath, DisplayRegion *> AlreadyCulled;
|
||||||
AlreadyCulled already_culled;
|
AlreadyCulled already_culled;
|
||||||
|
|
||||||
Windows::const_iterator wi;
|
size_t wlist_size = wlist.size();
|
||||||
for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
|
for (size_t wi = 0; wi < wlist_size; ++wi) {
|
||||||
GraphicsOutput *win = (*wi);
|
GraphicsOutput *win = wlist[wi];
|
||||||
if (win->is_active() && win->get_gsg()->is_active()) {
|
if (win->is_active() && win->get_gsg()->is_active()) {
|
||||||
PStatTimer timer(win->get_cull_window_pcollector(), current_thread);
|
PStatTimer timer(win->get_cull_window_pcollector(), current_thread);
|
||||||
int num_display_regions = win->get_num_active_display_regions();
|
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);
|
CPT(TransformState) cs_world_transform = cs_transform->compose(world_transform);
|
||||||
scene_setup->set_cs_world_transform(cs_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;
|
return scene_setup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,6 +214,28 @@ get_loader() const {
|
|||||||
return _loader;
|
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
|
// Function: GraphicsStateGuardian::get_pipe
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -266,8 +266,6 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
|
|||||||
|
|
||||||
_gamma = 1.0f;
|
_gamma = 1.0f;
|
||||||
_texture_quality_override = Texture::QL_default;
|
_texture_quality_override = Texture::QL_default;
|
||||||
|
|
||||||
_shader_generator = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -278,12 +276,6 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
|
|||||||
GraphicsStateGuardian::
|
GraphicsStateGuardian::
|
||||||
~GraphicsStateGuardian() {
|
~GraphicsStateGuardian() {
|
||||||
remove_gsg(this);
|
remove_gsg(this);
|
||||||
|
|
||||||
if (_shader_generator) {
|
|
||||||
delete _shader_generator;
|
|
||||||
_shader_generator = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
GeomMunger::unregister_mungers_for_gsg(this);
|
GeomMunger::unregister_mungers_for_gsg(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,10 +49,10 @@
|
|||||||
#include "shaderAttrib.h"
|
#include "shaderAttrib.h"
|
||||||
#include "texGenAttrib.h"
|
#include "texGenAttrib.h"
|
||||||
#include "textureAttrib.h"
|
#include "textureAttrib.h"
|
||||||
|
#include "shaderGenerator.h"
|
||||||
|
|
||||||
class DrawableRegion;
|
class DrawableRegion;
|
||||||
class GraphicsEngine;
|
class GraphicsEngine;
|
||||||
class ShaderGenerator;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : GraphicsStateGuardian
|
// Class : GraphicsStateGuardian
|
||||||
@ -104,6 +104,9 @@ PUBLISHED:
|
|||||||
INLINE void set_loader(Loader *loader);
|
INLINE void set_loader(Loader *loader);
|
||||||
INLINE Loader *get_loader() const;
|
INLINE Loader *get_loader() const;
|
||||||
|
|
||||||
|
INLINE void set_shader_generator(ShaderGenerator *shader_generator);
|
||||||
|
INLINE ShaderGenerator *get_shader_generator() const;
|
||||||
|
|
||||||
INLINE GraphicsPipe *get_pipe() const;
|
INLINE GraphicsPipe *get_pipe() const;
|
||||||
GraphicsEngine *get_engine() const;
|
GraphicsEngine *get_engine() const;
|
||||||
INLINE const GraphicsThreadingModel &get_threading_model() const;
|
INLINE const GraphicsThreadingModel &get_threading_model() const;
|
||||||
@ -546,7 +549,7 @@ protected:
|
|||||||
PN_stdfloat _gamma;
|
PN_stdfloat _gamma;
|
||||||
Texture::QualityLevel _texture_quality_override;
|
Texture::QualityLevel _texture_quality_override;
|
||||||
|
|
||||||
ShaderGenerator* _shader_generator;
|
PT(ShaderGenerator) _shader_generator;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
PT(Texture) _flash_texture;
|
PT(Texture) _flash_texture;
|
||||||
|
@ -43,11 +43,14 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
|
|||||||
|
|
||||||
_munge_color = false;
|
_munge_color = false;
|
||||||
_munge_color_scale = false;
|
_munge_color_scale = false;
|
||||||
|
_auto_shader = false;
|
||||||
|
|
||||||
if (!get_gsg()->get_runtime_color_scale()) {
|
if (!get_gsg()->get_runtime_color_scale()) {
|
||||||
// We might need to munge the colors.
|
// We might need to munge the colors.
|
||||||
CPT(ColorAttrib) color_attrib = DCAST(ColorAttrib, state->get_attrib(ColorAttrib::get_class_slot()));
|
const ColorAttrib *color_attrib = (const ColorAttrib *)
|
||||||
CPT(ColorScaleAttrib) color_scale_attrib = DCAST(ColorScaleAttrib, state->get_attrib(ColorScaleAttrib::get_class_slot()));
|
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 &&
|
if (color_attrib != (ColorAttrib *)NULL &&
|
||||||
color_attrib->get_color_type() == ColorAttrib::T_flat) {
|
color_attrib->get_color_type() == ColorAttrib::T_flat) {
|
||||||
@ -72,7 +75,8 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
|
|||||||
color_scale_attrib->has_scale()) {
|
color_scale_attrib->has_scale()) {
|
||||||
_color_scale = color_scale_attrib->get_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
|
// If the GSG says it can't cheat this RGB or alpha scale, we have
|
||||||
// to apply the color scale directly.
|
// to apply the color scale directly.
|
||||||
@ -88,6 +92,12 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
|
|||||||
// situation and handle it correctly.
|
// 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);
|
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());
|
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;
|
return munged_state;
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,7 @@ private:
|
|||||||
|
|
||||||
bool _munge_color;
|
bool _munge_color;
|
||||||
bool _munge_color_scale;
|
bool _munge_color_scale;
|
||||||
|
bool _auto_shader;
|
||||||
|
|
||||||
LColor _color;
|
LColor _color;
|
||||||
LVecBase4 _color_scale;
|
LVecBase4 _color_scale;
|
||||||
|
@ -3194,16 +3194,6 @@ set_state_and_transform(const RenderState *target,
|
|||||||
_target_rs = target;
|
_target_rs = target;
|
||||||
|
|
||||||
_target_shader = DCAST(ShaderAttrib, _target_rs->get_attrib_def(ShaderAttrib::get_class_slot()));
|
_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();
|
int alpha_test_slot = AlphaTestAttrib::get_class_slot();
|
||||||
if (_target_rs->get_attrib(alpha_test_slot) != _state_rs->get_attrib(alpha_test_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.
|
// ShaderAttrib will be synthesized by the runtime and stored here.
|
||||||
// I can't declare this as a ShaderAttrib because that would create
|
// I can't declare this as a ShaderAttrib because that would create
|
||||||
// a circular include-file dependency problem. Aaargh.
|
// a circular include-file dependency problem. Aaargh.
|
||||||
CPT(RenderAttrib) _generated_shader;
|
mutable CPT(RenderAttrib) _generated_shader;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// This mutex protects _states. It also protects any modification
|
// This mutex protects _states. It also protects any modification
|
||||||
|
@ -53,7 +53,7 @@ TypeHandle ShaderGenerator::_type_handle;
|
|||||||
// which the shader generator belongs.
|
// which the shader generator belongs.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
ShaderGenerator::
|
ShaderGenerator::
|
||||||
ShaderGenerator(PT(GraphicsStateGuardianBase) gsg, PT(GraphicsOutputBase) host) :
|
ShaderGenerator(GraphicsStateGuardianBase *gsg, GraphicsOutputBase *host) :
|
||||||
_gsg(gsg), _host(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.
|
// See if we already have a buffer. If not, create one.
|
||||||
PT(Texture) tex;
|
Texture *tex;
|
||||||
if (light->_sbuffers.count(_gsg) == 0) {
|
if (light->_sbuffers.count(_gsg) == 0) {
|
||||||
// Nope, the light doesn't have a buffer for our GSG. Make one.
|
// Nope, the light doesn't have a buffer for our GSG. Make one.
|
||||||
tex = _gsg->make_shadow_buffer(light_np, _host);
|
tex = _gsg->make_shadow_buffer(light_np, _host);
|
||||||
@ -612,7 +612,7 @@ update_shadow_buffer(NodePath light_np) {
|
|||||||
// - omit attenuation calculations if attenuation off
|
// - omit attenuation calculations if attenuation off
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
CPT(RenderAttrib) ShaderGenerator::
|
CPT(ShaderAttrib) ShaderGenerator::
|
||||||
synthesize_shader(const RenderState *rs) {
|
synthesize_shader(const RenderState *rs) {
|
||||||
analyze_renderstate(rs);
|
analyze_renderstate(rs);
|
||||||
reset_register_allocator();
|
reset_register_allocator();
|
||||||
@ -1462,7 +1462,7 @@ synthesize_shader(const RenderState *rs) {
|
|||||||
}
|
}
|
||||||
clear_analysis();
|
clear_analysis();
|
||||||
reset_register_allocator();
|
reset_register_allocator();
|
||||||
return shattr;
|
return DCAST(ShaderAttrib, shattr);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1636,4 +1636,3 @@ texture_type_as_string(Texture::TextureType ttype) {
|
|||||||
return "2D";
|
return "2D";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,12 +63,11 @@ class LightAttrib;
|
|||||||
// Thanks to them!
|
// Thanks to them!
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA_PGRAPHNODES ShaderGenerator : public TypedReferenceCount {
|
||||||
class EXPCL_PANDA_PGRAPHNODES ShaderGenerator : public TypedObject {
|
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
ShaderGenerator(PT(GraphicsStateGuardianBase) gsg, PT(GraphicsOutputBase) host);
|
ShaderGenerator(GraphicsStateGuardianBase *gsg, GraphicsOutputBase *host);
|
||||||
virtual ~ShaderGenerator();
|
virtual ~ShaderGenerator();
|
||||||
virtual CPT(RenderAttrib) synthesize_shader(const RenderState *rs);
|
virtual CPT(ShaderAttrib) synthesize_shader(const RenderState *rs);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CPT(RenderAttrib) create_shader_attrib(const string &txt);
|
CPT(RenderAttrib) create_shader_attrib(const string &txt);
|
||||||
@ -152,9 +151,9 @@ protected:
|
|||||||
void analyze_renderstate(const RenderState *rs);
|
void analyze_renderstate(const RenderState *rs);
|
||||||
void clear_analysis();
|
void clear_analysis();
|
||||||
|
|
||||||
PT(GraphicsStateGuardianBase) _gsg;
|
// This is not a PT() to prevent a circular reference.
|
||||||
PT(GraphicsOutputBase) _host;
|
GraphicsStateGuardianBase *_gsg;
|
||||||
pmap<WCPT(RenderState), CPT(ShaderAttrib)> _generated_shaders;
|
GraphicsOutputBase *_host;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static TypeHandle get_class_type() {
|
static TypeHandle get_class_type() {
|
||||||
@ -177,4 +176,3 @@ public:
|
|||||||
#include "shaderGenerator.I"
|
#include "shaderGenerator.I"
|
||||||
|
|
||||||
#endif // SHADERGENERATOR_H
|
#endif // SHADERGENERATOR_H
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user