Panda3D
lightLensNode.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file lightLensNode.cxx
10  * @author drose
11  * @date 2002-03-26
12  */
13 
14 #include "lightLensNode.h"
15 #include "bamWriter.h"
16 #include "bamReader.h"
17 #include "datagram.h"
18 #include "datagramIterator.h"
19 #include "renderState.h"
20 #include "cullFaceAttrib.h"
21 #include "colorWriteAttrib.h"
23 
24 TypeHandle LightLensNode::_type_handle;
25 
26 /**
27  *
28  */
29 LightLensNode::
30 LightLensNode(const std::string &name, Lens *lens) :
31  Camera(name, lens),
32  _has_specular_color(false),
33  _attrib_count(0),
34  _used_by_auto_shader(false)
35 {
36  set_active(false);
37  _shadow_caster = false;
38  _sb_size.set(512, 512);
39  _sb_sort = -10;
40  // set_initial_state(RenderState::make(ShaderAttrib::make_off(), 1000));
41  // Backface culling helps eliminating artifacts.
42  set_initial_state(RenderState::make(CullFaceAttrib::make_reverse(),
43  ColorWriteAttrib::make(ColorWriteAttrib::C_off)));
44 }
45 
46 /**
47  *
48  */
49 LightLensNode::
50 ~LightLensNode() {
51  set_active(false);
52  clear_shadow_buffers();
53 
54  // If this triggers, the number of attrib_ref() didn't match the number of
55  // attrib_unref() calls, probably indicating a bug in LightAttrib.
56  nassertv(AtomicAdjust::get(_attrib_count) == 0);
57 }
58 
59 /**
60  *
61  */
62 LightLensNode::
63 LightLensNode(const LightLensNode &copy) :
64  Light(copy),
65  Camera(copy),
66  _shadow_caster(copy._shadow_caster),
67  _sb_size(copy._sb_size),
68  _sb_sort(-10),
69  _has_specular_color(copy._has_specular_color),
70  _attrib_count(0),
71  _used_by_auto_shader(false)
72 {
73  if (_shadow_caster) {
74  setup_shadow_map();
75  }
76 }
77 
78 /**
79  * Sets the flag indicating whether this light should cast shadows or not.
80  * This is the variant without buffer size, meaning that the current buffer
81  * size will be kept (512x512 is the default). Note that enabling shadows will
82  * require the shader generator to be enabled on the scene.
83  */
85 set_shadow_caster(bool caster) {
86  if (_shadow_caster && !caster) {
87  clear_shadow_buffers();
88  }
89  if (_shadow_caster != caster && _used_by_auto_shader) {
90  // Make sure any shaders using this light are regenerated.
91  GraphicsStateGuardianBase::mark_rehash_generated_shaders();
92  }
93  _shadow_caster = caster;
94  set_active(caster);
95  if (caster) {
96  setup_shadow_map();
97  }
98 }
99 
100 /**
101  * Sets the flag indicating whether this light should cast shadows or not.
102  * The xsize and ysize parameters specify the size of the shadow buffer that
103  * will be set up, the sort parameter specifies the sort. Note that enabling
104  * shadows will require the shader generator to be enabled on the scene.
105  */
107 set_shadow_caster(bool caster, int buffer_xsize, int buffer_ysize, int buffer_sort) {
108  if ((_shadow_caster && !caster) || buffer_xsize != _sb_size[0] || buffer_ysize != _sb_size[1]) {
109  clear_shadow_buffers();
110  }
111  if (_shadow_caster != caster && _used_by_auto_shader) {
112  // Make sure any shaders using this light are regenerated.
113  GraphicsStateGuardianBase::mark_rehash_generated_shaders();
114  }
115  _shadow_caster = caster;
116  _sb_size.set(buffer_xsize, buffer_ysize);
117 
118  if (buffer_sort != _sb_sort) {
119  ShadowBuffers::iterator it;
120  for(it = _sbuffers.begin(); it != _sbuffers.end(); ++it) {
121  (*it).second->set_sort(buffer_sort);
122  }
123  _sb_sort = buffer_sort;
124  }
125  set_active(caster);
126  if (caster) {
127  setup_shadow_map();
128  }
129 }
130 
131 /**
132  * Clears the shadow buffers, meaning they will be automatically recreated
133  * when the Shader Generator needs them.
134  */
135 void LightLensNode::
136 clear_shadow_buffers() {
137  if (_shadow_map) {
138  // Clear it to all ones, so that any shaders that might still be using
139  // it will see the shadows being disabled.
140  _shadow_map->clear_image();
141  }
142 
143  ShadowBuffers::iterator it;
144  for(it = _sbuffers.begin(); it != _sbuffers.end(); ++it) {
145  (*it).first->remove_window((*it).second);
146  }
147  _sbuffers.clear();
148 }
149 
150 /**
151  * Creates the shadow map texture. Can be overridden.
152  */
153 void LightLensNode::
154 setup_shadow_map() {
155  if (_shadow_map != nullptr &&
156  _shadow_map->get_x_size() == _sb_size[0] &&
157  _shadow_map->get_y_size() == _sb_size[1]) {
158  // Nothing to do.
159  return;
160  }
161 
162  if (_shadow_map == nullptr) {
163  _shadow_map = new Texture(get_name());
164  }
165 
166  _shadow_map->setup_2d_texture(_sb_size[0], _sb_size[1], Texture::T_unsigned_byte, Texture::F_depth_component);
167  _shadow_map->set_clear_color(LColor(1));
168  _shadow_map->set_wrap_u(SamplerState::WM_border_color);
169  _shadow_map->set_wrap_v(SamplerState::WM_border_color);
170  _shadow_map->set_border_color(LColor(1));
171  _shadow_map->set_minfilter(SamplerState::FT_shadow);
172  _shadow_map->set_magfilter(SamplerState::FT_shadow);
173 }
174 
175 /**
176  * This is called when the light is added to a LightAttrib.
177  */
179 attrib_ref() {
180  AtomicAdjust::inc(_attrib_count);
181 }
182 
183 /**
184  * This is called when the light is removed from a LightAttrib.
185  */
187 attrib_unref() {
188  // When it is removed from the last LightAttrib, destroy the shadow buffers.
189  // This is necessary to break the circular reference that the buffer holds
190  // on this node, via the display region's camera.
191  if (!AtomicAdjust::dec(_attrib_count)) {
192  clear_shadow_buffers();
193  }
194 }
195 
196 /**
197  * Returns the Light object upcast to a PandaNode.
198  */
200 as_node() {
201  return this;
202 }
203 
204 /**
205  * Cross-casts the node to a Light pointer, if it is one of the four kinds of
206  * Light nodes, or returns NULL if it is not.
207  */
209 as_light() {
210  return this;
211 }
212 
213 /**
214  *
215  */
216 void LightLensNode::
217 output(std::ostream &out) const {
218  LensNode::output(out);
219 }
220 
221 /**
222  *
223  */
224 void LightLensNode::
225 write(std::ostream &out, int indent_level) const {
226  LensNode::write(out, indent_level);
227 }
228 
229 /**
230  * Writes the contents of this object to the datagram for shipping out to a
231  * Bam file.
232  */
234 write_datagram(BamWriter *manager, Datagram &dg) {
235  Camera::write_datagram(manager, dg);
236  Light::write_datagram(manager, dg);
237 
238  dg.add_bool(_shadow_caster);
239  dg.add_int32(_sb_size[0]);
240  dg.add_int32(_sb_size[1]);
241  dg.add_int32(_sb_sort);
242 }
243 
244 /**
245  * This internal function is called by make_from_bam to read in all of the
246  * relevant data from the BamFile for the new LightLensNode.
247  */
248 void LightLensNode::
249 fillin(DatagramIterator &scan, BamReader *manager) {
250  Camera::fillin(scan, manager);
251  Light::fillin(scan, manager);
252 
253  bool shadow_caster = scan.get_bool();
254  int sb_xsize = scan.get_int32();
255  int sb_ysize = scan.get_int32();
256  int sb_sort = scan.get_int32();
257  set_shadow_caster(shadow_caster, sb_xsize, sb_ysize, sb_sort);
258 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static bool dec(Integer &var)
Atomically decrements the indicated variable and returns true if the new value is nonzero,...
static void inc(Integer &var)
Atomically increments the indicated variable.
static Integer get(const Integer &var)
Atomically retrieves the snapshot value of the indicated variable.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
A node that can be positioned around in the scene graph to represent a point of view for rendering a ...
Definition: camera.h:35
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
Definition: camera.cxx:271
set_active
Sets the active flag on the camera.
Definition: camera.h:50
A class to retrieve the individual data elements previously stored in a Datagram.
bool get_bool()
Extracts a boolean value.
int32_t get_int32()
Extracts a signed 32-bit integer.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
void add_int32(int32_t value)
Adds a signed 32-bit integer to the datagram.
Definition: datagram.I:67
void add_bool(bool value)
Adds a boolean value to the datagram.
Definition: datagram.I:34
A base class for any number of different kinds of lenses, linear and otherwise.
Definition: lens.h:41
A derivative of Light and of Camera.
Definition: lightLensNode.h:33
virtual void attrib_unref()
This is called when the light is removed from a LightAttrib.
virtual PandaNode * as_node()
Returns the Light object upcast to a PandaNode.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
virtual Light * as_light()
Cross-casts the node to a Light pointer, if it is one of the four kinds of Light nodes,...
virtual void attrib_ref()
This is called when the light is added to a LightAttrib.
void set_shadow_caster(bool caster)
Sets the flag indicating whether this light should cast shadows or not.
The abstract interface to all kinds of lights.
Definition: light.h:38
A basic node of the scene graph or data graph.
Definition: pandaNode.h:65
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition: texture.h:71
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.