00001 // Filename: lightRampAttrib.cxx 00002 // Created by: drose (04Mar02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "lightRampAttrib.h" 00016 #include "graphicsStateGuardianBase.h" 00017 #include "dcast.h" 00018 #include "bamReader.h" 00019 #include "bamWriter.h" 00020 #include "datagram.h" 00021 #include "datagramIterator.h" 00022 00023 TypeHandle LightRampAttrib::_type_handle; 00024 int LightRampAttrib::_attrib_slot; 00025 CPT(RenderAttrib) LightRampAttrib::_default; 00026 00027 //////////////////////////////////////////////////////////////////// 00028 // Function: LightRampAttrib::make_default 00029 // Access: Published, Static 00030 // Description: Constructs a new LightRampAttrib object. This 00031 // is the standard OpenGL lighting ramp, which clamps 00032 // the final light total to the 0-1 range. 00033 //////////////////////////////////////////////////////////////////// 00034 CPT(RenderAttrib) LightRampAttrib:: 00035 make_default() { 00036 if (_default == 0) { 00037 LightRampAttrib *attrib = new LightRampAttrib(); 00038 _default = return_new(attrib); 00039 } 00040 return _default; 00041 } 00042 00043 //////////////////////////////////////////////////////////////////// 00044 // Function: LightRampAttrib::make_identity 00045 // Access: Published, Static 00046 // Description: Constructs a new LightRampAttrib object. This 00047 // differs from the usual OpenGL lighting model in that 00048 // it does not clamp the final lighting total to (0,1). 00049 //////////////////////////////////////////////////////////////////// 00050 CPT(RenderAttrib) LightRampAttrib:: 00051 make_identity() { 00052 LightRampAttrib *attrib = new LightRampAttrib(); 00053 attrib->_mode = LRT_identity; 00054 return return_new(attrib); 00055 } 00056 00057 //////////////////////////////////////////////////////////////////// 00058 // Function: LightRampAttrib::make_single_threshold 00059 // Access: Published, Static 00060 // Description: Constructs a new LightRampAttrib object. This 00061 // causes the luminance of the diffuse lighting 00062 // contribution to be quantized using a single threshold: 00063 // @code 00064 // if (original_luminance > threshold0) { 00065 // luminance = level0; 00066 // } else { 00067 // luminance = 0.0; 00068 // } 00069 // @endcode 00070 //////////////////////////////////////////////////////////////////// 00071 CPT(RenderAttrib) LightRampAttrib:: 00072 make_single_threshold(PN_stdfloat thresh0, PN_stdfloat val0) { 00073 LightRampAttrib *attrib = new LightRampAttrib(); 00074 attrib->_mode = LRT_single_threshold; 00075 attrib->_threshold[0] = thresh0; 00076 attrib->_level[0] = val0; 00077 return return_new(attrib); 00078 } 00079 00080 //////////////////////////////////////////////////////////////////// 00081 // Function: LightRampAttrib::make_double_threshold 00082 // Access: Published, Static 00083 // Description: Constructs a new LightRampAttrib object. This 00084 // causes the luminance of the diffuse lighting 00085 // contribution to be quantized using two thresholds: 00086 // @code 00087 // if (original_luminance > threshold1) { 00088 // luminance = level1; 00089 // } else if (original_luminance > threshold0) { 00090 // luminance = level0; 00091 // } else { 00092 // luminance = 0.0; 00093 // } 00094 // @endcode 00095 //////////////////////////////////////////////////////////////////// 00096 CPT(RenderAttrib) LightRampAttrib:: 00097 make_double_threshold(PN_stdfloat thresh0, PN_stdfloat val0, PN_stdfloat thresh1, PN_stdfloat val1) { 00098 LightRampAttrib *attrib = new LightRampAttrib(); 00099 attrib->_mode = LRT_single_threshold; 00100 attrib->_threshold[0] = thresh0; 00101 attrib->_level[0] = val0; 00102 attrib->_threshold[1] = thresh1; 00103 attrib->_level[1] = val1; 00104 return return_new(attrib); 00105 } 00106 00107 //////////////////////////////////////////////////////////////////// 00108 // Function: LightRampAttrib::make_hdr0 00109 // Access: Published, Static 00110 // Description: Constructs a new LightRampAttrib object. This causes 00111 // an HDR tone mapping operation to be applied. 00112 // 00113 // Normally, brightness values greater than 1 cannot be 00114 // distinguished from each other, causing very brightly lit 00115 // objects to wash out white and all detail to be erased. 00116 // HDR tone mapping remaps brightness values in the range 00117 // 0-infinity into the range (0,1), making it possible to 00118 // distinguish detail in scenes whose brightness exceeds 1. 00119 // 00120 // However, the monitor has finite contrast. Normally, all 00121 // of that contrast is used to represent brightnesses in 00122 // the range 0-1. The HDR0 tone mapping operator 'steals' 00123 // one quarter of that contrast to represent brightnesses in 00124 // the range 1-infinity. 00125 // @code 00126 // FINAL_RGB = (RGB^3 + RGB^2 + RGB) / (RGB^3 + RGB^2 + RGB + 1) 00127 // @endcode 00128 //////////////////////////////////////////////////////////////////// 00129 CPT(RenderAttrib) LightRampAttrib:: 00130 make_hdr0() { 00131 LightRampAttrib *attrib = new LightRampAttrib(); 00132 attrib->_mode = LRT_hdr0; 00133 return return_new(attrib); 00134 } 00135 00136 //////////////////////////////////////////////////////////////////// 00137 // Function: LightRampAttrib::make_hdr1 00138 // Access: Published, Static 00139 // Description: Constructs a new LightRampAttrib object. This causes 00140 // an HDR tone mapping operation to be applied. 00141 // 00142 // Normally, brightness values greater than 1 cannot be 00143 // distinguished from each other, causing very brightly lit 00144 // objects to wash out white and all detail to be erased. 00145 // HDR tone mapping remaps brightness values in the range 00146 // 0-infinity into the range (0,1), making it possible to 00147 // distinguish detail in scenes whose brightness exceeds 1. 00148 // 00149 // However, the monitor has finite contrast. Normally, all 00150 // of that contrast is used to represent brightnesses in 00151 // the range 0-1. The HDR1 tone mapping operator 'steals' 00152 // one third of that contrast to represent brightnesses in 00153 // the range 1-infinity. 00154 // @code 00155 // FINAL_RGB = (RGB^2 + RGB) / (RGB^2 + RGB + 1) 00156 // @endcode 00157 //////////////////////////////////////////////////////////////////// 00158 CPT(RenderAttrib) LightRampAttrib:: 00159 make_hdr1() { 00160 LightRampAttrib *attrib = new LightRampAttrib(); 00161 attrib->_mode = LRT_hdr1; 00162 return return_new(attrib); 00163 } 00164 00165 //////////////////////////////////////////////////////////////////// 00166 // Function: LightRampAttrib::make_hdr2 00167 // Access: Published, Static 00168 // Description: Constructs a new LightRampAttrib object. This causes 00169 // an HDR tone mapping operation to be applied. 00170 // 00171 // Normally, brightness values greater than 1 cannot be 00172 // distinguished from each other, causing very brightly lit 00173 // objects to wash out white and all detail to be erased. 00174 // HDR tone mapping remaps brightness values in the range 00175 // 0-infinity into the range (0,1), making it possible to 00176 // distinguish detail in scenes whose brightness exceeds 1. 00177 // 00178 // However, the monitor has finite contrast. Normally, all 00179 // of that contrast is used to represent brightnesses in 00180 // the range 0-1. The HDR2 tone mapping operator 'steals' 00181 // one half of that contrast to represent brightnesses in 00182 // the range 1-infinity. 00183 // @code 00184 // FINAL_RGB = (RGB) / (RGB + 1) 00185 // @endcode 00186 //////////////////////////////////////////////////////////////////// 00187 CPT(RenderAttrib) LightRampAttrib:: 00188 make_hdr2() { 00189 LightRampAttrib *attrib = new LightRampAttrib(); 00190 attrib->_mode = LRT_hdr2; 00191 return return_new(attrib); 00192 } 00193 00194 //////////////////////////////////////////////////////////////////// 00195 // Function: LightRampAttrib::output 00196 // Access: Public, Virtual 00197 // Description: 00198 //////////////////////////////////////////////////////////////////// 00199 void LightRampAttrib:: 00200 output(ostream &out) const { 00201 out << get_type() << ":"; 00202 switch (_mode) { 00203 case LRT_default: 00204 out << "default()"; 00205 break; 00206 case LRT_identity: 00207 out << "identity()"; 00208 break; 00209 case LRT_single_threshold: 00210 out << "single_threshold(" << _level[0] << "," << _level[1] << "," << _threshold[0] << ")"; 00211 break; 00212 case LRT_double_threshold: 00213 out << "double_threshold(" << _level[0] << "," << _level[1] << "," << _threshold[0] << "," << _threshold[1] << ")"; 00214 break; 00215 case LRT_hdr0: 00216 out << "hdr0()"; 00217 break; 00218 case LRT_hdr1: 00219 out << "hdr1()"; 00220 break; 00221 case LRT_hdr2: 00222 out << "hdr2()"; 00223 break; 00224 } 00225 } 00226 00227 //////////////////////////////////////////////////////////////////// 00228 // Function: LightRampAttrib::compare_to_impl 00229 // Access: Protected, Virtual 00230 // Description: Intended to be overridden by derived LightRampAttrib 00231 // types to return a unique number indicating whether 00232 // this LightRampAttrib is equivalent to the other one. 00233 // 00234 // This should return 0 if the two LightRampAttrib objects 00235 // are equivalent, a number less than zero if this one 00236 // should be sorted before the other one, and a number 00237 // greater than zero otherwise. 00238 // 00239 // This will only be called with two LightRampAttrib 00240 // objects whose get_type() functions return the same. 00241 //////////////////////////////////////////////////////////////////// 00242 int LightRampAttrib:: 00243 compare_to_impl(const RenderAttrib *other) const { 00244 const LightRampAttrib *ta; 00245 DCAST_INTO_R(ta, other, 0); 00246 int compare_result = ((int)_mode - (int)ta->_mode) ; 00247 if (compare_result != 0) { 00248 return compare_result; 00249 } 00250 for (int i = 0; i < 2; i++) { 00251 if (_level[i] != ta->_level[i]) { 00252 return (_level[i] < ta->_level[i]) ? -1 : 1; 00253 } 00254 } 00255 for (int i = 0; i < 2; i++) { 00256 if (_threshold[i] != ta->_threshold[i]) { 00257 return (_threshold[i] < ta->_threshold[i]) ? -1 : 1; 00258 } 00259 } 00260 return 0; 00261 } 00262 00263 //////////////////////////////////////////////////////////////////// 00264 // Function: LightRampAttrib::get_hash_impl 00265 // Access: Protected, Virtual 00266 // Description: Intended to be overridden by derived RenderAttrib 00267 // types to return a unique hash for these particular 00268 // properties. RenderAttribs that compare the same with 00269 // compare_to_impl(), above, should return the same 00270 // hash; RenderAttribs that compare differently should 00271 // return a different hash. 00272 //////////////////////////////////////////////////////////////////// 00273 size_t LightRampAttrib:: 00274 get_hash_impl() const { 00275 size_t hash = 0; 00276 hash = int_hash::add_hash(hash, (int)_mode); 00277 float_hash fh; 00278 for (int i = 0; i < 2; i++) { 00279 hash = fh.add_hash(hash, _level[i]); 00280 hash = fh.add_hash(hash, _threshold[i]); 00281 } 00282 return hash; 00283 } 00284 00285 //////////////////////////////////////////////////////////////////// 00286 // Function: LightRampAttrib::get_auto_shader_attrib_impl 00287 // Access: Protected, Virtual 00288 // Description: 00289 //////////////////////////////////////////////////////////////////// 00290 CPT(RenderAttrib) LightRampAttrib:: 00291 get_auto_shader_attrib_impl(const RenderState *state) const { 00292 return this; 00293 } 00294 00295 //////////////////////////////////////////////////////////////////// 00296 // Function: LightRampAttrib::register_with_read_factory 00297 // Access: Public, Static 00298 // Description: Tells the BamReader how to create objects of type 00299 // LightRampAttrib. 00300 //////////////////////////////////////////////////////////////////// 00301 void LightRampAttrib:: 00302 register_with_read_factory() { 00303 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00304 } 00305 00306 //////////////////////////////////////////////////////////////////// 00307 // Function: LightRampAttrib::write_datagram 00308 // Access: Public, Virtual 00309 // Description: Writes the contents of this object to the datagram 00310 // for shipping out to a Bam file. 00311 //////////////////////////////////////////////////////////////////// 00312 void LightRampAttrib:: 00313 write_datagram(BamWriter *manager, Datagram &dg) { 00314 RenderAttrib::write_datagram(manager, dg); 00315 00316 dg.add_int8(_mode); 00317 for (int i=0; i<2; i++) { 00318 dg.add_stdfloat(_level[i]); 00319 } 00320 for (int i=0; i<2; i++) { 00321 dg.add_stdfloat(_threshold[i]); 00322 } 00323 } 00324 00325 //////////////////////////////////////////////////////////////////// 00326 // Function: LightRampAttrib::make_from_bam 00327 // Access: Protected, Static 00328 // Description: This function is called by the BamReader's factory 00329 // when a new object of type LightRampAttrib is encountered 00330 // in the Bam file. It should create the LightRampAttrib 00331 // and extract its information from the file. 00332 //////////////////////////////////////////////////////////////////// 00333 TypedWritable *LightRampAttrib:: 00334 make_from_bam(const FactoryParams ¶ms) { 00335 LightRampAttrib *attrib = new LightRampAttrib; 00336 DatagramIterator scan; 00337 BamReader *manager; 00338 00339 parse_params(params, scan, manager); 00340 attrib->fillin(scan, manager); 00341 00342 return attrib; 00343 } 00344 00345 //////////////////////////////////////////////////////////////////// 00346 // Function: LightRampAttrib::fillin 00347 // Access: Protected 00348 // Description: This internal function is called by make_from_bam to 00349 // read in all of the relevant data from the BamFile for 00350 // the new LightRampAttrib. 00351 //////////////////////////////////////////////////////////////////// 00352 void LightRampAttrib:: 00353 fillin(DatagramIterator &scan, BamReader *manager) { 00354 RenderAttrib::fillin(scan, manager); 00355 00356 _mode = (LightRampMode)scan.get_int8(); 00357 for (int i=0; i<2; i++) { 00358 _level[i] = scan.get_stdfloat(); 00359 } 00360 for (int i=0; i<2; i++) { 00361 _threshold[i] = scan.get_stdfloat(); 00362 } 00363 }