Panda3D
 All Classes Functions Variables Enumerations
frameBufferProperties.cxx
1 // Filename: frameBufferProperties.cxx
2 // Created by: drose (27Jan03)
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 "frameBufferProperties.h"
16 #include "string_utils.h"
17 #include "renderBuffer.h"
18 #include "config_display.h"
19 #include "texture.h"
20 
21 ////////////////////////////////////////////////////////////////////
22 // Function: FrameBufferProperties::Constructor
23 // Access: Published
24 // Description:
25 ////////////////////////////////////////////////////////////////////
26 FrameBufferProperties::
27 FrameBufferProperties() {
28  clear();
29 }
30 
31 ////////////////////////////////////////////////////////////////////
32 // Function: FrameBufferProperties::Copy Assignment Operator
33 // Access: Published
34 // Description:
35 ////////////////////////////////////////////////////////////////////
36 void FrameBufferProperties::
37 operator = (const FrameBufferProperties &copy) {
38  _flags_specified = copy._flags_specified;
39  _flags = copy._flags;
40  _specified = copy._specified;
41 
42  for (int i = 0; i < FBP_COUNT; ++i) {
43  _property[i] = copy._property[i];
44  }
45 }
46 
47 ////////////////////////////////////////////////////////////////////
48 // Function: FrameBufferProperties::subsumes
49 // Access: Public
50 // Description: Returns true if this set of properties makes
51 // strictly greater or equal demands of the framebuffer
52 // than the other set of framebuffer properties.
53 ////////////////////////////////////////////////////////////////////
55 subsumes(const FrameBufferProperties &other) const {
56  if (((other._flags & other._flags_specified) & ~(_flags & _flags_specified)) != 0) {
57  // The other has bits enabled that we don't have enabled.
58  return false;
59  }
60 
61  for (int i = 0; i < FBP_COUNT; ++i) {
62  if (other._property[i] > _property[i]) {
63  return false;
64  }
65  }
66 
67  return true;
68 }
69 
70 ////////////////////////////////////////////////////////////////////
71 // Function: FrameBufferProperties::get_default
72 // Access: Published, Static
73 // Description: Returns a FrameBufferProperties structure with all of
74 // the default values filled in according to the user's
75 // config file.
76 ////////////////////////////////////////////////////////////////////
79  static bool default_ready = false;
80  static FrameBufferProperties default_props;
81 
82  if (default_ready) {
83  return default_props;
84  }
85 
86  default_props.set_rgb_color(true);
87  default_props.set_back_buffers(back_buffers);
88 
89  int num_words = framebuffer_mode.get_num_words();
90  if (num_words > 0) {
91  display_cat.error()
92  << "The config-variable 'framebuffer-mode' no longer functions.\n";
93  display_cat.error()
94  << "Instead, use one or more of these:\n";
95  display_cat.error() << " framebuffer-hardware #t\n";
96  display_cat.error() << " framebuffer-software #t\n";
97  display_cat.error() << " framebuffer-depth #t\n";
98  display_cat.error() << " framebuffer-alpha #t\n";
99  display_cat.error() << " framebuffer-stencil #t\n";
100  display_cat.error() << " framebuffer-multisample #t\n";
101  display_cat.error() << " framebuffer-stereo #t\n";
102  display_cat.error() << " depth-bits N\n";
103  display_cat.error() << " color-bits N\n";
104  display_cat.error() << " red-bits N\n";
105  display_cat.error() << " green-bits N\n";
106  display_cat.error() << " blue-bits N\n";
107  display_cat.error() << " alpha-bits N\n";
108  display_cat.error() << " stencil-bits N\n";
109  display_cat.error() << " multisamples N\n";
110  display_cat.error() << " coverage-samples N\n";
111  display_cat.error() << " back-buffers N\n";
112  }
113 
114  if (framebuffer_hardware) {
115  default_props.set_force_hardware(true);
116  }
117  if (framebuffer_software) {
118  default_props.set_force_software(true);
119  }
120  if (framebuffer_depth) {
121  default_props.set_depth_bits(1);
122  }
123  if (framebuffer_alpha) {
124  default_props.set_alpha_bits(1);
125  }
126  if (framebuffer_stencil) {
127  default_props.set_stencil_bits(1);
128  }
129  if (framebuffer_accum) {
130  default_props.set_accum_bits(1);
131  }
132  if (framebuffer_multisample) {
133  default_props.set_multisamples(1);
134  }
135  if (framebuffer_stereo) {
136  default_props.set_stereo(true);
137  }
138  if (framebuffer_srgb) {
139  default_props.set_srgb_color(true);
140  }
141  if (framebuffer_float) {
142  default_props.set_float_color(true);
143  }
144  if (depth_bits > 0) {
145  default_props.set_depth_bits(depth_bits);
146  }
147  switch (color_bits.size()) {
148  case 0:
149  break;
150  case 1:
151  default_props.set_color_bits(color_bits[0]);
152  break;
153  case 3:
154  default_props.set_color_bits(color_bits[0] + color_bits[1] + color_bits[2]);
155  default_props.set_red_bits(color_bits[0]);
156  default_props.set_green_bits(color_bits[1]);
157  default_props.set_blue_bits(color_bits[2]);
158  break;
159  default:
160  default_props.set_color_bits(color_bits[0]);
161  display_cat.error()
162  << "Configuration variable color-bits takes either 1 or 3 values, not "
163  << color_bits.size() << "\n";
164  break;
165  }
166  if (alpha_bits > 0) {
167  default_props.set_alpha_bits(alpha_bits);
168  }
169  if (stencil_bits > 0) {
170  default_props.set_stencil_bits(stencil_bits);
171  }
172  if (accum_bits > 0) {
173  default_props.set_accum_bits(accum_bits);
174  }
175  if (multisamples > 0) {
176  default_props.set_multisamples(multisamples);
177  }
178 
179  if ((default_props._flags & FBF_force_software) != 0 &&
180  (default_props._flags & FBF_force_hardware) != 0){
181  default_props._flags &= ~(FBF_force_software | FBF_force_hardware);
182  }
183 
184  default_ready = true;
185  return default_props;
186 }
187 
188 ////////////////////////////////////////////////////////////////////
189 // Function: FrameBufferProperties::operator ==
190 // Access: Published
191 // Description:
192 ////////////////////////////////////////////////////////////////////
193 bool FrameBufferProperties::
194 operator == (const FrameBufferProperties &other) const {
195  if ((_flags & _flags_specified) != (other._flags & other._flags_specified)) {
196  return false;
197  }
198 
199  if (_specified != other._specified) {
200  return false;
201  }
202 
203  for (int i = 0; i < FBP_COUNT; ++i) {
204  if (_property[i] != other._property[i]) {
205  return false;
206  }
207  }
208 
209  return true;
210 }
211 
212 ////////////////////////////////////////////////////////////////////
213 // Function: FrameBufferProperties::clear
214 // Access: Published
215 // Description: Unsets all properties that have been specified so
216 // far, and resets the FrameBufferProperties structure to its
217 // initial empty state.
218 ////////////////////////////////////////////////////////////////////
220 clear() {
221  _flags = 0;
222  _flags_specified = 0;
223 
224  for (int i = 0; i < FBP_COUNT; ++i) {
225  _property[i] = 0;
226  }
227  _specified = 0;
228 }
229 
230 ////////////////////////////////////////////////////////////////////
231 // Function: FrameBufferProperties::add_properties
232 // Access: Published
233 // Description: Sets any properties that are explicitly specified in
234 // other on this object. Leaves other properties
235 // unchanged.
236 ////////////////////////////////////////////////////////////////////
239  _flags &= ~other._flags_specified;
240  _flags |= other._flags & other._flags_specified;
241 
242  for (int i = 0; i < FBP_COUNT; ++i) {
243  if (other._specified & (1 << i)) {
244  _property[i] = other._property[i];
245  _specified |= (1 << i);
246  }
247  }
248 }
249 
250 ////////////////////////////////////////////////////////////////////
251 // Function: FrameBufferProperties::output
252 // Access: Published
253 // Description: Generates a string representation.
254 ////////////////////////////////////////////////////////////////////
256 output(ostream &out) const {
257  if ((_flags & FBF_float_depth) != 0) {
258  out << "float_depth ";
259  }
260  if (_property[FBP_depth_bits] > 0) {
261  out << "depth_bits=" << _property[FBP_depth_bits] << " ";
262  }
263  if ((_flags & FBF_float_color) != 0) {
264  out << "float_color ";
265  }
266  if ((_flags & FBF_srgb_color) != 0) {
267  out << "srgb_color ";
268  }
269  if ((_flags & FBF_indexed_color) != 0) {
270  out << "indexed_color ";
271  }
272  if (_property[FBP_color_bits] > 0) {
273  out << "color_bits=" << _property[FBP_color_bits] << " ";
274  }
275  if (_property[FBP_red_bits] > 0) {
276  out << "red_bits=" << _property[FBP_red_bits] << " ";
277  }
278  if (_property[FBP_green_bits] > 0) {
279  out << "green_bits=" << _property[FBP_green_bits] << " ";
280  }
281  if (_property[FBP_blue_bits] > 0) {
282  out << "blue_bits=" << _property[FBP_blue_bits] << " ";
283  }
284  if (_property[FBP_alpha_bits] > 0) {
285  out << "alpha_bits=" << _property[FBP_alpha_bits] << " ";
286  }
287  if (_property[FBP_stencil_bits] > 0) {
288  out << "stencil_bits=" << _property[FBP_stencil_bits] << " ";
289  }
290  if (_property[FBP_accum_bits] > 0) {
291  out << "accum_bits=" << _property[FBP_accum_bits] << " ";
292  }
293  if (_property[FBP_aux_rgba] > 0) {
294  out << "aux_rgba=" << _property[FBP_aux_rgba] << " ";
295  }
296  if (_property[FBP_aux_hrgba] > 0) {
297  out << "aux_hrgba=" << _property[FBP_aux_hrgba] << " ";
298  }
299  if (_property[FBP_aux_float] > 0) {
300  out << "aux_float=" << _property[FBP_aux_float] << " ";
301  }
302  if (_property[FBP_multisamples] > 0) {
303  out << "multisamples=" << _property[FBP_multisamples] << " ";
304  }
305  if (_property[FBP_coverage_samples] > 0) {
306  out << "coverage_samples=" << _property[FBP_coverage_samples] << " ";
307  }
308  if (_property[FBP_back_buffers] > 0) {
309  out << "back_buffers=" << _property[FBP_back_buffers] << " ";
310  }
311  if ((_flags & FBF_stereo) != 0) {
312  out << "stereo ";
313  }
314  if ((_flags & FBF_force_hardware) != 0) {
315  out << "force_hardware ";
316  }
317  if ((_flags & FBF_force_software) != 0) {
318  out << "force_software ";
319  }
320 }
321 
322 ////////////////////////////////////////////////////////////////////
323 // Function: FrameBufferProperties::get_aux_mask
324 // Access: Published
325 // Description: Converts the aux bitplanes of the
326 // framebuffer into a RenderBuffer::Type.
327 ////////////////////////////////////////////////////////////////////
329 get_aux_mask() const {
330  int mask = 0;
331  for (int i=0; i<_property[FBP_aux_rgba]; i++) {
332  mask |= (RenderBuffer::T_aux_rgba_0 << i);
333  }
334  for (int i=0; i<_property[FBP_aux_hrgba]; i++) {
335  mask |= (RenderBuffer::T_aux_hrgba_0 << i);
336  }
337  for (int i=0; i<_property[FBP_aux_float]; i++) {
338  mask |= (RenderBuffer::T_aux_float_0 << i);
339  }
340  return mask;
341 }
342 
343 ////////////////////////////////////////////////////////////////////
344 // Function: FrameBufferProperties::get_buffer_mask
345 // Access: Private
346 // Description: Converts the non-aux bitplanes of the
347 // framebuffer into a RenderBuffer::Type.
348 ////////////////////////////////////////////////////////////////////
351  int mask = 0;
352 
353  if (_property[FBP_back_buffers] > 0) {
354  mask = RenderBuffer::T_front | RenderBuffer::T_back;
355  } else {
356  mask = RenderBuffer::T_front;
357  }
358  if (_property[FBP_depth_bits] > 0) {
359  mask |= RenderBuffer::T_depth;
360  }
361  if (_property[FBP_stencil_bits] > 0) {
362  mask |= RenderBuffer::T_stencil;
363  }
364  return mask;
365 }
366 
367 ////////////////////////////////////////////////////////////////////
368 // Function: FrameBufferProperties::is_any_specified
369 // Access: Published
370 // Description: Returns true if any properties have been specified,
371 // false otherwise.
372 ////////////////////////////////////////////////////////////////////
375  return (_flags_specified | _specified) != 0;
376 }
377 
378 ////////////////////////////////////////////////////////////////////
379 // Function: FrameBufferProperties::set_all_specified
380 // Access: Published
381 // Description: Marks all bits as having been specified.
382 ////////////////////////////////////////////////////////////////////
385  _flags_specified = FBF_all;
386  _specified = (1 << FBP_COUNT) - 1;
387 }
388 
389 ////////////////////////////////////////////////////////////////////
390 // Function: FrameBufferProperties::is_basic
391 // Access: Published
392 // Description: Returns true if the properties are extremely basic.
393 // The following count as basic: rgb or rgba, depth.
394 // If anything else is specified, the properties are
395 // non-basic.
396 ////////////////////////////////////////////////////////////////////
398 is_basic() const {
399  if (_property[FBP_depth_bits] > 1) {
400  return false;
401  }
402  if (_property[FBP_color_bits] > 1) {
403  return false;
404  }
405  if (_property[FBP_red_bits] > 1) {
406  return false;
407  }
408  if (_property[FBP_green_bits] > 1) {
409  return false;
410  }
411  if (_property[FBP_blue_bits] > 1) {
412  return false;
413  }
414  if (_property[FBP_alpha_bits] > 1) {
415  return false;
416  }
417  if (_property[FBP_stencil_bits] > 0) {
418  return false;
419  }
420  if (_property[FBP_aux_rgba] > 0) {
421  return false;
422  }
423  if (_property[FBP_aux_hrgba] > 0) {
424  return false;
425  }
426  if (_property[FBP_aux_float] > 0) {
427  return false;
428  }
429  if (_property[FBP_multisamples] > 1) {
430  return false;
431  }
432  if (_property[FBP_coverage_samples] > 0) {
433  return false;
434  }
435  if (_property[FBP_back_buffers] > 0) {
436  return false;
437  }
438  if ((_flags & FBF_indexed_color) != 0) {
439  return false;
440  }
441  if ((_flags & FBF_force_hardware) != 0) {
442  return false;
443  }
444  if ((_flags & FBF_force_software) != 0) {
445  return false;
446  }
447  if ((_flags & FBF_srgb_color) != 0) {
448  return false;
449  }
450  if ((_flags & FBF_float_color) != 0) {
451  return false;
452  }
453  if ((_flags & FBF_float_depth) != 0) {
454  return false;
455  }
456  return true;
457 }
458 
459 ////////////////////////////////////////////////////////////////////
460 // Function: FrameBufferProperties::set_one_bit_per_channel
461 // Access: Published
462 // Description: If any of the depth, color, alpha, accum, or
463 // stencil properties is set to more than one,
464 // then they are reduced to one.
465 ////////////////////////////////////////////////////////////////////
468  for (int prop = FBP_depth_bits; prop <= FBP_accum_bits; ++prop) {
469  if (_property[prop] > 1) {
470  _property[prop] = 1;
471  }
472  }
473 }
474 
475 ////////////////////////////////////////////////////////////////////
476 // Function: FrameBufferProperties::get_quality
477 // Access: Published
478 // Description: Assumes that these properties are a description of
479 // a window.
480 //
481 // Measures how well this window satisfies a specified
482 // set of requirements. A higher quality number means
483 // that more requirements were satisfied. A quality of
484 // zero means that the window is unsuitable.
485 //
486 // The routine deducts a lot if the window fails to
487 // provide a requested feature. It deducts less
488 // if the window provides a feature, but at a degraded
489 // level of functionality (ie, the user asks for rgba8,
490 // color, but the window only provides rgba4). The
491 // routine also deducts a small amount for unnecessary
492 // features. For example, if the window has an
493 // accumulation buffer when one is not requested will
494 // reduce quality slightly. Maximum quality is obtained
495 // when the window exactly matches the request.
496 //
497 // If you want to know whether the window satisfies
498 // all of the requirements, use the "subsumes" function.
499 ////////////////////////////////////////////////////////////////////
501 get_quality(const FrameBufferProperties &reqs) const {
502 
503  if (!get_indexed_color() && !get_rgb_color()) {
504  // Nonfunctioning window.
505  return 0;
506  }
507 
508  if ((reqs.get_rgb_color() && !get_rgb_color()) ||
509  (reqs.get_indexed_color() && !get_indexed_color())) {
510  // These properties are nonnegotiable.
511  return 0;
512  }
513 
514  int quality = 100000000;
515 
516  // Deduct for using the wrong kind of renderer (hardware or software).
517  // Cost: 10,000,000
518 
519  if ((reqs._flags & FBF_force_hardware) > (_flags & FBF_force_hardware) ||
520  (reqs._flags & FBF_force_software) > (_flags & FBF_force_software)) {
521  quality -= 10000000;
522  }
523 
524  // Deduct for missing depth, color, alpha, stencil, or accum.
525  // Cost: 1,000,000
526 
527  for (int prop = FBP_depth_bits; prop <= FBP_accum_bits; ++prop) {
528  if (reqs._property[prop] && _property[prop] == 0) {
529  quality -= 1000000;
530  }
531  }
532 
533  // Deduct for missing aux bitplanes.
534  // Cost: 100,000
535 
536  for (int prop = FBP_aux_rgba; prop <= FBP_aux_float; ++prop) {
537  if (reqs._property[prop] > _property[prop]) {
538  quality -= 100000;
539  }
540  }
541 
542  // Deduct for stereo not enabled.
543  // Cost: 100,000
544 
545  if (reqs.get_stereo() && !get_stereo()) {
546  quality -= 100000;
547  }
548 
549  // Deduct for not being sRGB-capable.
550  // Cost: 100,000
551 
552  if (reqs.get_srgb_color() && !get_srgb_color()) {
553  quality -= 100000;
554  }
555 
556  // Deduct for not having a floating-point format if we requested it.
557  // Cost: 100,000
558 
559  if (reqs.get_float_color() && !get_float_color()) {
560  quality -= 100000;
561  }
562 
563  if (reqs.get_float_depth() && !get_float_depth()) {
564  quality -= 100000;
565  }
566 
567  // Deduct for insufficient back-buffers.
568  // Cost: 100,000
569 
570  if (reqs._property[FBP_back_buffers] > _property[FBP_back_buffers]) {
571  quality -= 100000;
572  }
573 
574  // Deduct for lacking multisamples altogether.
575  // Cost: 100,000
576  if (reqs._property[FBP_multisamples] != 0 && _property[FBP_multisamples] == 0) {
577  quality -= 100000;
578  }
579 
580  // Deduct for not enough bits in depth, color, alpha, stencil, or accum.
581  // Cost: 10,000
582 
583  for (int prop = FBP_depth_bits; prop <= FBP_accum_bits; ++prop) {
584  if (_property[prop] != 0 && reqs._property[prop] > _property[prop]) {
585  quality -= 10000;
586  }
587  }
588 
589  // deduct for insufficient multisamples.
590  // Cost: 1,000
591 
592  if (_property[FBP_multisamples] != 0 &&
593  reqs._property[FBP_multisamples] > _property[FBP_multisamples]) {
594  quality -= 1000;
595  }
596 
597  // Deduct for unrequested bitplanes.
598  // Cost: 50
599 
600  for (int prop = FBP_depth_bits; prop <= FBP_accum_bits; ++prop) {
601  if ((_property[prop]) && (reqs._property[prop] == 0)) {
602  quality -= 50;
603  }
604  }
605  for (int prop = FBP_aux_rgba; prop <= FBP_aux_float; ++prop) {
606  int extra = _property[prop] > reqs._property[prop];
607  if (extra > 0) {
608  extra = min(extra, 3);
609  quality -= extra*50;
610  }
611  }
612 
613  // Deduct for excessive resolution in any bitplane (unless we asked
614  // for only 1 bit, which is the convention for any amount).
615 
616  // Cost: 50
617 
618  for (int prop = FBP_depth_bits; prop <= FBP_accum_bits; ++prop) {
619  if (reqs._property[prop] > 1 &&
620  _property[prop] > reqs._property[prop]) {
621  quality -= 50;
622  }
623  }
624 
625  // Bonus for each depth bit.
626  // Extra: 2 per bit.
627  if (reqs._property[FBP_depth_bits] != 0) {
628  quality += 2 * _property[FBP_depth_bits];
629  }
630 
631  // Bonus for each multisample.
632  // Extra: 2 per sample.
633  if (reqs._property[FBP_multisamples] != 0) {
634  quality += 2 * _property[FBP_multisamples];
635  }
636 
637  // Bonus for each coverage sample.
638  // Extra: 2 per sample.
639  if (reqs._property[FBP_coverage_samples] != 0) {
640  quality += 2 * _property[FBP_coverage_samples];
641  }
642 
643  // Bonus for each color, alpha, stencil, and accum.
644  // Extra: 1 per bit.
645  for (int prop=FBP_color_bits; prop<=FBP_accum_bits; prop++) {
646  if (reqs._property[prop] != 0) {
647  quality += _property[prop];
648  }
649  }
650 
651  return quality;
652 }
653 
654 ////////////////////////////////////////////////////////////////////
655 // Function: FrameBufferProperties::verify_hardware_software
656 // Access: Public
657 // Description: Validates that the properties represent the desired
658 // kind of renderer (hardware or software). If not,
659 // prints out an error message and returns false.
660 ////////////////////////////////////////////////////////////////////
662 verify_hardware_software(const FrameBufferProperties &props, const string &renderer) const {
663 
664  if (get_force_hardware() < props.get_force_hardware()) {
665  display_cat.error()
666  << "The application requested harware acceleration, but your OpenGL\n";
667  display_cat.error()
668  << "driver, " << renderer << ", only supports software rendering.\n";
669  display_cat.error()
670  << "You need to install a hardware-accelerated OpenGL driver, or,\n";
671  display_cat.error()
672  << "if you actually *want* to use a software renderer, then\n";
673  display_cat.error()
674  << "alter the hardware/software configuration in your Config.prc file.\n";
675  return false;
676  }
677 
678  if (get_force_software() < props.get_force_software()) {
679  display_cat.error()
680  << "The application requested a software renderer, but your OpenGL\n";
681  display_cat.error()
682  << "driver, " << renderer << ", is probably hardware-accelerated.\n";
683  display_cat.error()
684  << "If you want to allow hardware acceleration, then alter the\n";
685  display_cat.error()
686  << "hardware/software configuration in your Config.prc file.\n";
687  return false;
688  }
689 
690  return true;
691 }
692 
693 ////////////////////////////////////////////////////////////////////
694 // Function: FrameBufferProperties::setup_color_texture
695 // Access: Public
696 // Description: Sets the texture up for render-to-texture matching
697 // these framebuffer properties.
698 //
699 // Returns true if there was a format that had enough
700 // bits, false otherwise. Of course, this is no
701 // guarantee that a particular graphics back-end
702 // supports rendering to textures of that format.
703 ////////////////////////////////////////////////////////////////////
706  // Note by rdb: I'm not entirely happy about this system. I'd
707  // eventually like to move to a system in which framebuffer color
708  // formats and texture formats are unified (like in Direct3D and
709  // OpenGL) and where a table such as the below one would be
710  // generated dynamically by the GSG to reflect the formats that
711  // are supported for render-to-texture.
712 
713  static const int num_formats = 12;
714  static const struct {
715  unsigned char color_bits, red_bits, green_bits, blue_bits, alpha_bits;
716  bool has_float;
717  Texture::Format format;
718  } formats[num_formats] = {
719  //{ 1, 1, 0, 0, 0, F_red},
720  { 1, 1, 1, 1, 0, false, Texture::F_rgb },
721  { 1, 1, 1, 1, 1, false, Texture::F_rgba },
722  { 24, 8, 8, 8, 0, false, Texture::F_rgb8 },
723  { 24, 8, 8, 8, 8, false, Texture::F_rgba8 },
724  { 16, 16, 0, 0, 0, true, Texture::F_r16 },
725  { 32, 16, 16, 0, 0, true, Texture::F_rg16 },
726  { 48, 16, 16, 16, 0, true, Texture::F_rgb16 },
727  { 48, 16, 16, 16, 16, true, Texture::F_rgba16 },
728  { 32, 32, 0, 0, 0, true, Texture::F_r32 },
729  { 64, 32, 32, 0, 0, true, Texture::F_rg32 },
730  { 96, 32, 32, 32, 0, true, Texture::F_rgb32 },
731  { 96, 32, 32, 32, 32, true, Texture::F_rgba32 },
732  };
733 
734  if (get_srgb_color()) {
735  // These are the only sRGB formats. Deal with it.
736  if (get_alpha_bits() == 0) {
737  tex->set_format(Texture::F_srgb);
738  } else {
739  tex->set_format(Texture::F_srgb_alpha);
740  }
741 
742  return (get_color_bits() <= 24 &&
743  get_red_bits() <= 8 &&
744  get_green_bits() <= 8 &&
745  get_blue_bits() <= 8 &&
746  get_alpha_bits() <= 8);
747 
748  } else {
749  if (get_float_color()) {
750  tex->set_component_type(Texture::T_float);
751  }
752 
753  for (int i = 0; i < num_formats; ++i) {
754  if (get_color_bits() <= (int)formats[i].color_bits &&
755  get_red_bits() <= (int)formats[i].red_bits &&
756  get_green_bits() <= (int)formats[i].green_bits &&
757  get_blue_bits() <= (int)formats[i].blue_bits &&
758  get_alpha_bits() <= (int)formats[i].alpha_bits &&
759  get_float_color() <= formats[i].has_float) {
760 
761  tex->set_format(formats[i].format);
762  return true;
763  }
764  }
765 
766  // Can't get requested bits. Choose a generic format and return.
767  tex->set_format((get_alpha_bits() == 0) ? Texture::F_rgb : Texture::F_rgba);
768  return false;
769  }
770 }
771 
772 ////////////////////////////////////////////////////////////////////
773 // Function: FrameBufferProperties::setup_depth_texture
774 // Access: Public
775 // Description: Sets the texture up for render-to-texture matching
776 // these framebuffer properties.
777 //
778 // Returns true if there was a format that had enough
779 // bits, false otherwise. Of course, this is no
780 // guarantee that a particular graphics back-end
781 // supports rendering to textures of that format.
782 ////////////////////////////////////////////////////////////////////
785  if (get_float_depth()) {
786  tex->set_component_type(Texture::T_float);
787  tex->set_format(Texture::F_depth_component32);
788  return (get_depth_bits() <= 32);
789 
790  } else if (get_depth_bits() <= 1) {
791  tex->set_format(Texture::F_depth_component);
792  return true;
793 
794  } else if (get_depth_bits() <= 16) {
795  tex->set_format(Texture::F_depth_component16);
796  return true;
797 
798  } else if (get_depth_bits() <= 24) {
799  tex->set_format(Texture::F_depth_component24);
800  return true;
801 
802  } else if (get_depth_bits() <= 32) {
803  tex->set_format(Texture::F_depth_component32);
804  return true;
805  }
806 
807  tex->set_format(Texture::F_depth_component);
808  return false;
809 }
static const FrameBufferProperties & get_default()
Returns a FrameBufferProperties structure with all of the default values filled in according to the u...
int size() const
Returns the number of unique words in the variable.
void set_all_specified()
Marks all bits as having been specified.
void clear()
Unsets all properties that have been specified so far, and resets the FrameBufferProperties structure...
int get_num_words() const
Returns the number of words in the variable&#39;s value.
void add_properties(const FrameBufferProperties &other)
Sets any properties that are explicitly specified in other on this object.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition: texture.h:75
void set_format(Format format)
Changes the format value for the texture components.
Definition: texture.I:2440
int get_aux_mask() const
Converts the aux bitplanes of the framebuffer into a RenderBuffer::Type.
int get_buffer_mask() const
Converts the non-aux bitplanes of the framebuffer into a RenderBuffer::Type.
bool subsumes(const FrameBufferProperties &other) const
Returns true if this set of properties makes strictly greater or equal demands of the framebuffer tha...
bool verify_hardware_software(const FrameBufferProperties &props, const string &renderer) const
Validates that the properties represent the desired kind of renderer (hardware or software)...
bool setup_color_texture(Texture *tex) const
Sets the texture up for render-to-texture matching these framebuffer properties.
int get_quality(const FrameBufferProperties &reqs) const
Assumes that these properties are a description of a window.
bool setup_depth_texture(Texture *tex) const
Sets the texture up for render-to-texture matching these framebuffer properties.
bool is_any_specified() const
Returns true if any properties have been specified, false otherwise.
void set_one_bit_per_channel()
If any of the depth, color, alpha, accum, or stencil properties is set to more than one...
void set_component_type(ComponentType component_type)
Changes the data value for the texture components.
Definition: texture.I:2452
void output(ostream &out) const
Generates a string representation.
void set_color_bits(int n)
Sets the number of requested color bits as a single number that represents the sum of the individual ...
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
bool is_basic() const
Returns true if the properties are extremely basic.