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  */
328 void StencilAttrib::
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  */
337 void StencilAttrib::
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 }
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:51
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being written.
Definition: bamWriter.I:59
CPT(RenderAttrib) StencilAttrib
Constructs a StencilAttrib that has stenciling turned off.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
int32_t get_int32()
Extracts a signed 32-bit integer.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static void register_with_read_factory()
Tells the BamReader how to create objects of type StencilAttrib.
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
Definition: bamReader.I:83
void add_uint32(uint32_t value)
Adds an unsigned 32-bit integer to the datagram.
Definition: datagram.I:94
static size_t add_hash(size_t start, const Key &key)
Adds the indicated key into a running hash.
Definition: stl_compares.I:101
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
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
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
uint32_t get_uint32()
Extracts an unsigned 32-bit integer.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_int32(int32_t value)
Adds a signed 32-bit integer to the datagram.
Definition: datagram.I:67
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
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:81
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.