00001 // Filename: antialiasAttrib.cxx 00002 // Created by: drose (26Jan05) 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 "antialiasAttrib.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 AntialiasAttrib::_type_handle; 00024 int AntialiasAttrib::_attrib_slot; 00025 00026 //////////////////////////////////////////////////////////////////// 00027 // Function: AntialiasAttrib::make 00028 // Access: Published, Static 00029 // Description: Constructs a new AntialiasAttrib object. 00030 // 00031 // The mode should be either M_none, M_auto, or a union 00032 // of any or all of M_point, M_line, M_polygon, and 00033 // M_multisample. Also, in addition to the above 00034 // choices, it may include either of M_better of 00035 // M_faster to specify a performance/quality tradeoff 00036 // hint. 00037 // 00038 // If M_none is specified, no antialiasing is performed. 00039 // 00040 // If M_multisample is specified, it means to use the 00041 // special framebuffer multisample bits for 00042 // antialiasing, if it is available. If so, the 00043 // M_point, M_line, and M_polygon modes are ignored. 00044 // This advanced antialiasing mode is only available on 00045 // certain graphics hardware. If it is not available, 00046 // the M_multisample bit is ignored (and the other modes 00047 // may be used instead, if specified). 00048 // 00049 // M_point, M_line, and/or M_polygon specify 00050 // per-primitive smoothing. When enabled, M_point and 00051 // M_line may force transparency on. M_polygon requires 00052 // a frame buffer that includes an alpha channel, and it 00053 // works best if the primitives are sorted 00054 // front-to-back. 00055 // 00056 // If M_auto is specified, M_multisample is selected if 00057 // it is available, otherwise M_polygon is selected, 00058 // unless drawing lines or points, in which case M_line 00059 // or M_point is selected (these two generally produce 00060 // better results than M_multisample) 00061 //////////////////////////////////////////////////////////////////// 00062 CPT(RenderAttrib) AntialiasAttrib:: 00063 make(unsigned short mode) { 00064 AntialiasAttrib *attrib = new AntialiasAttrib(mode); 00065 return return_new(attrib); 00066 } 00067 00068 //////////////////////////////////////////////////////////////////// 00069 // Function: AntialiasAttrib::make_default 00070 // Access: Published, Static 00071 // Description: Returns a RenderAttrib that corresponds to whatever 00072 // the standard default properties for render attributes 00073 // of this type ought to be. 00074 //////////////////////////////////////////////////////////////////// 00075 CPT(RenderAttrib) AntialiasAttrib:: 00076 make_default() { 00077 if (default_antialias_enable) { 00078 return return_new(new AntialiasAttrib(M_auto)); 00079 } else { 00080 return return_new(new AntialiasAttrib(M_none)); 00081 } 00082 } 00083 00084 //////////////////////////////////////////////////////////////////// 00085 // Function: AntialiasAttrib::output 00086 // Access: Public, Virtual 00087 // Description: 00088 //////////////////////////////////////////////////////////////////// 00089 void AntialiasAttrib:: 00090 output(ostream &out) const { 00091 out << get_type() << ":"; 00092 00093 int type = get_mode_type(); 00094 char sep = ' '; 00095 00096 if (type == M_none) { 00097 out << " none"; 00098 00099 } else if (type == M_auto) { 00100 out << " auto"; 00101 00102 } else { 00103 if ((_mode & M_point) != 0) { 00104 out << sep << "point"; 00105 sep = '|'; 00106 } 00107 if ((_mode & M_line) != 0) { 00108 out << sep << "line"; 00109 sep = '|'; 00110 } 00111 if ((_mode & M_polygon) != 0) { 00112 out << sep << "polygon"; 00113 sep = '|'; 00114 } 00115 if ((_mode & M_auto) != 0) { 00116 out << sep << "best"; 00117 sep = '|'; 00118 } 00119 } 00120 00121 if ((_mode & M_faster) != 0) { 00122 out << sep << "faster"; 00123 sep = '|'; 00124 } 00125 if ((_mode & M_better) != 0) { 00126 out << sep << "better"; 00127 sep = '|'; 00128 } 00129 } 00130 00131 //////////////////////////////////////////////////////////////////// 00132 // Function: AntialiasAttrib::compare_to_impl 00133 // Access: Protected, Virtual 00134 // Description: Intended to be overridden by derived AntialiasAttrib 00135 // types to return a unique number indicating whether 00136 // this AntialiasAttrib is equivalent to the other one. 00137 // 00138 // This should return 0 if the two AntialiasAttrib objects 00139 // are equivalent, a number less than zero if this one 00140 // should be sorted before the other one, and a number 00141 // greater than zero otherwise. 00142 // 00143 // This will only be called with two AntialiasAttrib 00144 // objects whose get_type() functions return the same. 00145 //////////////////////////////////////////////////////////////////// 00146 int AntialiasAttrib:: 00147 compare_to_impl(const RenderAttrib *other) const { 00148 const AntialiasAttrib *ta; 00149 DCAST_INTO_R(ta, other, 0); 00150 if (_mode != ta->_mode) { 00151 return (int)_mode - (int)ta->_mode; 00152 } 00153 return 0; 00154 } 00155 00156 //////////////////////////////////////////////////////////////////// 00157 // Function: AntialiasAttrib::get_hash_impl 00158 // Access: Protected, Virtual 00159 // Description: Intended to be overridden by derived RenderAttrib 00160 // types to return a unique hash for these particular 00161 // properties. RenderAttribs that compare the same with 00162 // compare_to_impl(), above, should return the same 00163 // hash; RenderAttribs that compare differently should 00164 // return a different hash. 00165 //////////////////////////////////////////////////////////////////// 00166 size_t AntialiasAttrib:: 00167 get_hash_impl() const { 00168 size_t hash = 0; 00169 hash = int_hash::add_hash(hash, (int)_mode); 00170 return hash; 00171 } 00172 00173 //////////////////////////////////////////////////////////////////// 00174 // Function: AntialiasAttrib::compose_impl 00175 // Access: Protected, Virtual 00176 // Description: Intended to be overridden by derived RenderAttrib 00177 // types to specify how two consecutive RenderAttrib 00178 // objects of the same type interact. 00179 // 00180 // This should return the result of applying the other 00181 // RenderAttrib to a node in the scene graph below this 00182 // RenderAttrib, which was already applied. In most 00183 // cases, the result is the same as the other 00184 // RenderAttrib (that is, a subsequent RenderAttrib 00185 // completely replaces the preceding one). On the other 00186 // hand, some kinds of RenderAttrib (for instance, 00187 // ColorTransformAttrib) might combine in meaningful 00188 // ways. 00189 //////////////////////////////////////////////////////////////////// 00190 CPT(RenderAttrib) AntialiasAttrib:: 00191 compose_impl(const RenderAttrib *other) const { 00192 const AntialiasAttrib *ta; 00193 DCAST_INTO_R(ta, other, 0); 00194 00195 unsigned short mode_type; 00196 unsigned short mode_quality; 00197 00198 if (ta->get_mode_type() == M_none || ta->get_mode_type() == M_auto || 00199 get_mode_type() == M_auto) { 00200 // These two special types don't combine: if one of these modes is 00201 // involved, the lower attrib wins. 00202 mode_type = ta->get_mode_type(); 00203 00204 } else { 00205 // Otherwise, the both modes reflect an explicit setting. In that 00206 // case, these modes combine in the sensible way, as a union of 00207 // bits. 00208 mode_type = get_mode_type() | ta->get_mode_type(); 00209 } 00210 00211 if (ta->get_mode_quality() != 0) { 00212 // If any quality is specified on the lower attrib, it wins. 00213 mode_quality = ta->get_mode_quality(); 00214 } else { 00215 // Otherwise, the upper quality wins. 00216 mode_quality = get_mode_quality(); 00217 } 00218 00219 return make(mode_type | mode_quality); 00220 } 00221 00222 //////////////////////////////////////////////////////////////////// 00223 // Function: AntialiasAttrib::register_with_read_factory 00224 // Access: Public, Static 00225 // Description: Tells the BamReader how to create objects of type 00226 // AntialiasAttrib. 00227 //////////////////////////////////////////////////////////////////// 00228 void AntialiasAttrib:: 00229 register_with_read_factory() { 00230 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00231 } 00232 00233 //////////////////////////////////////////////////////////////////// 00234 // Function: AntialiasAttrib::write_datagram 00235 // Access: Public, Virtual 00236 // Description: Writes the contents of this object to the datagram 00237 // for shipping out to a Bam file. 00238 //////////////////////////////////////////////////////////////////// 00239 void AntialiasAttrib:: 00240 write_datagram(BamWriter *manager, Datagram &dg) { 00241 RenderAttrib::write_datagram(manager, dg); 00242 00243 dg.add_uint16(_mode); 00244 } 00245 00246 //////////////////////////////////////////////////////////////////// 00247 // Function: AntialiasAttrib::make_from_bam 00248 // Access: Protected, Static 00249 // Description: This function is called by the BamReader's factory 00250 // when a new object of type AntialiasAttrib is encountered 00251 // in the Bam file. It should create the AntialiasAttrib 00252 // and extract its information from the file. 00253 //////////////////////////////////////////////////////////////////// 00254 TypedWritable *AntialiasAttrib:: 00255 make_from_bam(const FactoryParams ¶ms) { 00256 AntialiasAttrib *attrib = new AntialiasAttrib(M_none); 00257 DatagramIterator scan; 00258 BamReader *manager; 00259 00260 parse_params(params, scan, manager); 00261 attrib->fillin(scan, manager); 00262 00263 return attrib; 00264 } 00265 00266 //////////////////////////////////////////////////////////////////// 00267 // Function: AntialiasAttrib::fillin 00268 // Access: Protected 00269 // Description: This internal function is called by make_from_bam to 00270 // read in all of the relevant data from the BamFile for 00271 // the new AntialiasAttrib. 00272 //////////////////////////////////////////////////////////////////// 00273 void AntialiasAttrib:: 00274 fillin(DatagramIterator &scan, BamReader *manager) { 00275 RenderAttrib::fillin(scan, manager); 00276 00277 _mode = scan.get_uint16(); 00278 }