Changes to light inheritance to allow shadows

This commit is contained in:
rdb 2009-05-27 17:33:21 +00:00
parent 82c1bec8fd
commit 801ddc8bb8
7 changed files with 170 additions and 24 deletions

View File

@ -25,8 +25,8 @@ TypeHandle Camera::_type_handle;
// Description:
////////////////////////////////////////////////////////////////////
Camera::
Camera(const string &name) :
LensNode(name),
Camera(const string &name, Lens *lens) :
LensNode(name, lens),
_active(true),
_camera_mask(~PandaNode::get_overall_bit()),
_initial_state(RenderState::make_empty())

View File

@ -18,6 +18,7 @@
#include "pandabase.h"
#include "lensNode.h"
#include "perspectiveLens.h"
#include "nodePath.h"
#include "weakNodePath.h"
#include "drawMask.h"
@ -35,7 +36,7 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_PGRAPH Camera : public LensNode {
PUBLISHED:
Camera(const string &name);
Camera(const string &name, Lens *lens = new PerspectiveLens());
Camera(const Camera &copy);
public:

View File

@ -13,6 +13,7 @@
////////////////////////////////////////////////////////////////////
#include "directionalLight.h"
#include "orthographicLens.h"
#include "graphicsStateGuardianBase.h"
#include "bamWriter.h"
#include "bamReader.h"
@ -65,7 +66,7 @@ fillin(DatagramIterator &scan, BamReader *) {
////////////////////////////////////////////////////////////////////
DirectionalLight::
DirectionalLight(const string &name) :
LightNode(name)
LightLensNode(name, new OrthographicLens())
{
}
@ -78,7 +79,7 @@ DirectionalLight(const string &name) :
////////////////////////////////////////////////////////////////////
DirectionalLight::
DirectionalLight(const DirectionalLight &copy) :
LightNode(copy),
LightLensNode(copy),
_cycler(copy._cycler)
{
}
@ -106,7 +107,7 @@ make_copy() const {
////////////////////////////////////////////////////////////////////
void DirectionalLight::
xform(const LMatrix4f &mat) {
LightNode::xform(mat);
LightLensNode::xform(mat);
CDWriter cdata(_cycler);
cdata->_point = cdata->_point * mat;
cdata->_direction = cdata->_direction * mat;
@ -199,7 +200,7 @@ register_with_read_factory() {
////////////////////////////////////////////////////////////////////
void DirectionalLight::
write_datagram(BamWriter *manager, Datagram &dg) {
LightNode::write_datagram(manager, dg);
LightLensNode::write_datagram(manager, dg);
manager->write_cdata(dg, _cycler);
}
@ -232,6 +233,6 @@ make_from_bam(const FactoryParams &params) {
////////////////////////////////////////////////////////////////////
void DirectionalLight::
fillin(DatagramIterator &scan, BamReader *manager) {
LightNode::fillin(scan, manager);
LightLensNode::fillin(scan, manager);
manager->read_cdata(scan, _cycler);
}

View File

@ -17,14 +17,14 @@
#include "pandabase.h"
#include "lightNode.h"
#include "lightLensNode.h"
////////////////////////////////////////////////////////////////////
// Class : DirectionalLight
// Description : A light shining from infinitely far away in a
// particular direction, like sunlight.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_PGRAPHNODES DirectionalLight : public LightNode {
class EXPCL_PANDA_PGRAPHNODES DirectionalLight : public LightLensNode {
PUBLISHED:
DirectionalLight(const string &name);
@ -91,9 +91,9 @@ public:
return _type_handle;
}
static void init_type() {
LightNode::init_type();
LightLensNode::init_type();
register_type(_type_handle, "DirectionalLight",
LightNode::get_class_type());
LightLensNode::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();

View File

@ -11,3 +11,73 @@
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: LightLensNode::is_shadow_caster
// Access: Published
// Description: Returns whether this light is configured to cast
// shadows or not.
////////////////////////////////////////////////////////////////////
INLINE bool LightLensNode::
is_shadow_caster() {
return _shadow_caster;
}
////////////////////////////////////////////////////////////////////
// Function: LightLensNode::set_shadow_caster
// Access: Published
// Description: Sets the flag indicating whether this light should
// cast shadows or not. This is the variant without
// buffer size, meaning that the current buffer size
// will be kept (512x512 is the default).
// Note that enabling shadows will require the shader
// generator to be enabled on the scene.
////////////////////////////////////////////////////////////////////
INLINE void LightLensNode::
set_shadow_caster(bool caster) {
if (_shadow_caster && !caster) {
clear_shadow_buffers();
}
_shadow_caster = caster;
set_active(caster);
}
////////////////////////////////////////////////////////////////////
// Function: LightLensNode::set_shadow_caster
// Access: Published
// Description: Sets the flag indicating whether this light should
// cast shadows or not. The xsize and ysize parameters
// specify the size of the shadow buffer that will be
// set up, the sort parameter specifies the sort.
// Note that enabling shadows will require the shader
// generator to be enabled on the scene.
////////////////////////////////////////////////////////////////////
INLINE void LightLensNode::
set_shadow_caster(bool caster, int buffer_xsize, int buffer_ysize, int buffer_sort) {
if ((_shadow_caster && !caster) || buffer_xsize != _sb_xsize || buffer_ysize != _sb_ysize) {
clear_shadow_buffers();
}
_shadow_caster = caster;
_sb_xsize = buffer_xsize;
_sb_ysize = buffer_ysize;
if (buffer_sort != _sb_sort) {
ShadowBuffers::iterator it;
for(it = _sbuffers.begin(); it != _sbuffers.end(); ++it) {
it->second->set_sort(buffer_sort);
}
_sb_sort = buffer_sort;
}
set_active(caster);
}
////////////////////////////////////////////////////////////////////
// Function: LightLensNode::set_push_bias
// Access: Published
// Description: Sets the push bias value, this is used to eliminate
// depth texture precision errors in shadows. Change
// this value if your shadows look strange.
////////////////////////////////////////////////////////////////////
INLINE void LightLensNode::
set_push_bias(float push_bias) {
_push_bias = push_bias;
}

View File

@ -17,6 +17,7 @@
#include "bamReader.h"
#include "datagram.h"
#include "datagramIterator.h"
#include "graphicsEngine.h"
TypeHandle LightLensNode::_type_handle;
@ -26,9 +27,26 @@ TypeHandle LightLensNode::_type_handle;
// Description:
////////////////////////////////////////////////////////////////////
LightLensNode::
LightLensNode(const string &name) :
LensNode(name)
LightLensNode(const string &name, Lens *lens) :
Camera(name, lens)
{
set_active(false);
_shadow_caster = false;
_sb_xsize = 512;
_sb_ysize = 512;
_sb_sort = -10;
_push_bias = 0.5;
}
////////////////////////////////////////////////////////////////////
// Function: LightLensNode::Destructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
LightLensNode::
~LightLensNode() {
set_active(false);
clear_shadow_buffers();
}
////////////////////////////////////////////////////////////////////
@ -37,10 +55,31 @@ LightLensNode(const string &name) :
// Description:
////////////////////////////////////////////////////////////////////
LightLensNode::
LightLensNode(const LightLensNode &copy) :
LightLensNode(const LightLensNode &copy) :
Light(copy),
LensNode(copy)
Camera(copy)
{
_shadow_caster = false;
_sb_xsize = 512;
_sb_ysize = 512;
_sb_sort = -10;
_push_bias = 0.5;
}
////////////////////////////////////////////////////////////////////
// Function: LightLensNode::clear_shadow_buffers
// Access: Protected
// Description: Clears the shadow buffers, meaning they will be
// automatically recreated when the Shader Generator
// needs them.
////////////////////////////////////////////////////////////////////
void LightLensNode::
clear_shadow_buffers() {
ShadowBuffers::iterator it;
for(it = _sbuffers.begin(); it != _sbuffers.end(); ++it) {
it->first->get_engine()->remove_window(it->second);
}
_sbuffers.clear();
}
////////////////////////////////////////////////////////////////////
@ -93,8 +132,14 @@ write(ostream &out, int indent_level) const {
////////////////////////////////////////////////////////////////////
void LightLensNode::
write_datagram(BamWriter *manager, Datagram &dg) {
LensNode::write_datagram(manager, dg);
Camera::write_datagram(manager, dg);
Light::write_datagram(manager, dg);
dg.add_bool(_shadow_caster);
dg.add_int32(_sb_xsize);
dg.add_int32(_sb_ysize);
dg.add_int32(_sb_sort);
dg.add_float64(_push_bias);
}
////////////////////////////////////////////////////////////////////
@ -106,6 +151,13 @@ write_datagram(BamWriter *manager, Datagram &dg) {
////////////////////////////////////////////////////////////////////
void LightLensNode::
fillin(DatagramIterator &scan, BamReader *manager) {
LensNode::fillin(scan, manager);
Camera::fillin(scan, manager);
Light::fillin(scan, manager);
bool shadow_caster = scan.get_bool();
int sb_xsize = scan.get_int32();
int sb_ysize = scan.get_int32();
int sb_sort = scan.get_int32();
set_shadow_caster(shadow_caster, sb_xsize, sb_ysize, sb_sort);
set_push_bias(scan.get_float64());
}

View File

@ -18,18 +18,38 @@
#include "pandabase.h"
#include "light.h"
#include "lensNode.h"
#include "camera.h"
#include "graphicsStateGuardian.h"
#include "graphicsOutput.h"
class ShaderGenerator;
////////////////////////////////////////////////////////////////////
// Class : LightLensNode
// Description : A derivative of Light and of LensNode.
// Description : A derivative of Light and of Camera. The name might
// be misleading: it does not directly derive from
// LensNode, but through the Camera class. The Camera
// serves no purpose unless shadows are enabled.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_PGRAPHNODES LightLensNode : public Light, public LensNode {
class EXPCL_PANDA_PGRAPHNODES LightLensNode : public Light, public Camera {
PUBLISHED:
LightLensNode(const string &name);
LightLensNode(const string &name, Lens *lens = new PerspectiveLens());
virtual ~LightLensNode();
INLINE bool is_shadow_caster();
INLINE void set_shadow_caster(bool caster);
INLINE void set_shadow_caster(bool caster, int buffer_xsize, int buffer_ysize, int sort = -10);
INLINE void set_push_bias(float push_bias);
protected:
LightLensNode(const LightLensNode &copy);
void clear_shadow_buffers();
bool _shadow_caster;
int _sb_xsize, _sb_ysize, _sb_sort;
double _push_bias;
typedef pmap<CPT(GraphicsStateGuardian), PT(GraphicsOutput) > ShadowBuffers;
ShadowBuffers _sbuffers;
public:
virtual PandaNode *as_node();
@ -53,10 +73,10 @@ public:
}
static void init_type() {
Light::init_type();
LensNode::init_type();
Camera::init_type();
register_type(_type_handle, "LightLensNode",
Light::get_class_type(),
LensNode::get_class_type());
Camera::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
@ -65,6 +85,8 @@ public:
private:
static TypeHandle _type_handle;
friend class ShaderGenerator;
};
INLINE ostream &operator << (ostream &out, const LightLensNode &light) {