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