Panda3D
 All Classes Functions Variables Enumerations
stencilAttrib.cxx
1 // Filename: stencilAttrib.cxx
2 // Created by: aignacio (18May06)
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 "stencilAttrib.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 StencilAttrib::_type_handle;
24 int StencilAttrib::_attrib_slot;
25 
26 const char *StencilAttrib::
27 stencil_render_state_name_array[StencilAttrib::SRS_total] =
28 {
29  "SRS_front_comparison_function",
30  "SRS_front_stencil_fail_operation",
31  "SRS_front_stencil_pass_z_fail_operation",
32  "SRS_front_stencil_pass_z_pass_operation",
33 
34  "SRS_reference",
35  "SRS_read_mask",
36  "SRS_write_mask",
37 
38  "SRS_back_comparison_function",
39  "SRS_back_stencil_fail_operation",
40  "SRS_back_stencil_pass_z_fail_operation",
41  "SRS_back_stencil_pass_z_pass_operation",
42 
43  "SRS_clear",
44  "SRS_clear_value",
45 };
46 
47 ////////////////////////////////////////////////////////////////////
48 // Function: StencilAttrib::Constructor
49 // Access: Private
50 // Description: Use StencilAttrib::make() to construct a new
51 // StencilAttrib object.
52 ////////////////////////////////////////////////////////////////////
53 StencilAttrib::
54 StencilAttrib() {
55  _stencil_render_states [SRS_front_comparison_function] = M_none;
56  _stencil_render_states [SRS_front_stencil_fail_operation] = SO_keep;
57  _stencil_render_states [SRS_front_stencil_pass_z_fail_operation] = SO_keep;
58  _stencil_render_states [SRS_front_stencil_pass_z_pass_operation] = SO_keep;
59 
60  _stencil_render_states [SRS_reference] = 0;
61  _stencil_render_states [SRS_read_mask] = ~0;
62  _stencil_render_states [SRS_write_mask] = ~0;
63 
64  _stencil_render_states [SRS_back_comparison_function] = M_none;
65  _stencil_render_states [SRS_back_stencil_fail_operation] = SO_keep;
66  _stencil_render_states [SRS_back_stencil_pass_z_fail_operation] = SO_keep;
67  _stencil_render_states [SRS_back_stencil_pass_z_pass_operation] = SO_keep;
68 
69  _stencil_render_states [SRS_clear] = 0;
70  _stencil_render_states [SRS_clear_value] = 0;
71 }
72 
73 ////////////////////////////////////////////////////////////////////
74 // Function: StencilAttrib::make_off
75 // Access: Published, Static
76 // Description: Constructs a StencilAttrib that has stenciling
77 // turned off.
78 ////////////////////////////////////////////////////////////////////
80 make_off() {
81  StencilAttrib *attrib = new StencilAttrib;
82  return return_new(attrib);
83 }
84 
85 ////////////////////////////////////////////////////////////////////
86 // Function: StencilAttrib::make_default
87 // Access: Published, Static
88 // Description: Returns a RenderAttrib that corresponds to whatever
89 // the standard default properties for render attributes
90 // of this type ought to be.
91 ////////////////////////////////////////////////////////////////////
93 make_default() {
94  return return_new(new StencilAttrib);
95 }
96 
97 ////////////////////////////////////////////////////////////////////
98 // Function: StencilAttrib::make
99 // Access: Published, Static
100 // Description: Constructs a front face StencilAttrib.
101 ////////////////////////////////////////////////////////////////////
103 make(
104  bool front_enable,
105  PandaCompareFunc front_comparison_function,
106  StencilOperation stencil_fail_operation,
107  StencilOperation stencil_pass_z_fail_operation,
108  StencilOperation front_stencil_pass_z_pass_operation,
109  unsigned int reference,
110  unsigned int read_mask,
111  unsigned int write_mask)
112 {
113  StencilAttrib *attrib = new StencilAttrib;
114 
115  if (!front_enable) {
116  front_comparison_function = M_none;
117  }
118 
119  attrib->_stencil_render_states [SRS_front_comparison_function] = front_comparison_function;
120  attrib->_stencil_render_states [SRS_front_stencil_fail_operation] = stencil_fail_operation;
121  attrib->_stencil_render_states [SRS_front_stencil_pass_z_fail_operation] = stencil_pass_z_fail_operation;
122  attrib->_stencil_render_states [SRS_front_stencil_pass_z_pass_operation] = front_stencil_pass_z_pass_operation;
123 
124  attrib->_stencil_render_states [SRS_reference] = reference;
125  attrib->_stencil_render_states [SRS_read_mask] = read_mask;
126  attrib->_stencil_render_states [SRS_write_mask] = write_mask;
127 
128  attrib->_stencil_render_states [SRS_back_comparison_function] = M_none;
129  attrib->_stencil_render_states [SRS_back_stencil_fail_operation] = SO_keep;
130  attrib->_stencil_render_states [SRS_back_stencil_pass_z_fail_operation] = SO_keep;
131  attrib->_stencil_render_states [SRS_back_stencil_pass_z_pass_operation] = SO_keep;
132 
133  return return_new(attrib);
134 }
135 
136 ////////////////////////////////////////////////////////////////////
137 // Function: StencilAttrib::make_2_sided
138 // Access: Published, Static
139 // Description: Constructs a two-sided StencilAttrib.
140 ////////////////////////////////////////////////////////////////////
142 make_2_sided(
143  bool front_enable,
144  bool back_enable,
145  PandaCompareFunc front_comparison_function,
146  StencilOperation stencil_fail_operation,
147  StencilOperation stencil_pass_z_fail_operation,
148  StencilOperation front_stencil_pass_z_pass_operation,
149  unsigned int reference,
150  unsigned int read_mask,
151  unsigned int write_mask,
152  PandaCompareFunc back_comparison_function,
153  StencilOperation back_stencil_fail_operation,
154  StencilOperation back_stencil_pass_z_fail_operation,
155  StencilOperation back_stencil_pass_z_pass_operation)
156 {
157  StencilAttrib *attrib = new StencilAttrib;
158 
159  if (!front_enable) {
160  front_comparison_function = M_none;
161  }
162 
163  if (!back_enable) {
164  back_comparison_function = M_none;
165  }
166 
167  attrib->_stencil_render_states [SRS_front_comparison_function] = front_comparison_function;
168  attrib->_stencil_render_states [SRS_front_stencil_fail_operation] = stencil_fail_operation;
169  attrib->_stencil_render_states [SRS_front_stencil_pass_z_fail_operation] = stencil_pass_z_fail_operation;
170  attrib->_stencil_render_states [SRS_front_stencil_pass_z_pass_operation] = front_stencil_pass_z_pass_operation;
171 
172  attrib->_stencil_render_states [SRS_reference] = reference;
173  attrib->_stencil_render_states [SRS_read_mask] = read_mask;
174  attrib->_stencil_render_states [SRS_write_mask] = write_mask;
175 
176  attrib->_stencil_render_states [SRS_back_comparison_function] = back_comparison_function;
177  attrib->_stencil_render_states [SRS_back_stencil_fail_operation] = back_stencil_fail_operation;
178  attrib->_stencil_render_states [SRS_back_stencil_pass_z_fail_operation] = back_stencil_pass_z_fail_operation;
179  attrib->_stencil_render_states [SRS_back_stencil_pass_z_pass_operation] = back_stencil_pass_z_pass_operation;
180 
181  return return_new(attrib);
182 }
183 
184 ////////////////////////////////////////////////////////////////////
185 // Function: StencilAttrib::make
186 // Access: Published, Static
187 // Description: Constructs a front face StencilAttrib.
188 ////////////////////////////////////////////////////////////////////
190 make_with_clear(
191  bool front_enable,
192  PandaCompareFunc front_comparison_function,
193  StencilOperation stencil_fail_operation,
194  StencilOperation stencil_pass_z_fail_operation,
195  StencilOperation front_stencil_pass_z_pass_operation,
196  unsigned int reference,
197  unsigned int read_mask,
198  unsigned int write_mask,
199  bool clear,
200  unsigned int clear_value)
201 {
202  StencilAttrib *attrib = new StencilAttrib;
203 
204  if (!front_enable) {
205  front_comparison_function = M_none;
206  }
207 
208  attrib->_stencil_render_states [SRS_front_comparison_function] = front_comparison_function;
209  attrib->_stencil_render_states [SRS_front_stencil_fail_operation] = stencil_fail_operation;
210  attrib->_stencil_render_states [SRS_front_stencil_pass_z_fail_operation] = stencil_pass_z_fail_operation;
211  attrib->_stencil_render_states [SRS_front_stencil_pass_z_pass_operation] = front_stencil_pass_z_pass_operation;
212 
213  attrib->_stencil_render_states [SRS_reference] = reference;
214  attrib->_stencil_render_states [SRS_read_mask] = read_mask;
215  attrib->_stencil_render_states [SRS_write_mask] = write_mask;
216 
217  attrib->_stencil_render_states [SRS_back_comparison_function] = M_none;
218  attrib->_stencil_render_states [SRS_back_stencil_fail_operation] = SO_keep;
219  attrib->_stencil_render_states [SRS_back_stencil_pass_z_fail_operation] = SO_keep;
220  attrib->_stencil_render_states [SRS_back_stencil_pass_z_pass_operation] = SO_keep;
221 
222  attrib->_stencil_render_states [SRS_clear] = clear;
223  attrib->_stencil_render_states [SRS_clear_value] = clear_value;
224 
225  return return_new(attrib);
226 }
227 
228 ////////////////////////////////////////////////////////////////////
229 // Function: StencilAttrib::make_2_sided
230 // Access: Published, Static
231 // Description: Constructs a two-sided StencilAttrib.
232 ////////////////////////////////////////////////////////////////////
234 make_2_sided_with_clear(
235  bool front_enable,
236  bool back_enable,
237  PandaCompareFunc front_comparison_function,
238  StencilOperation stencil_fail_operation,
239  StencilOperation stencil_pass_z_fail_operation,
240  StencilOperation front_stencil_pass_z_pass_operation,
241  unsigned int reference,
242  unsigned int read_mask,
243  unsigned int write_mask,
244  PandaCompareFunc back_comparison_function,
245  StencilOperation back_stencil_fail_operation,
246  StencilOperation back_stencil_pass_z_fail_operation,
247  StencilOperation back_stencil_pass_z_pass_operation,
248  bool clear,
249  unsigned int clear_value)
250 {
251  StencilAttrib *attrib = new StencilAttrib;
252 
253  if (!front_enable) {
254  front_comparison_function = M_none;
255  }
256 
257  if (!back_enable) {
258  back_comparison_function = M_none;
259  }
260 
261  attrib->_stencil_render_states [SRS_front_comparison_function] = front_comparison_function;
262  attrib->_stencil_render_states [SRS_front_stencil_fail_operation] = stencil_fail_operation;
263  attrib->_stencil_render_states [SRS_front_stencil_pass_z_fail_operation] = stencil_pass_z_fail_operation;
264  attrib->_stencil_render_states [SRS_front_stencil_pass_z_pass_operation] = front_stencil_pass_z_pass_operation;
265 
266  attrib->_stencil_render_states [SRS_reference] = reference;
267  attrib->_stencil_render_states [SRS_read_mask] = read_mask;
268  attrib->_stencil_render_states [SRS_write_mask] = write_mask;
269 
270  attrib->_stencil_render_states [SRS_back_comparison_function] = back_comparison_function;
271  attrib->_stencil_render_states [SRS_back_stencil_fail_operation] = back_stencil_fail_operation;
272  attrib->_stencil_render_states [SRS_back_stencil_pass_z_fail_operation] = back_stencil_pass_z_fail_operation;
273  attrib->_stencil_render_states [SRS_back_stencil_pass_z_pass_operation] = back_stencil_pass_z_pass_operation;
274 
275  attrib->_stencil_render_states [SRS_clear] = clear;
276  attrib->_stencil_render_states [SRS_clear_value] = clear_value;
277 
278  return return_new(attrib);
279 }
280 
281 ////////////////////////////////////////////////////////////////////
282 // Function: StencilAttrib::output
283 // Access: Public, Virtual
284 // Description:
285 ////////////////////////////////////////////////////////////////////
286 void StencilAttrib::
287 output(ostream &out) const {
288 
289  int index;
290  for (index = 0; index < SRS_total; index++) {
291  out
292  << "(" << stencil_render_state_name_array [index]
293  << ", " << _stencil_render_states [index] << ")";
294  }
295 }
296 
297 ////////////////////////////////////////////////////////////////////
298 // Function: StencilAttrib::compare_to_impl
299 // Access: Protected, Virtual
300 // Description: Intended to be overridden by derived StencilAttrib
301 // types to return a unique number indicating whether
302 // this StencilAttrib is equivalent to the other one.
303 //
304 // This should return 0 if the two StencilAttrib objects
305 // are equivalent, a number less than zero if this one
306 // should be sorted before the other one, and a number
307 // greater than zero otherwise.
308 //
309 // This will only be called with two StencilAttrib
310 // objects whose get_type() functions return the same.
311 ////////////////////////////////////////////////////////////////////
312 int StencilAttrib::
313 compare_to_impl(const RenderAttrib *other) const {
314  const StencilAttrib *sa;
315  DCAST_INTO_R(sa, other, 0);
316 
317  int a;
318  int b;
319  int index;
320  int compare_result = 0;
321 
322  for (index = 0; index < SRS_total; ++index) {
323  a = (int) sa -> _stencil_render_states[index];
324  b = (int) _stencil_render_states[index];
325  compare_result = (a - b);
326  if (compare_result) {
327  break;
328  }
329  }
330 
331  return compare_result;
332 }
333 
334 ////////////////////////////////////////////////////////////////////
335 // Function: StencilAttrib::get_hash_impl
336 // Access: Protected, Virtual
337 // Description: Intended to be overridden by derived RenderAttrib
338 // types to return a unique hash for these particular
339 // properties. RenderAttribs that compare the same with
340 // compare_to_impl(), above, should return the same
341 // hash; RenderAttribs that compare differently should
342 // return a different hash.
343 ////////////////////////////////////////////////////////////////////
344 size_t StencilAttrib::
345 get_hash_impl() const {
346  size_t hash = 0;
347  for (int index = 0; index < SRS_total; index++) {
348  hash = int_hash::add_hash(hash, (int)_stencil_render_states[index]);
349  }
350  return hash;
351 }
352 
353 ////////////////////////////////////////////////////////////////////
354 // Function: StencilAttrib::register_with_read_factory
355 // Access: Public, Static
356 // Description: Tells the BamReader how to create objects of type
357 // StencilAttrib.
358 ////////////////////////////////////////////////////////////////////
359 void StencilAttrib::
361  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
362 }
363 
364 ////////////////////////////////////////////////////////////////////
365 // Function: StencilAttrib::write_datagram
366 // Access: Public, Virtual
367 // Description: Writes the contents of this object to the datagram
368 // for shipping out to a Bam file.
369 ////////////////////////////////////////////////////////////////////
370 void StencilAttrib::
372  RenderAttrib::write_datagram(manager, dg);
373 
374  for (int index = 0; index < SRS_total; ++index) {
375  dg.add_uint32(_stencil_render_states[index]);
376  }
377 }
378 
379 ////////////////////////////////////////////////////////////////////
380 // Function: StencilAttrib::make_from_bam
381 // Access: Protected, Static
382 // Description: This function is called by the BamReader's factory
383 // when a new object of type StencilAttrib is encountered
384 // in the Bam file. It should create the StencilAttrib
385 // and extract its information from the file.
386 ////////////////////////////////////////////////////////////////////
387 TypedWritable *StencilAttrib::
388 make_from_bam(const FactoryParams &params) {
389  StencilAttrib *attrib = new StencilAttrib;
390  DatagramIterator scan;
391  BamReader *manager;
392 
393  parse_params(params, scan, manager);
394  attrib->fillin(scan, manager);
395 
396  return attrib;
397 }
398 
399 ////////////////////////////////////////////////////////////////////
400 // Function: StencilAttrib::fillin
401 // Access: Protected
402 // Description: This internal function is called by make_from_bam to
403 // read in all of the relevant data from the BamFile for
404 // the new StencilAttrib.
405 ////////////////////////////////////////////////////////////////////
406 void StencilAttrib::
407 fillin(DatagramIterator &scan, BamReader *manager) {
408  RenderAttrib::fillin(scan, manager);
409 
410  if (manager->get_file_minor_ver() < 35) {
411  unsigned int front_enable, back_enable;
412  front_enable = scan.get_int32();
413  back_enable = scan.get_int32();
414 
415  for (int index = 0; index < SRS_total; ++index) {
416  _stencil_render_states[index] = scan.get_int32();
417  }
418 
419  if (front_enable) {
420  _stencil_render_states[SRS_front_comparison_function]++;
421  } else {
422  _stencil_render_states[SRS_front_comparison_function] = M_none;
423  }
424 
425  if (back_enable) {
426  _stencil_render_states[SRS_back_comparison_function]++;
427  } else {
428  _stencil_render_states[SRS_back_comparison_function] = M_none;
429  }
430  } else {
431  for (int index = 0; index < SRS_total; ++index) {
432  _stencil_render_states[index] = scan.get_uint32();
433  }
434  }
435 }
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
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
PN_int32 get_int32()
Extracts a signed 32-bit integer.
PN_uint32 get_uint32()
Extracts an unsigned 32-bit integer.
static void register_with_read_factory()
Tells the BamReader how to create objects of type StencilAttrib.
static size_t add_hash(size_t start, const Key &key)
Adds the indicated key into a running hash.
Definition: stl_compares.I:122
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
A StencilAttrib is a collection of all stencil render states.
Definition: stencilAttrib.h:32
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
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
void add_uint32(PN_uint32 value)
Adds an unsigned 32-bit integer to the datagram.
Definition: datagram.I:192
A class to retrieve the individual data elements previously stored in a Datagram. ...
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
Definition: bamReader.I:105
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
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.