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