00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "frameBufferProperties.h"
00016 #include "string_utils.h"
00017 #include "renderBuffer.h"
00018 #include "config_display.h"
00019
00020
00021
00022
00023
00024
00025 FrameBufferProperties::
00026 FrameBufferProperties() {
00027 clear();
00028 }
00029
00030
00031
00032
00033
00034
00035 void FrameBufferProperties::
00036 operator = (const FrameBufferProperties ©) {
00037 for (int i=0; i<FBP_COUNT; i++) {
00038 _specified[i] = copy._specified[i];
00039 _property[i] = copy._property[i];
00040 }
00041 }
00042
00043
00044
00045
00046
00047
00048
00049
00050 bool FrameBufferProperties::
00051 subsumes(const FrameBufferProperties &other) const {
00052 for (int i=0; i<FBP_COUNT; i++) {
00053 if (other._property[i] > _property[i]) {
00054 return false;
00055 }
00056 }
00057 return true;
00058 }
00059
00060
00061
00062
00063
00064
00065
00066
00067 const FrameBufferProperties &FrameBufferProperties::
00068 get_default() {
00069 static bool default_ready = false;
00070 static FrameBufferProperties default_props;
00071
00072 if (default_ready) {
00073 return default_props;
00074 }
00075
00076 default_props.set_rgb_color(1);
00077 default_props.set_back_buffers(back_buffers);
00078
00079 int num_words = framebuffer_mode.get_num_words();
00080 if (num_words > 0) {
00081 display_cat.error()
00082 << "The config-variable 'framebuffer-mode' no longer functions.\n";
00083 display_cat.error()
00084 << "Instead, use one or more of these:\n";
00085 display_cat.error() << " framebuffer-hardware #t\n";
00086 display_cat.error() << " framebuffer-software #t\n";
00087 display_cat.error() << " framebuffer-depth #t\n";
00088 display_cat.error() << " framebuffer-alpha #t\n";
00089 display_cat.error() << " framebuffer-stencil #t\n";
00090 display_cat.error() << " framebuffer-multisample #t\n";
00091 display_cat.error() << " framebuffer-stereo #t\n";
00092 display_cat.error() << " depth-bits N\n";
00093 display_cat.error() << " color-bits N\n";
00094 display_cat.error() << " alpha-bits N\n";
00095 display_cat.error() << " stencil-bits N\n";
00096 display_cat.error() << " multisamples N\n";
00097 display_cat.error() << " back-buffers N\n";
00098 }
00099
00100 if (framebuffer_hardware) {
00101 default_props.set_force_hardware(1);
00102 }
00103 if (framebuffer_software) {
00104 default_props.set_force_software(1);
00105 }
00106 if (framebuffer_depth) {
00107 default_props.set_depth_bits(1);
00108 }
00109 if (framebuffer_alpha) {
00110 default_props.set_alpha_bits(1);
00111 }
00112 if (framebuffer_stencil) {
00113 default_props.set_stencil_bits(1);
00114 }
00115 if (framebuffer_accum) {
00116 default_props.set_accum_bits(1);
00117 }
00118 if (framebuffer_multisample) {
00119 default_props.set_multisamples(1);
00120 }
00121 if (framebuffer_stereo) {
00122 default_props.set_stereo(1);
00123 }
00124 if (depth_bits > 0) {
00125 default_props.set_depth_bits(depth_bits);
00126 }
00127 if (color_bits > 0) {
00128 default_props.set_color_bits(color_bits);
00129 }
00130 if (alpha_bits > 0) {
00131 default_props.set_alpha_bits(alpha_bits);
00132 }
00133 if (stencil_bits > 0) {
00134 default_props.set_stencil_bits(stencil_bits);
00135 }
00136 if (accum_bits > 0) {
00137 default_props.set_accum_bits(accum_bits);
00138 }
00139 if (multisamples > 0) {
00140 default_props.set_multisamples(multisamples);
00141 }
00142
00143 if ((default_props._property[FBP_force_software])&&
00144 (default_props._property[FBP_force_hardware])) {
00145 default_props._property[FBP_force_software] = 0;
00146 default_props._property[FBP_force_hardware] = 0;
00147 }
00148
00149 default_ready = true;
00150 return default_props;
00151 }
00152
00153
00154
00155
00156
00157
00158 bool FrameBufferProperties::
00159 operator == (const FrameBufferProperties &other) const {
00160 for (int i=0; i<FBP_COUNT; i++) {
00161 if (_specified[i] != other._specified[i]) {
00162 return false;
00163 }
00164 if (_property[i] != other._property[i]) {
00165 return false;
00166 }
00167 }
00168 return true;
00169 }
00170
00171
00172
00173
00174
00175
00176
00177
00178 void FrameBufferProperties::
00179 clear() {
00180 for (int i=0; i<FBP_COUNT; i++) {
00181 _specified[i] = 0;
00182 _property[i] = 0;
00183 }
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193 void FrameBufferProperties::
00194 add_properties(const FrameBufferProperties &other) {
00195 for (int i=0; i<FBP_COUNT; i++) {
00196 if (other._specified[i]) {
00197 _property[i] = other._property[i];
00198 _specified[i] = true;
00199 }
00200 }
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210 void FrameBufferProperties::
00211 output(ostream &out) const {
00212 if (_property[FBP_depth_bits] > 0) {
00213 out << "depth_bits=" << _property[FBP_depth_bits] << " ";
00214 }
00215 if (_property[FBP_color_bits] > 0) {
00216 out << "color_bits=" << _property[FBP_color_bits] << " ";
00217 }
00218 if (_property[FBP_alpha_bits] > 0) {
00219 out << "alpha_bits=" << _property[FBP_alpha_bits] << " ";
00220 }
00221 if (_property[FBP_stencil_bits] > 0) {
00222 out << "stencil_bits=" << _property[FBP_stencil_bits] << " ";
00223 }
00224 if (_property[FBP_accum_bits] > 0) {
00225 out << "accum_bits=" << _property[FBP_accum_bits] << " ";
00226 }
00227 if (_property[FBP_aux_rgba] > 0) {
00228 out << "aux_rgba=" << _property[FBP_aux_rgba] << " ";
00229 }
00230 if (_property[FBP_aux_hrgba] > 0) {
00231 out << "aux_hrgba=" << _property[FBP_aux_hrgba] << " ";
00232 }
00233 if (_property[FBP_aux_float] > 0) {
00234 out << "aux_float=" << _property[FBP_aux_float] << " ";
00235 }
00236 if (_property[FBP_multisamples] > 0) {
00237 out << "multisamples=" << _property[FBP_multisamples] << " ";
00238 }
00239 if (_property[FBP_back_buffers] > 0) {
00240 out << "back_buffers=" << _property[FBP_back_buffers] << " ";
00241 }
00242 if (_property[FBP_indexed_color] > 0) {
00243 out << "indexed_color=" << _property[FBP_indexed_color] << " ";
00244 }
00245 if (_property[FBP_stereo] > 0) {
00246 out << "stereo=" << _property[FBP_stereo] << " ";
00247 }
00248 if (_property[FBP_force_hardware] > 0) {
00249 out << "force_hardware=" << _property[FBP_force_hardware] << " ";
00250 }
00251 if (_property[FBP_force_software] > 0) {
00252 out << "force_software=" << _property[FBP_force_software] << " ";
00253 }
00254 }
00255
00256
00257
00258
00259
00260
00261
00262 int FrameBufferProperties::
00263 get_aux_mask() const {
00264 int mask = 0;
00265 for (int i=0; i<_property[FBP_aux_rgba]; i++) {
00266 mask |= (RenderBuffer::T_aux_rgba_0 << i);
00267 }
00268 for (int i=0; i<_property[FBP_aux_hrgba]; i++) {
00269 mask |= (RenderBuffer::T_aux_hrgba_0 << i);
00270 }
00271 for (int i=0; i<_property[FBP_aux_float]; i++) {
00272 mask |= (RenderBuffer::T_aux_float_0 << i);
00273 }
00274 return mask;
00275 }
00276
00277
00278
00279
00280
00281
00282
00283 int FrameBufferProperties::
00284 get_buffer_mask() const {
00285 int mask = 0;
00286
00287 if (_property[FBP_back_buffers] > 0) {
00288 mask = RenderBuffer::T_front | RenderBuffer::T_back;
00289 } else {
00290 mask = RenderBuffer::T_front;
00291 }
00292 if (_property[FBP_depth_bits] > 0) {
00293 mask |= RenderBuffer::T_depth;
00294 }
00295 if (_property[FBP_stencil_bits] > 0) {
00296 mask |= RenderBuffer::T_stencil;
00297 }
00298 return mask;
00299 }
00300
00301
00302
00303
00304
00305
00306
00307 bool FrameBufferProperties::
00308 is_any_specified() const {
00309 for (int i=0; i<FBP_COUNT; i++) {
00310 if (_specified[i]) {
00311 return true;
00312 }
00313 }
00314 return false;
00315 }
00316
00317
00318
00319
00320
00321
00322 void FrameBufferProperties::
00323 set_all_specified() {
00324 for (int i=0; i<FBP_COUNT; i++) {
00325 _specified[i] = true;
00326 }
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 bool FrameBufferProperties::
00338 is_basic() const {
00339 if (_property[FBP_depth_bits] > 1) {
00340 return false;
00341 }
00342 if (_property[FBP_color_bits] > 1) {
00343 return false;
00344 }
00345 if (_property[FBP_alpha_bits] > 1) {
00346 return false;
00347 }
00348 if (_property[FBP_stencil_bits] > 0) {
00349 return false;
00350 }
00351 if (_property[FBP_aux_rgba] > 0) {
00352 return false;
00353 }
00354 if (_property[FBP_aux_hrgba] > 0) {
00355 return false;
00356 }
00357 if (_property[FBP_aux_float] > 0) {
00358 return false;
00359 }
00360 if (_property[FBP_multisamples] > 1) {
00361 return false;
00362 }
00363 if (_property[FBP_back_buffers] > 0) {
00364 return false;
00365 }
00366 if (_property[FBP_indexed_color] > 0) {
00367 return false;
00368 }
00369 if (_property[FBP_force_hardware] > 0) {
00370 return false;
00371 }
00372 if (_property[FBP_force_software] > 0) {
00373 return false;
00374 }
00375 return true;
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385 void FrameBufferProperties::
00386 set_one_bit_per_channel() {
00387 for (int prop=FBP_depth_bits; prop<=FBP_accum_bits; ++prop) {
00388 if (_property[prop] > 1) {
00389 _property[prop] = 1;
00390 }
00391 }
00392 }
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 int FrameBufferProperties::
00420 get_quality(const FrameBufferProperties &reqs) const {
00421
00422 if ((_property[FBP_indexed_color]==0) && (_property[FBP_rgb_color]==0)) {
00423
00424 return 0;
00425 }
00426
00427 if ((reqs._property[FBP_rgb_color] > _property[FBP_rgb_color])||
00428 (reqs._property[FBP_indexed_color] > _property[FBP_indexed_color])) {
00429
00430 return 0;
00431 }
00432
00433 int quality = 100000000;
00434
00435
00436
00437
00438 if ((reqs._property[FBP_force_hardware] > _property[FBP_force_hardware])||
00439 (reqs._property[FBP_force_software] > _property[FBP_force_software])) {
00440 quality -= 10000000;
00441 }
00442
00443
00444
00445
00446 for (int prop=FBP_depth_bits; prop<=FBP_accum_bits; prop++) {
00447 if ((reqs._property[prop]) && (_property[prop]==0)) {
00448 quality -= 1000000;
00449 }
00450 }
00451
00452
00453
00454
00455 for (int prop=FBP_aux_rgba; prop<=FBP_aux_float; prop++) {
00456 if (reqs._property[prop] > _property[prop]) {
00457 quality -= 100000;
00458 }
00459 }
00460
00461
00462
00463
00464 if (reqs._property[FBP_stereo] > _property[FBP_stereo]) {
00465 quality -= 100000;
00466 }
00467
00468
00469
00470
00471 if (reqs._property[FBP_back_buffers] > _property[FBP_back_buffers]) {
00472 quality -= 100000;
00473 }
00474
00475
00476
00477 if (reqs._property[FBP_multisamples] != 0 && _property[FBP_multisamples] == 0) {
00478 quality -= 100000;
00479 }
00480
00481
00482
00483
00484 for (int prop=FBP_depth_bits; prop<=FBP_accum_bits; prop++) {
00485 if (_property[prop] != 0 && reqs._property[prop] > _property[prop]) {
00486 quality -= 10000;
00487 }
00488 }
00489
00490
00491
00492
00493 if (_property[FBP_multisamples] != 0 &&
00494 reqs._property[FBP_multisamples] > _property[FBP_multisamples]) {
00495 quality -= 1000;
00496 }
00497
00498
00499
00500
00501 for (int prop=FBP_depth_bits; prop<=FBP_accum_bits; prop++) {
00502 if ((_property[prop]) && (reqs._property[prop] == 0)) {
00503 quality -= 50;
00504 }
00505 }
00506 for (int prop=FBP_aux_rgba; prop<=FBP_aux_float; prop++) {
00507 int extra = _property[prop] > reqs._property[prop];
00508 if (extra > 0) {
00509 extra = min(extra, 3);
00510 quality -= extra*50;
00511 }
00512 }
00513
00514
00515
00516
00517
00518
00519 for (int prop=FBP_depth_bits; prop<=FBP_accum_bits; prop++) {
00520 if (reqs._property[prop] > 1 &&
00521 _property[prop] > reqs._property[prop]) {
00522 quality -= 50;
00523 }
00524 }
00525
00526
00527
00528 if (reqs._property[FBP_depth_bits] != 0) {
00529 quality += 2 * _property[FBP_depth_bits];
00530 }
00531
00532
00533
00534 if (reqs._property[FBP_multisamples] != 0) {
00535 quality += 2 * _property[FBP_multisamples];
00536 }
00537
00538
00539
00540 for (int prop=FBP_color_bits; prop<=FBP_accum_bits; prop++) {
00541 if (reqs._property[prop] != 0) {
00542 quality += _property[prop];
00543 }
00544 }
00545
00546 return quality;
00547 };
00548
00549
00550
00551
00552
00553
00554
00555
00556 bool FrameBufferProperties::
00557 verify_hardware_software(const FrameBufferProperties &props, const string &renderer) const {
00558
00559 if (get_force_hardware() < props.get_force_hardware()) {
00560 display_cat.error()
00561 << "The application requested harware acceleration, but your OpenGL\n";
00562 display_cat.error()
00563 << "driver, " << renderer << ", only supports software rendering.\n";
00564 display_cat.error()
00565 << "You need to install a hardware-accelerated OpenGL driver, or,\n";
00566 display_cat.error()
00567 << "if you actually *want* to use a software renderer, then\n";
00568 display_cat.error()
00569 << "alter the hardware/software configuration in your Config.prc file.\n";
00570 return false;
00571 }
00572
00573 if (get_force_software() < props.get_force_software()) {
00574 display_cat.error()
00575 << "The application requested a software renderer, but your OpenGL\n";
00576 display_cat.error()
00577 << "driver, " << renderer << ", is probably hardware-accelerated.\n";
00578 display_cat.error()
00579 << "If you want to allow hardware acceleration, then alter the\n";
00580 display_cat.error()
00581 << "hardware/software configuration in your Config.prc file.\n";
00582 return false;
00583 }
00584
00585 return true;
00586 }
00587
00588