Panda3D
 All Classes Functions Variables Enumerations
cullFaceAttrib.cxx
1 // Filename: cullFaceAttrib.cxx
2 // Created by: drose (27Feb02)
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 "cullFaceAttrib.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 CullFaceAttrib::_type_handle;
24 int CullFaceAttrib::_attrib_slot;
25 
26 ////////////////////////////////////////////////////////////////////
27 // Function: CullFaceAttrib::make
28 // Access: Published, Static
29 // Description: Constructs a new CullFaceAttrib object that specifies
30 // how to cull geometry. By Panda convention, vertices
31 // are ordered counterclockwise when seen from the
32 // front, so the M_cull_clockwise will cull backfacing
33 // polygons.
34 //
35 // M_cull_unchanged is an identity attrib; if this is
36 // applied to vertices without any other intervening
37 // attrib, it is the same as applying the default
38 // attrib.
39 ////////////////////////////////////////////////////////////////////
41 make(CullFaceAttrib::Mode mode) {
42  CullFaceAttrib *attrib = new CullFaceAttrib(mode, false);
43  return return_new(attrib);
44 }
45 
46 ////////////////////////////////////////////////////////////////////
47 // Function: CullFaceAttrib::make_reverse
48 // Access: Published, Static
49 // Description: Constructs a new CullFaceAttrib object that reverses
50 // the effects of any other CullFaceAttrib objects in
51 // the scene graph. M_cull_clockwise will be treated as
52 // M_cull_counter_clockwise, and vice-versa.
53 // M_cull_none is unchanged.
54 ////////////////////////////////////////////////////////////////////
56 make_reverse() {
57  CullFaceAttrib *attrib = new CullFaceAttrib(M_cull_unchanged, true);
58  return return_new(attrib);
59 }
60 
61 ////////////////////////////////////////////////////////////////////
62 // Function: CullFaceAttrib::make_default
63 // Access: Published, Static
64 // Description: Returns a RenderAttrib that corresponds to whatever
65 // the standard default properties for render attributes
66 // of this type ought to be.
67 ////////////////////////////////////////////////////////////////////
69 make_default() {
70  return return_new(new CullFaceAttrib(M_cull_clockwise, false));
71 }
72 
73 ////////////////////////////////////////////////////////////////////
74 // Function: CullFaceAttrib::get_effective_mode
75 // Access: Published
76 // Description: Returns the effective culling mode. This is the same
77 // as the actual culling mode, unless the reverse flag
78 // is set, which swaps CW for CCW and vice-versa. Also,
79 // M_cull_unchanged is mapped to M_cull_none.
80 ////////////////////////////////////////////////////////////////////
81 CullFaceAttrib::Mode CullFaceAttrib::
83  if (_reverse) {
84  switch (_mode) {
85  case M_cull_clockwise:
86  case M_cull_unchanged:
87  return M_cull_counter_clockwise;
88 
89  case M_cull_counter_clockwise:
90  return M_cull_clockwise;
91 
92  default:
93  break;
94  }
95 
96  } else {
97  switch (_mode) {
98  case M_cull_clockwise:
99  case M_cull_unchanged:
100  return M_cull_clockwise;
101 
102  case M_cull_counter_clockwise:
103  return M_cull_counter_clockwise;
104 
105  default:
106  break;
107  }
108  }
109 
110  return M_cull_none;
111 }
112 
113 ////////////////////////////////////////////////////////////////////
114 // Function: CullFaceAttrib::output
115 // Access: Public, Virtual
116 // Description:
117 ////////////////////////////////////////////////////////////////////
118 void CullFaceAttrib::
119 output(ostream &out) const {
120  out << get_type() << ":";
121  switch (get_actual_mode()) {
122  case M_cull_none:
123  out << "cull_none";
124  break;
125  case M_cull_clockwise:
126  out << "cull_clockwise";
127  break;
128  case M_cull_counter_clockwise:
129  out << "cull_counter_clockwise";
130  break;
131  case M_cull_unchanged:
132  out << "cull_unchanged";
133  break;
134  }
135  if (get_reverse()) {
136  out << "(reverse)";
137  }
138 }
139 
140 ////////////////////////////////////////////////////////////////////
141 // Function: CullFaceAttrib::compare_to_impl
142 // Access: Protected, Virtual
143 // Description: Intended to be overridden by derived CullFaceAttrib
144 // types to return a unique number indicating whether
145 // this CullFaceAttrib is equivalent to the other one.
146 //
147 // This should return 0 if the two CullFaceAttrib objects
148 // are equivalent, a number less than zero if this one
149 // should be sorted before the other one, and a number
150 // greater than zero otherwise.
151 //
152 // This will only be called with two CullFaceAttrib
153 // objects whose get_type() functions return the same.
154 ////////////////////////////////////////////////////////////////////
155 int CullFaceAttrib::
156 compare_to_impl(const RenderAttrib *other) const {
157  const CullFaceAttrib *ta;
158  DCAST_INTO_R(ta, other, 0);
159  if (_mode != ta->_mode) {
160  return (int)_mode - (int)ta->_mode;
161  }
162  return (int)_reverse - (int)ta->_reverse;
163 }
164 
165 ////////////////////////////////////////////////////////////////////
166 // Function: CullFaceAttrib::get_hash_impl
167 // Access: Protected, Virtual
168 // Description: Intended to be overridden by derived RenderAttrib
169 // types to return a unique hash for these particular
170 // properties. RenderAttribs that compare the same with
171 // compare_to_impl(), above, should return the same
172 // hash; RenderAttribs that compare differently should
173 // return a different hash.
174 ////////////////////////////////////////////////////////////////////
175 size_t CullFaceAttrib::
176 get_hash_impl() const {
177  size_t hash = 0;
178  hash = int_hash::add_hash(hash, (int)_mode);
179  hash = int_hash::add_hash(hash, (int)_reverse);
180  return hash;
181 }
182 
183 ////////////////////////////////////////////////////////////////////
184 // Function: CullFaceAttrib::compose_impl
185 // Access: Protected, Virtual
186 // Description: Intended to be overridden by derived RenderAttrib
187 // types to specify how two consecutive RenderAttrib
188 // objects of the same type interact.
189 //
190 // This should return the result of applying the other
191 // RenderAttrib to a node in the scene graph below this
192 // RenderAttrib, which was already applied. In most
193 // cases, the result is the same as the other
194 // RenderAttrib (that is, a subsequent RenderAttrib
195 // completely replaces the preceding one). On the other
196 // hand, some kinds of RenderAttrib (for instance,
197 // ColorTransformAttrib) might combine in meaningful
198 // ways.
199 ////////////////////////////////////////////////////////////////////
201 compose_impl(const RenderAttrib *other) const {
202  const CullFaceAttrib *ta;
203  DCAST_INTO_R(ta, other, 0);
204 
205  if (!_reverse && ta->_mode != M_cull_unchanged) {
206  // The normal case (there is nothing funny going on): the second
207  // attrib completely replaces this attrib.
208  return other;
209  }
210 
211  // In the more complex case, the two attribs affect each other in
212  // some way, and we must generate a new attrib from the result.
213  Mode mode = _mode;
214  if (ta->_mode != M_cull_unchanged) {
215  mode = ta->_mode;
216  }
217  bool reverse = (_reverse && !ta->_reverse) || (!_reverse && ta->_reverse);
218 
219  CullFaceAttrib *attrib = new CullFaceAttrib(mode, reverse);
220  return return_new(attrib);
221 }
222 
223 ////////////////////////////////////////////////////////////////////
224 // Function: CullFaceAttrib::invert_compose_impl
225 // Access: Protected, Virtual
226 // Description: Intended to be overridden by derived RenderAttrib
227 // types to specify how two consecutive RenderAttrib
228 // objects of the same type interact.
229 //
230 // See invert_compose() and compose_impl().
231 ////////////////////////////////////////////////////////////////////
233 invert_compose_impl(const RenderAttrib *other) const {
234  const CullFaceAttrib *ta;
235  DCAST_INTO_R(ta, other, 0);
236 
237  // The invert case is the same as the normal case, except that the
238  // meaning of _reverse is inverted. See compose_impl(), above.
239 
240  if (_reverse && ta->_mode != M_cull_unchanged) {
241  return other;
242  }
243 
244  Mode mode = _mode;
245  if (ta->_mode != M_cull_unchanged) {
246  mode = ta->_mode;
247  }
248  bool reverse = (!_reverse && !ta->_reverse) || (_reverse && ta->_reverse);
249 
250  CullFaceAttrib *attrib = new CullFaceAttrib(mode, reverse);
251  return return_new(attrib);
252 }
253 
254 ////////////////////////////////////////////////////////////////////
255 // Function: CullFaceAttrib::register_with_read_factory
256 // Access: Public, Static
257 // Description: Tells the BamReader how to create objects of type
258 // CullFaceAttrib.
259 ////////////////////////////////////////////////////////////////////
260 void CullFaceAttrib::
262  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
263 }
264 
265 ////////////////////////////////////////////////////////////////////
266 // Function: CullFaceAttrib::write_datagram
267 // Access: Public, Virtual
268 // Description: Writes the contents of this object to the datagram
269 // for shipping out to a Bam file.
270 ////////////////////////////////////////////////////////////////////
271 void CullFaceAttrib::
273  RenderAttrib::write_datagram(manager, dg);
274 
275  dg.add_int8(_mode);
276  dg.add_bool(_reverse);
277 }
278 
279 ////////////////////////////////////////////////////////////////////
280 // Function: CullFaceAttrib::make_from_bam
281 // Access: Protected, Static
282 // Description: This function is called by the BamReader's factory
283 // when a new object of type CullFaceAttrib is encountered
284 // in the Bam file. It should create the CullFaceAttrib
285 // and extract its information from the file.
286 ////////////////////////////////////////////////////////////////////
287 TypedWritable *CullFaceAttrib::
288 make_from_bam(const FactoryParams &params) {
289  CullFaceAttrib *attrib = new CullFaceAttrib(M_cull_none, false);
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 // Function: CullFaceAttrib::fillin
301 // Access: Protected
302 // Description: This internal function is called by make_from_bam to
303 // read in all of the relevant data from the BamFile for
304 // the new CullFaceAttrib.
305 ////////////////////////////////////////////////////////////////////
306 void CullFaceAttrib::
307 fillin(DatagramIterator &scan, BamReader *manager) {
308  RenderAttrib::fillin(scan, manager);
309 
310  _mode = (Mode)scan.get_int8();
311  _reverse = scan.get_bool();
312 }
PN_int8 get_int8()
Extracts a signed 8-bit integer.
bool get_bool()
Extracts a boolean value.
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
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
Indicates which faces should be culled based on their vertex ordering.
static size_t add_hash(size_t start, const Key &key)
Adds the indicated key into a running hash.
Definition: stl_compares.I:122
Mode get_effective_mode() const
Returns the effective culling mode.
void add_bool(bool value)
Adds a boolean value to the datagram.
Definition: datagram.I:118
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
bool get_reverse() const
Returns the &#39;reverse&#39; flag.
static void register_with_read_factory()
Tells the BamReader how to create objects of type CullFaceAttrib.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
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
Mode get_actual_mode() const
Returns the actual culling mode, without considering the effects of the reverse flag.