mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
Fixes for this circular dependency mess
This commit is contained in:
parent
5a3dd8d0c3
commit
557abfae5e
@ -99,7 +99,7 @@ PUBLISHED:
|
|||||||
|
|
||||||
INLINE int count_textures() const;
|
INLINE int count_textures() const;
|
||||||
INLINE bool has_texture() const;
|
INLINE bool has_texture() const;
|
||||||
INLINE Texture *get_texture(int i=0) const;
|
virtual INLINE Texture *get_texture(int i=0) const;
|
||||||
INLINE RenderTexturePlane get_texture_plane(int i=0) const;
|
INLINE RenderTexturePlane get_texture_plane(int i=0) const;
|
||||||
INLINE RenderTextureMode get_rtm_mode(int i=0) const;
|
INLINE RenderTextureMode get_rtm_mode(int i=0) const;
|
||||||
void clear_render_textures();
|
void clear_render_textures();
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include "lightAttrib.h"
|
#include "lightAttrib.h"
|
||||||
#include "texGenAttrib.h"
|
#include "texGenAttrib.h"
|
||||||
#include "shaderGenerator.h"
|
#include "shaderGenerator.h"
|
||||||
|
#include "lightLensNode.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
@ -2541,3 +2542,61 @@ async_reload_texture(TextureContext *tc) {
|
|||||||
request->set_priority(priority);
|
request->set_priority(priority);
|
||||||
_loader->load_async(request);
|
_loader->load_async(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GraphicsStateGuardian::make_shadow_buffer
|
||||||
|
// Access: Protected
|
||||||
|
// Description: Creates a depth buffer for shadow mapping. This
|
||||||
|
// is a convenience function for the ShaderGenerator;
|
||||||
|
// putting this directly in the ShaderGenerator would
|
||||||
|
// cause circular dependency issues.
|
||||||
|
// Returns the depth texture.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PT(Texture) GraphicsStateGuardian::
|
||||||
|
make_shadow_buffer(const NodePath &light_np, GraphicsOutputBase *host) {
|
||||||
|
// Make sure everything is valid.
|
||||||
|
nassertr(light_np.node()->is_of_type(DirectionalLight::get_class_type()) ||
|
||||||
|
light_np.node()->is_of_type(Spotlight::get_class_type()), NULL);
|
||||||
|
PT(LightLensNode) light = DCAST(LightLensNode, light_np.node());
|
||||||
|
if (light == NULL || !light->_shadow_caster) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nassertr(light->_sbuffers.count(this) == 0, NULL);
|
||||||
|
|
||||||
|
display_cat.debug() << "Constructing shadow buffer for light '" << light->get_name()
|
||||||
|
<< "', size=" << light->_sb_xsize << "x" << light->_sb_ysize
|
||||||
|
<< ", sort=" << light->_sb_sort << "\n";
|
||||||
|
FrameBufferProperties fbp;
|
||||||
|
fbp.set_depth_bits(1); // We only need depth
|
||||||
|
PT(GraphicsOutput) sbuffer = get_engine()->make_output(get_pipe(), light->get_name(),
|
||||||
|
light->_sb_sort, fbp, WindowProperties::size(light->_sb_xsize, light->_sb_ysize),
|
||||||
|
GraphicsPipe::BF_refuse_window, this, DCAST(GraphicsOutput, host));
|
||||||
|
nassertr(sbuffer != NULL, NULL);
|
||||||
|
|
||||||
|
// Create a texture and fill it in with some data to workaround an OpenGL error
|
||||||
|
PT(Texture) tex = new Texture(light->get_name());
|
||||||
|
tex->setup_2d_texture(light->_sb_xsize, light->_sb_ysize, Texture::T_float, Texture::F_depth_stencil);
|
||||||
|
tex->make_ram_image();
|
||||||
|
sbuffer->add_render_texture(tex, GraphicsOutput::RTM_bind_or_copy,
|
||||||
|
GraphicsOutput::RTP_depth_stencil);
|
||||||
|
// Set the wrap mode to BORDER_COLOR
|
||||||
|
tex->set_wrap_u(Texture::WM_border_color);
|
||||||
|
tex->set_wrap_v(Texture::WM_border_color);
|
||||||
|
tex->set_border_color(LVecBase4f(1, 1, 1, 1));
|
||||||
|
|
||||||
|
if (get_supports_shadow_filter()) {
|
||||||
|
// If we have the ARB_shadow extension, enable shadow filtering.
|
||||||
|
tex->set_minfilter(Texture::FT_shadow);
|
||||||
|
tex->set_magfilter(Texture::FT_shadow);
|
||||||
|
} else {
|
||||||
|
// We only accept linear - this tells the GPU to use hardware PCF.
|
||||||
|
tex->set_minfilter(Texture::FT_linear);
|
||||||
|
tex->set_magfilter(Texture::FT_linear);
|
||||||
|
}
|
||||||
|
sbuffer->make_display_region(0, 1, 0, 1)->set_camera(light_np);
|
||||||
|
light->_sbuffers[this] = sbuffer;
|
||||||
|
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -302,6 +302,8 @@ public:
|
|||||||
|
|
||||||
static void create_gamma_table (float gamma, unsigned short *red_table, unsigned short *green_table, unsigned short *blue_table);
|
static void create_gamma_table (float gamma, unsigned short *red_table, unsigned short *green_table, unsigned short *blue_table);
|
||||||
|
|
||||||
|
virtual PT(Texture) make_shadow_buffer(const NodePath &light_np, GraphicsOutputBase *host);
|
||||||
|
|
||||||
#ifdef DO_PSTATS
|
#ifdef DO_PSTATS
|
||||||
static void init_frame_pstats();
|
static void init_frame_pstats();
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#include "pandabase.h"
|
#include "pandabase.h"
|
||||||
#include "typedWritableReferenceCount.h"
|
#include "typedWritableReferenceCount.h"
|
||||||
|
|
||||||
|
class Texture;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : GraphicsOutputBase
|
// Class : GraphicsOutputBase
|
||||||
// Description : An abstract base class for GraphicsOutput, for all
|
// Description : An abstract base class for GraphicsOutput, for all
|
||||||
@ -26,6 +28,7 @@
|
|||||||
class EXPCL_PANDA_GSGBASE GraphicsOutputBase : public TypedWritableReferenceCount {
|
class EXPCL_PANDA_GSGBASE GraphicsOutputBase : public TypedWritableReferenceCount {
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
virtual void set_sort(int sort)=0;
|
virtual void set_sort(int sort)=0;
|
||||||
|
virtual Texture *get_texture(int i=0) const=0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static TypeHandle get_class_type() {
|
static TypeHandle get_class_type() {
|
||||||
|
@ -87,6 +87,7 @@ class PointLight;
|
|||||||
class DirectionalLight;
|
class DirectionalLight;
|
||||||
class Spotlight;
|
class Spotlight;
|
||||||
class AmbientLight;
|
class AmbientLight;
|
||||||
|
class LightLensNode;
|
||||||
|
|
||||||
class DisplayRegion;
|
class DisplayRegion;
|
||||||
class Lens;
|
class Lens;
|
||||||
@ -219,6 +220,10 @@ public:
|
|||||||
virtual void bind_light(Spotlight *light_obj, const NodePath &light,
|
virtual void bind_light(Spotlight *light_obj, const NodePath &light,
|
||||||
int light_id) { }
|
int light_id) { }
|
||||||
|
|
||||||
|
// This function creates a shadow mapping buffer. This is not put in ShaderGenerator
|
||||||
|
// because that would cause circular dependencies.
|
||||||
|
virtual PT(Texture) make_shadow_buffer(const NodePath &light_np, GraphicsOutputBase *host)=0;
|
||||||
|
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
static GraphicsStateGuardianBase *get_default_gsg();
|
static GraphicsStateGuardianBase *get_default_gsg();
|
||||||
static void set_default_gsg(GraphicsStateGuardianBase *default_gsg);
|
static void set_default_gsg(GraphicsStateGuardianBase *default_gsg);
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "graphicsOutputBase.h"
|
#include "graphicsOutputBase.h"
|
||||||
|
|
||||||
class ShaderGenerator;
|
class ShaderGenerator;
|
||||||
|
class GraphicsStateGuardian;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : LightLensNode
|
// Class : LightLensNode
|
||||||
@ -88,6 +89,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
static TypeHandle _type_handle;
|
static TypeHandle _type_handle;
|
||||||
|
|
||||||
|
friend class GraphicsStateGuardian;
|
||||||
friend class ShaderGenerator;
|
friend class ShaderGenerator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -477,51 +477,15 @@ 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(GraphicsOutput) sbuffer;
|
|
||||||
PT(Texture) tex;
|
PT(Texture) tex;
|
||||||
if (light->_sbuffers.count(DCAST(GraphicsStateGuardianBase, _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.
|
tex = _gsg->make_shadow_buffer(light_np, _host);
|
||||||
FrameBufferProperties fbp;
|
|
||||||
fbp.set_depth_bits(1); // We only need depth
|
|
||||||
pgraph_cat.debug() << "Constructing shadow buffer for light '" << light->get_name()
|
|
||||||
<< "', size=" << light->_sb_xsize << "x" << light->_sb_ysize
|
|
||||||
<< ", sort=" << light->_sb_sort << "\n";
|
|
||||||
sbuffer = _gsg->get_engine()->make_output(_gsg->get_pipe(), light->get_name(),
|
|
||||||
light->_sb_sort, fbp, WindowProperties::size(light->_sb_xsize, light->_sb_ysize),
|
|
||||||
GraphicsPipe::BF_refuse_window, _gsg, _host);
|
|
||||||
nassertr(sbuffer != NULL, NULL);
|
|
||||||
|
|
||||||
// Create a texture and fill it in with some data to workaround an OpenGL error
|
|
||||||
tex = new Texture(light->get_name());
|
|
||||||
tex->setup_2d_texture(light->_sb_xsize, light->_sb_ysize, Texture::T_float, Texture::F_depth_stencil);
|
|
||||||
tex->make_ram_image();
|
|
||||||
sbuffer->add_render_texture(tex, GraphicsOutput::RTM_bind_or_copy,
|
|
||||||
DrawableRegion::RTP_depth_stencil);
|
|
||||||
// Set the wrap mode to BORDER_COLOR
|
|
||||||
tex->set_wrap_u(Texture::WM_border_color);
|
|
||||||
tex->set_wrap_v(Texture::WM_border_color);
|
|
||||||
tex->set_border_color(LVecBase4f(1, 1, 1, 1));
|
|
||||||
|
|
||||||
if (_use_shadow_filter) {
|
|
||||||
// If we have the ARB_shadow extension, enable shadow filtering.
|
|
||||||
tex->set_minfilter(Texture::FT_shadow);
|
|
||||||
tex->set_magfilter(Texture::FT_shadow);
|
|
||||||
} else {
|
} else {
|
||||||
// We only accept linear - this tells the GPU to use hardware PCF.
|
|
||||||
tex->set_minfilter(Texture::FT_linear);
|
|
||||||
tex->set_magfilter(Texture::FT_linear);
|
|
||||||
}
|
|
||||||
sbuffer->make_display_region(0, 1, 0, 1)->set_camera(light_np);
|
|
||||||
light->_sbuffers[DCAST(GraphicsStateGuardianBase, _gsg)] = DCAST(GraphicsOutputBase, sbuffer);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// There's already a buffer - use that.
|
// There's already a buffer - use that.
|
||||||
sbuffer = DCAST(GraphicsOutput, light->_sbuffers[DCAST(GraphicsStateGuardianBase, _gsg)]);
|
tex = light->_sbuffers[_gsg]->get_texture();
|
||||||
tex = sbuffer->get_texture();
|
|
||||||
nassertr(tex != NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
nassertr(tex != NULL, NULL);
|
||||||
|
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user