Panda3D
lightRampAttrib.cxx
1 // Filename: lightRampAttrib.cxx
2 // Created by: drose (04Mar02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "lightRampAttrib.h"
16 #include "graphicsStateGuardianBase.h"
17 #include "dcast.h"
18 #include "bamReader.h"
19 #include "bamWriter.h"
20 #include "datagram.h"
21 #include "datagramIterator.h"
22 
23 TypeHandle LightRampAttrib::_type_handle;
24 int LightRampAttrib::_attrib_slot;
25 CPT(RenderAttrib) LightRampAttrib::_default;
26 
27 ////////////////////////////////////////////////////////////////////
28 // Function: LightRampAttrib::make_default
29 // Access: Published, Static
30 // Description: Constructs a new LightRampAttrib object. This
31 // is the standard OpenGL lighting ramp, which clamps
32 // the final light total to the 0-1 range.
33 ////////////////////////////////////////////////////////////////////
34 CPT(RenderAttrib) LightRampAttrib::
35 make_default() {
36  if (_default == 0) {
37  LightRampAttrib *attrib = new LightRampAttrib();
38  _default = return_new(attrib);
39  }
40  return _default;
41 }
42 
43 ////////////////////////////////////////////////////////////////////
44 // Function: LightRampAttrib::make_identity
45 // Access: Published, Static
46 // Description: Constructs a new LightRampAttrib object. This
47 // differs from the usual OpenGL lighting model in that
48 // it does not clamp the final lighting total to (0,1).
49 ////////////////////////////////////////////////////////////////////
50 CPT(RenderAttrib) LightRampAttrib::
51 make_identity() {
52  LightRampAttrib *attrib = new LightRampAttrib();
53  attrib->_mode = LRT_identity;
54  return return_new(attrib);
55 }
56 
57 ////////////////////////////////////////////////////////////////////
58 // Function: LightRampAttrib::make_single_threshold
59 // Access: Published, Static
60 // Description: Constructs a new LightRampAttrib object. This
61 // causes the luminance of the diffuse lighting
62 // contribution to be quantized using a single threshold:
63 // @code
64 // if (original_luminance > threshold0) {
65 // luminance = level0;
66 // } else {
67 // luminance = 0.0;
68 // }
69 // @endcode
70 ////////////////////////////////////////////////////////////////////
71 CPT(RenderAttrib) LightRampAttrib::
72 make_single_threshold(PN_stdfloat thresh0, PN_stdfloat val0) {
73  LightRampAttrib *attrib = new LightRampAttrib();
74  attrib->_mode = LRT_single_threshold;
75  attrib->_threshold[0] = thresh0;
76  attrib->_level[0] = val0;
77  return return_new(attrib);
78 }
79 
80 ////////////////////////////////////////////////////////////////////
81 // Function: LightRampAttrib::make_double_threshold
82 // Access: Published, Static
83 // Description: Constructs a new LightRampAttrib object. This
84 // causes the luminance of the diffuse lighting
85 // contribution to be quantized using two thresholds:
86 // @code
87 // if (original_luminance > threshold1) {
88 // luminance = level1;
89 // } else if (original_luminance > threshold0) {
90 // luminance = level0;
91 // } else {
92 // luminance = 0.0;
93 // }
94 // @endcode
95 ////////////////////////////////////////////////////////////////////
96 CPT(RenderAttrib) LightRampAttrib::
97 make_double_threshold(PN_stdfloat thresh0, PN_stdfloat val0, PN_stdfloat thresh1, PN_stdfloat val1) {
98  LightRampAttrib *attrib = new LightRampAttrib();
99  attrib->_mode = LRT_double_threshold;
100  attrib->_threshold[0] = thresh0;
101  attrib->_level[0] = val0;
102  attrib->_threshold[1] = thresh1;
103  attrib->_level[1] = val1;
104  return return_new(attrib);
105 }
106 
107 ////////////////////////////////////////////////////////////////////
108 // Function: LightRampAttrib::make_hdr0
109 // Access: Published, Static
110 // Description: Constructs a new LightRampAttrib object. This causes
111 // an HDR tone mapping operation to be applied.
112 //
113 // Normally, brightness values greater than 1 cannot be
114 // distinguished from each other, causing very brightly lit
115 // objects to wash out white and all detail to be erased.
116 // HDR tone mapping remaps brightness values in the range
117 // 0-infinity into the range (0,1), making it possible to
118 // distinguish detail in scenes whose brightness exceeds 1.
119 //
120 // However, the monitor has finite contrast. Normally, all
121 // of that contrast is used to represent brightnesses in
122 // the range 0-1. The HDR0 tone mapping operator 'steals'
123 // one quarter of that contrast to represent brightnesses in
124 // the range 1-infinity.
125 // @code
126 // FINAL_RGB = (RGB^3 + RGB^2 + RGB) / (RGB^3 + RGB^2 + RGB + 1)
127 // @endcode
128 ////////////////////////////////////////////////////////////////////
129 CPT(RenderAttrib) LightRampAttrib::
130 make_hdr0() {
131  LightRampAttrib *attrib = new LightRampAttrib();
132  attrib->_mode = LRT_hdr0;
133  return return_new(attrib);
134 }
135 
136 ////////////////////////////////////////////////////////////////////
137 // Function: LightRampAttrib::make_hdr1
138 // Access: Published, Static
139 // Description: Constructs a new LightRampAttrib object. This causes
140 // an HDR tone mapping operation to be applied.
141 //
142 // Normally, brightness values greater than 1 cannot be
143 // distinguished from each other, causing very brightly lit
144 // objects to wash out white and all detail to be erased.
145 // HDR tone mapping remaps brightness values in the range
146 // 0-infinity into the range (0,1), making it possible to
147 // distinguish detail in scenes whose brightness exceeds 1.
148 //
149 // However, the monitor has finite contrast. Normally, all
150 // of that contrast is used to represent brightnesses in
151 // the range 0-1. The HDR1 tone mapping operator 'steals'
152 // one third of that contrast to represent brightnesses in
153 // the range 1-infinity.
154 // @code
155 // FINAL_RGB = (RGB^2 + RGB) / (RGB^2 + RGB + 1)
156 // @endcode
157 ////////////////////////////////////////////////////////////////////
158 CPT(RenderAttrib) LightRampAttrib::
159 make_hdr1() {
160  LightRampAttrib *attrib = new LightRampAttrib();
161  attrib->_mode = LRT_hdr1;
162  return return_new(attrib);
163 }
164 
165 ////////////////////////////////////////////////////////////////////
166 // Function: LightRampAttrib::make_hdr2
167 // Access: Published, Static
168 // Description: Constructs a new LightRampAttrib object. This causes
169 // an HDR tone mapping operation to be applied.
170 //
171 // Normally, brightness values greater than 1 cannot be
172 // distinguished from each other, causing very brightly lit
173 // objects to wash out white and all detail to be erased.
174 // HDR tone mapping remaps brightness values in the range
175 // 0-infinity into the range (0,1), making it possible to
176 // distinguish detail in scenes whose brightness exceeds 1.
177 //
178 // However, the monitor has finite contrast. Normally, all
179 // of that contrast is used to represent brightnesses in
180 // the range 0-1. The HDR2 tone mapping operator 'steals'
181 // one half of that contrast to represent brightnesses in
182 // the range 1-infinity.
183 // @code
184 // FINAL_RGB = (RGB) / (RGB + 1)
185 // @endcode
186 ////////////////////////////////////////////////////////////////////
187 CPT(RenderAttrib) LightRampAttrib::
188 make_hdr2() {
189  LightRampAttrib *attrib = new LightRampAttrib();
190  attrib->_mode = LRT_hdr2;
191  return return_new(attrib);
192 }
193 
194 ////////////////////////////////////////////////////////////////////
195 // Function: LightRampAttrib::output
196 // Access: Public, Virtual
197 // Description:
198 ////////////////////////////////////////////////////////////////////
199 void LightRampAttrib::
200 output(ostream &out) const {
201  out << get_type() << ":";
202  switch (_mode) {
203  case LRT_default:
204  out << "default()";
205  break;
206  case LRT_identity:
207  out << "identity()";
208  break;
209  case LRT_single_threshold:
210  out << "single_threshold(" << _level[0] << "," << _level[1] << "," << _threshold[0] << ")";
211  break;
212  case LRT_double_threshold:
213  out << "double_threshold(" << _level[0] << "," << _level[1] << "," << _threshold[0] << "," << _threshold[1] << ")";
214  break;
215  case LRT_hdr0:
216  out << "hdr0()";
217  break;
218  case LRT_hdr1:
219  out << "hdr1()";
220  break;
221  case LRT_hdr2:
222  out << "hdr2()";
223  break;
224  }
225 }
226 
227 ////////////////////////////////////////////////////////////////////
228 // Function: LightRampAttrib::compare_to_impl
229 // Access: Protected, Virtual
230 // Description: Intended to be overridden by derived LightRampAttrib
231 // types to return a unique number indicating whether
232 // this LightRampAttrib is equivalent to the other one.
233 //
234 // This should return 0 if the two LightRampAttrib objects
235 // are equivalent, a number less than zero if this one
236 // should be sorted before the other one, and a number
237 // greater than zero otherwise.
238 //
239 // This will only be called with two LightRampAttrib
240 // objects whose get_type() functions return the same.
241 ////////////////////////////////////////////////////////////////////
242 int LightRampAttrib::
243 compare_to_impl(const RenderAttrib *other) const {
244  const LightRampAttrib *ta;
245  DCAST_INTO_R(ta, other, 0);
246  int compare_result = ((int)_mode - (int)ta->_mode) ;
247  if (compare_result != 0) {
248  return compare_result;
249  }
250  for (int i = 0; i < 2; i++) {
251  if (_level[i] != ta->_level[i]) {
252  return (_level[i] < ta->_level[i]) ? -1 : 1;
253  }
254  }
255  for (int i = 0; i < 2; i++) {
256  if (_threshold[i] != ta->_threshold[i]) {
257  return (_threshold[i] < ta->_threshold[i]) ? -1 : 1;
258  }
259  }
260  return 0;
261 }
262 
263 ////////////////////////////////////////////////////////////////////
264 // Function: LightRampAttrib::get_hash_impl
265 // Access: Protected, Virtual
266 // Description: Intended to be overridden by derived RenderAttrib
267 // types to return a unique hash for these particular
268 // properties. RenderAttribs that compare the same with
269 // compare_to_impl(), above, should return the same
270 // hash; RenderAttribs that compare differently should
271 // return a different hash.
272 ////////////////////////////////////////////////////////////////////
273 size_t LightRampAttrib::
274 get_hash_impl() const {
275  size_t hash = 0;
276  hash = int_hash::add_hash(hash, (int)_mode);
277  float_hash fh;
278  for (int i = 0; i < 2; i++) {
279  hash = fh.add_hash(hash, _level[i]);
280  hash = fh.add_hash(hash, _threshold[i]);
281  }
282  return hash;
283 }
284 
285 ////////////////////////////////////////////////////////////////////
286 // Function: LightRampAttrib::get_auto_shader_attrib_impl
287 // Access: Protected, Virtual
288 // Description:
289 ////////////////////////////////////////////////////////////////////
290 CPT(RenderAttrib) LightRampAttrib::
291 get_auto_shader_attrib_impl(const RenderState *state) const {
292  return this;
293 }
294 
295 ////////////////////////////////////////////////////////////////////
296 // Function: LightRampAttrib::register_with_read_factory
297 // Access: Public, Static
298 // Description: Tells the BamReader how to create objects of type
299 // LightRampAttrib.
300 ////////////////////////////////////////////////////////////////////
301 void LightRampAttrib::
302 register_with_read_factory() {
303  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
304 }
305 
306 ////////////////////////////////////////////////////////////////////
307 // Function: LightRampAttrib::write_datagram
308 // Access: Public, Virtual
309 // Description: Writes the contents of this object to the datagram
310 // for shipping out to a Bam file.
311 ////////////////////////////////////////////////////////////////////
314  RenderAttrib::write_datagram(manager, dg);
315 
316  dg.add_int8(_mode);
317  for (int i=0; i<2; i++) {
318  dg.add_stdfloat(_level[i]);
319  }
320  for (int i=0; i<2; i++) {
321  dg.add_stdfloat(_threshold[i]);
322  }
323 }
324 
325 ////////////////////////////////////////////////////////////////////
326 // Function: LightRampAttrib::make_from_bam
327 // Access: Protected, Static
328 // Description: This function is called by the BamReader's factory
329 // when a new object of type LightRampAttrib is encountered
330 // in the Bam file. It should create the LightRampAttrib
331 // and extract its information from the file.
332 ////////////////////////////////////////////////////////////////////
333 TypedWritable *LightRampAttrib::
334 make_from_bam(const FactoryParams &params) {
335  LightRampAttrib *attrib = new LightRampAttrib;
336  DatagramIterator scan;
337  BamReader *manager;
338 
339  parse_params(params, scan, manager);
340  attrib->fillin(scan, manager);
341 
342  return attrib;
343 }
344 
345 ////////////////////////////////////////////////////////////////////
346 // Function: LightRampAttrib::fillin
347 // Access: Protected
348 // Description: This internal function is called by make_from_bam to
349 // read in all of the relevant data from the BamFile for
350 // the new LightRampAttrib.
351 ////////////////////////////////////////////////////////////////////
352 void LightRampAttrib::
353 fillin(DatagramIterator &scan, BamReader *manager) {
354  RenderAttrib::fillin(scan, manager);
355 
356  _mode = (LightRampMode)scan.get_int8();
357  for (int i=0; i<2; i++) {
358  _level[i] = scan.get_stdfloat();
359  }
360  for (int i=0; i<2; i++) {
361  _threshold[i] = scan.get_stdfloat();
362  }
363 }
PN_int8 get_int8()
Extracts a signed 8-bit integer.
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:60
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
void add_int8(PN_int8 value)
Adds a signed 8-bit integer to the datagram.
Definition: datagram.I:128
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
A Light Ramp is any unary operator that takes a rendered pixel as input, and adjusts the brightness o...
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
Definition: datagram.I:240
static size_t add_hash(size_t start, const Key &key)
Adds the indicated key into a running hash.
Definition: stl_compares.I:122
This hash_compare class hashes a float or a double.
Definition: stl_compares.h:158
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:53
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
size_t add_hash(size_t start, const Key &key) const
Adds the indicated key into a running hash.
Definition: stl_compares.I:180
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43