00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "realtime_urdf_filter/FrameBufferObject.h"
00034 #include <stdio.h>
00035 #include <string.h>
00036
00037 using namespace std;
00038
00039
00040
00042 int _numInternal8AFormats = 1;
00043 GLenum _internal8AColorFormats[] = { GL_RGBA8 };
00045 int _numInternal8Formats = 1;
00046 GLenum _internal8ColorFormats[] = { GL_RGB8 };
00047
00049 int _numInternal16AFormats = 3;
00050 GLenum _internal16AColorFormats[] = { GL_RGBA16F_ARB,
00051 GL_FLOAT_RGBA16_NV,
00052 GL_RGBA_FLOAT16_ATI };
00053
00055 int _numInternal16Formats = 3;
00056 GLenum _internal16ColorFormats[] = { GL_RGB16F_ARB,
00057 GL_FLOAT_RGB16_NV,
00058 GL_RGB_FLOAT16_ATI };
00059
00061 int _numInternal32AFormats = 3;
00062 GLenum _internal32AColorFormats[] = { GL_RGBA32F_ARB,
00063 GL_FLOAT_RGBA32_NV,
00064 GL_RGBA_FLOAT32_ATI };
00065
00067 int _numInternal32Formats = 3;
00068 GLenum _internal32ColorFormats[] = { GL_RGB32F_ARB,
00069 GL_FLOAT_RGB32_NV,
00070 GL_RGB_FLOAT32_ATI };
00071
00072 GLenum _framebufferStatus;
00073
00074
00075
00076 FramebufferObject::FramebufferObject(const char *strMode) :
00077
00078 _textureTarget(GL_TEXTURE_RECTANGLE_ARB),
00079
00080
00081 _colorFormat(GL_RGBA),
00082 _internalColorFormat(GL_RGBA),
00083 _colorType(GL_UNSIGNED_BYTE),
00084
00085 _colorAttachmentDepth(RGBA_8),
00086
00087 _depthFormat(GL_DEPTH_COMPONENT),
00088 _internalDepthFormat(GL_DEPTH_COMPONENT24),
00089 _depthType(GL_UNSIGNED_BYTE),
00090
00091 _wrapS(GL_CLAMP_TO_EDGE),
00092 _wrapT(GL_CLAMP_TO_EDGE),
00093 _minFilter(GL_LINEAR),
00094 _magFilter(GL_LINEAR),
00095
00096 _width(512),
00097 _height(512),
00098
00099 _bFBOSupported(false),
00100 _bInitialized(false),
00101
00102 _bColorAttachment(false),
00103 _bColorAttachmentRenderTexture(false),
00104
00105 _bDepthAttachment(false),
00106 _bDepthAttachmentRenderTexture(false),
00107
00108 _bStencilAttachment(false),
00109 _bStencilAttachmentRenderTexture(false),
00110 _stencilDepth(1),
00111
00112
00113 _internalStencilFormat(GL_STENCIL_INDEX1),
00114
00115 _bPassThroughProgramInitialized(false),
00116
00117 _numColorAttachments(1),
00118
00119 _bFloatColorBuffer(false)
00120 {
00121 parseModeString(strMode);
00122 }
00123
00124
00125
00126 FramebufferObject::~FramebufferObject() {
00127
00128 if(_bInitialized) {
00129
00130 if(_bColorAttachment) {
00131
00132 for(int i=0; i<_numColorAttachments; i++) {
00133 if(_bColorAttachmentRenderTexture)
00134 glDeleteTextures(1, &_colorAttachmentID[i]);
00135 else
00136 glDeleteRenderbuffers(1, &_colorAttachmentID[i]);
00137 }
00138 }
00139
00140 if(_bDepthAttachment) {
00141 if(_bDepthAttachmentRenderTexture)
00142 glDeleteTextures(1, &_depthAttachmentID);
00143 else
00144 glDeleteRenderbuffers(1, &_depthAttachmentID);
00145 }
00146
00147 glDeleteFramebuffers(1, &_frameBufferID);
00148
00149 }
00150
00151 if(_bPassThroughProgramInitialized)
00152 glDeleteProgramsARB(1, &_passThroughProgram);
00153 }
00154
00155
00156
00157 unsigned int
00158 FramebufferObject::getWidth() {
00159 return _width;
00160 }
00161
00162
00163
00164 unsigned int
00165 FramebufferObject::getHeight() {
00166 return _height;
00167 }
00168
00169
00170
00171 void
00172 FramebufferObject::bind(int index) {
00173 glEnable(_textureTarget);
00174 glBindTexture(_textureTarget, _colorAttachmentID[index]);
00175 glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_S, _wrapS);
00176 glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_T, _wrapT);
00177 glTexParameteri(_textureTarget, GL_TEXTURE_MIN_FILTER, _minFilter);
00178 glTexParameteri(_textureTarget, GL_TEXTURE_MAG_FILTER, _magFilter);
00179 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00180 }
00181
00182
00183
00184 void
00185 FramebufferObject::bindDepth(void) {
00186 glEnable(_textureTarget);
00187 glBindTexture(_textureTarget, _depthAttachmentID);
00188 glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_S, _wrapS);
00189 glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_T, _wrapT);
00190 glTexParameteri(_textureTarget, GL_TEXTURE_MIN_FILTER, _minFilter);
00191 glTexParameteri(_textureTarget, GL_TEXTURE_MAG_FILTER, _magFilter);
00192 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00193 }
00194
00195
00196
00197 GLuint
00198 FramebufferObject::getColorAttachmentID(int index) {
00199 return _colorAttachmentID[index];
00200 }
00201
00202
00203
00204 GLuint
00205 FramebufferObject::getDepthAttachmentID(void) {
00206 return _depthAttachmentID;
00207 }
00208
00209
00210
00211 GLuint
00212 FramebufferObject::getStencilAttachmentID(void) {
00213 return _depthAttachmentID;
00214 }
00215
00216
00217
00218 void
00219 FramebufferObject::setMinFilter(GLint minFilter) {
00220 _minFilter = minFilter;
00221 }
00222
00223
00224
00225 void
00226 FramebufferObject::setMagFilter(GLint magFilter) {
00227 _magFilter = magFilter;
00228 }
00229
00230
00231
00232 void
00233 FramebufferObject::setWrapS(GLint wrapS) {
00234 _wrapS = wrapS;
00235 }
00236
00237
00238
00239 void
00240 FramebufferObject::setWrapT(GLint wrapT) {
00241 _wrapT = wrapT;
00242 }
00243
00244
00245
00246 bool
00247 FramebufferObject::initialize( unsigned int width, unsigned int height ) {
00248
00249 if(_bInitialized)
00250 return reInitialize( width, height );
00251
00252 _width = width;
00253 _height = height;
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 if(!GLEW_EXT_framebuffer_object)
00267 cout << "ERROR: FramebufferObject - GL_EXT_framebuffer_object not supported!" << endl;
00268
00269 if(!GLEW_EXT_packed_depth_stencil)
00270 cout << "ERROR: FramebufferObject - GL_EXT_packed_depth_stencil not supported!" << endl;
00271
00272 if(!GLEW_EXT_multi_draw_arrays)
00273 cout << "ERROR: FramebufferObject - GLEW_EXT_multi_draw_arrays not supported!" << endl;
00274
00275 if(!GLEW_ARB_framebuffer_object)
00276 cout << "ERROR: FramebufferObject - GL_ARB_framebuffer_object not supported!" << endl;
00277
00278 if(!GLEW_ARB_texture_non_power_of_two)
00279 cout << "ERROR: FramebufferObject - GL_ARB_texture_non_power_of_two not supported!" << endl;
00280
00281
00282
00283
00284
00285 if(!_bPassThroughProgramInitialized) {
00286
00287 glGenProgramsARB(1, &_passThroughProgram);
00288
00289 const char* strPassThroughProgram =
00290 "!!ARBfp1.0\n"
00291 "MOV result.color, fragment.color.primary;\n"
00292 "END\n";
00293
00294 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, _passThroughProgram);
00295 glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB,
00296 GL_PROGRAM_FORMAT_ASCII_ARB,
00297 strlen(strPassThroughProgram),
00298 strPassThroughProgram);
00299
00300 _bPassThroughProgramInitialized = true;
00301
00302 }
00303
00304 glGetIntegerv(GL_MAX_DRAW_BUFFERS, &_maxNumDrawBuffers);
00305 if(_numColorAttachments > _maxNumDrawBuffers) {
00306 cout << "WARNING: FramebufferObject::initialize - this machine only supports up to " << _maxNumDrawBuffers << " draw buffers. Reset number of color attachments!" << endl;
00307 _numColorAttachments = _maxNumDrawBuffers;
00308 }
00309
00310
00311
00312 glPushAttrib(GL_TEXTURE_BIT);
00313
00314
00315 glGenFramebuffers(1, &_frameBufferID);
00316 glBindFramebuffer(GL_FRAMEBUFFER, _frameBufferID);
00317
00318 if(_bColorAttachment) {
00319
00320 if(_bColorAttachmentRenderTexture) {
00321
00322 int count = 0;
00323 bool success = false;
00324
00325 int numFormats = 1;
00326 GLenum *format;
00327
00328 switch(_colorAttachmentDepth) {
00329 case RGBA_8:
00330 numFormats = _numInternal8AFormats;
00331 format = _internal8AColorFormats;
00332 break;
00333 case RGB_8:
00334 numFormats = _numInternal8Formats;
00335 format = _internal8ColorFormats;
00336 break;
00337 case RGBA_16:
00338 numFormats = _numInternal16AFormats;
00339 format = _internal16AColorFormats;
00340 break;
00341 case RGB_16:
00342 numFormats = _numInternal16Formats;
00343 format = _internal16ColorFormats;
00344 break;
00345 case RGBA_32:
00346 numFormats = _numInternal32AFormats;
00347 format = _internal32AColorFormats;
00348 break;
00349 case RGB_32:
00350 numFormats = _numInternal32Formats;
00351 format = _internal32ColorFormats;
00352 break;
00353 }
00354
00355
00356 glEnable(_textureTarget);
00357 glGenTextures(1, &_colorAttachmentID[0]);
00358
00359 do {
00360
00361 _internalColorFormat = format[count];
00362
00363 glBindTexture(_textureTarget, _colorAttachmentID[0]);
00364
00365 glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_S, _wrapS);
00366 glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_T, _wrapT);
00367 glTexParameteri(_textureTarget, GL_TEXTURE_MIN_FILTER, _minFilter);
00368 glTexParameteri(_textureTarget, GL_TEXTURE_MAG_FILTER, _magFilter);
00369 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00370
00371 glTexImage2D( _textureTarget,
00372 0,
00373 _internalColorFormat,
00374 _width,
00375 _height,
00376 0,
00377 _colorFormat,
00378 _colorType,
00379 NULL);
00380
00381
00382 glFramebufferTexture2D( GL_FRAMEBUFFER,
00383 GL_COLOR_ATTACHMENT0,
00384 _textureTarget,
00385 _colorAttachmentID[0],
00386 0);
00387
00388 success = checkFramebufferStatus();
00389 count++;
00390
00391 } while( !(success || (count > (numFormats-1))) );
00392
00393
00394
00395
00396 for(int i=1; i<_numColorAttachments; i++) {
00397
00398 glGenTextures(1, &_colorAttachmentID[i]);
00399
00400 glBindTexture(_textureTarget, _colorAttachmentID[i]);
00401
00402 glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_S, _wrapS);
00403 glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_T, _wrapT);
00404 glTexParameteri(_textureTarget, GL_TEXTURE_MIN_FILTER, _minFilter);
00405 glTexParameteri(_textureTarget, GL_TEXTURE_MAG_FILTER, _magFilter);
00406 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00407
00408 glTexImage2D( _textureTarget,
00409 0,
00410 _internalColorFormat,
00411 _width,
00412 _height,
00413 0,
00414 _colorFormat,
00415 _colorType,
00416 NULL);
00417
00418 GLint colorAttachmentMacro=GL_COLOR_ATTACHMENT0;
00419 switch(i) {
00420 case 1:
00421 colorAttachmentMacro=GL_COLOR_ATTACHMENT1;
00422 break;
00423 case 2:
00424 colorAttachmentMacro=GL_COLOR_ATTACHMENT2;
00425 break;
00426 case 3:
00427 colorAttachmentMacro=GL_COLOR_ATTACHMENT3;
00428 break;
00429 case 4:
00430 colorAttachmentMacro=GL_COLOR_ATTACHMENT4;
00431 break;
00432 case 5:
00433 colorAttachmentMacro=GL_COLOR_ATTACHMENT5;
00434 break;
00435 case 6:
00436 colorAttachmentMacro=GL_COLOR_ATTACHMENT6;
00437 break;
00438 case 7:
00439 colorAttachmentMacro=GL_COLOR_ATTACHMENT7;
00440 break;
00441 case 8:
00442 colorAttachmentMacro=GL_COLOR_ATTACHMENT8;
00443 break;
00444 case 9:
00445 colorAttachmentMacro=GL_COLOR_ATTACHMENT9;
00446 break;
00447 case 10:
00448 colorAttachmentMacro=GL_COLOR_ATTACHMENT10;
00449 break;
00450 case 11:
00451 colorAttachmentMacro=GL_COLOR_ATTACHMENT11;
00452 break;
00453 case 12:
00454 colorAttachmentMacro=GL_COLOR_ATTACHMENT12;
00455 break;
00456 case 13:
00457 colorAttachmentMacro=GL_COLOR_ATTACHMENT13;
00458 break;
00459 case 14:
00460 colorAttachmentMacro=GL_COLOR_ATTACHMENT14;
00461 break;
00462 case 15:
00463 colorAttachmentMacro=GL_COLOR_ATTACHMENT15;
00464 break;
00465 }
00466
00467
00468 glFramebufferTexture2D( GL_FRAMEBUFFER,
00469 colorAttachmentMacro,
00470 _textureTarget,
00471 _colorAttachmentID[i],
00472 0);
00473
00474 success = checkFramebufferStatus();
00475 GLenum err = glGetError();
00476 if(err != GL_NO_ERROR)
00477 printf("OpenGL ERROR after FBO initialization: %s\n", gluErrorString(err));
00478
00479 }
00480
00481
00482
00483 if(!success)
00484 printFramebufferStatus();
00485
00486 } else {
00487
00488
00489
00490
00491 for(int i=0; i<_numColorAttachments; i++) {
00492
00493 glGenRenderbuffers(1, &_colorAttachmentID[i]);
00494
00495
00496 glBindRenderbuffer(GL_RENDERBUFFER, _colorAttachmentID[i]);
00497 glRenderbufferStorage( GL_RENDERBUFFER,
00498 _internalColorFormat,
00499 _width,
00500 _height);
00501
00502 GLint colorAttachmentMacro=GL_COLOR_ATTACHMENT0;
00503 switch(i) {
00504 case 1:
00505 colorAttachmentMacro=GL_COLOR_ATTACHMENT1;
00506 break;
00507 case 2:
00508 colorAttachmentMacro=GL_COLOR_ATTACHMENT2;
00509 break;
00510 case 3:
00511 colorAttachmentMacro=GL_COLOR_ATTACHMENT3;
00512 break;
00513 case 4:
00514 colorAttachmentMacro=GL_COLOR_ATTACHMENT4;
00515 break;
00516 case 5:
00517 colorAttachmentMacro=GL_COLOR_ATTACHMENT5;
00518 break;
00519 case 6:
00520 colorAttachmentMacro=GL_COLOR_ATTACHMENT6;
00521 break;
00522 case 7:
00523 colorAttachmentMacro=GL_COLOR_ATTACHMENT7;
00524 break;
00525 case 8:
00526 colorAttachmentMacro=GL_COLOR_ATTACHMENT8;
00527 break;
00528 case 9:
00529 colorAttachmentMacro=GL_COLOR_ATTACHMENT9;
00530 break;
00531 case 10:
00532 colorAttachmentMacro=GL_COLOR_ATTACHMENT10;
00533 break;
00534 case 11:
00535 colorAttachmentMacro=GL_COLOR_ATTACHMENT11;
00536 break;
00537 case 12:
00538 colorAttachmentMacro=GL_COLOR_ATTACHMENT12;
00539 break;
00540 case 13:
00541 colorAttachmentMacro=GL_COLOR_ATTACHMENT13;
00542 break;
00543 case 14:
00544 colorAttachmentMacro=GL_COLOR_ATTACHMENT14;
00545 break;
00546 case 15:
00547 colorAttachmentMacro=GL_COLOR_ATTACHMENT15;
00548 break;
00549 }
00550
00551
00552 glFramebufferRenderbuffer( GL_FRAMEBUFFER,
00553 colorAttachmentMacro,
00554 GL_RENDERBUFFER,
00555 _colorAttachmentID[i] );
00556
00557 }
00558
00559
00560
00561 if(!checkFramebufferStatus())
00562 std::cerr<<"ERROR: "<<__FILE__<<":"<<__LINE__<<std::endl;
00563 printFramebufferStatus();
00564
00565 }
00566
00567 }
00568
00569
00570
00571
00572
00573
00574 if(_bDepthAttachment) {
00575
00576 if(_bStencilAttachment) {
00577
00578 if(_internalDepthFormat != GL_DEPTH_COMPONENT24)
00579 cout << "WARNING: reset internal depth attachment format to 24 Bit [GL_DEPTH_STENCIL], otherwise stencil attachment won't work!" << endl;
00580
00581
00582 _internalDepthFormat = GL_DEPTH_COMPONENT24;
00583 }
00584
00585 if(_bDepthAttachmentRenderTexture) {
00586
00587
00588 glGenTextures(1, &_depthAttachmentID);
00589 glBindTexture(_textureTarget, _depthAttachmentID);
00590
00591 glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_S, _wrapS);
00592 glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_T, _wrapT);
00593 glTexParameteri(_textureTarget, GL_TEXTURE_MIN_FILTER, _minFilter);
00594 glTexParameteri(_textureTarget, GL_TEXTURE_MAG_FILTER, _magFilter);
00595 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00596
00597 glTexImage2D( _textureTarget,
00598 0,
00599 _internalDepthFormat,
00600 _width,
00601 _height,
00602 0,
00603 _depthFormat,
00604 _depthType,
00605 NULL);
00606
00607
00608 glFramebufferTexture2D(
00609 GL_FRAMEBUFFER,
00610 GL_DEPTH_ATTACHMENT,
00611 _textureTarget,
00612 _depthAttachmentID, 0);
00613
00614 if(!checkFramebufferStatus()) {
00615 std::cerr<<"ERROR: "<<__FILE__<<":"<<__LINE__<<std::endl;
00616 printFramebufferStatus();
00617 }
00618
00619 } else {
00620
00621 glGenRenderbuffers(1, &_depthAttachmentID);
00622
00623
00624 glBindRenderbuffer(GL_RENDERBUFFER, _depthAttachmentID);
00625 glRenderbufferStorage( GL_RENDERBUFFER,
00626 _internalDepthFormat,
00627 _width,
00628 _height);
00629
00630
00631 glFramebufferRenderbuffer( GL_FRAMEBUFFER,
00632 GL_DEPTH_ATTACHMENT,
00633 GL_RENDERBUFFER,
00634 _depthAttachmentID );
00635
00636 if(!checkFramebufferStatus()) {
00637 std::cerr<<"ERROR: "<<__FILE__<<":"<<__LINE__<<std::endl;
00638 printFramebufferStatus();
00639 }
00640
00641 }
00642
00643 }
00644
00645
00646
00647
00648
00649
00650
00651
00652 if(_bStencilAttachment) {
00653
00654 if(!_bDepthAttachment)
00655 cout << "ERROR: FBO stencil attachment is currently only supported in combination with a depth attachment: 24 Bit depth attachment + 8 Bit stencil attachment. See EXT_packed_depth_stencil specifications for details!" << endl;
00656
00657 if(_bStencilAttachmentRenderTexture) {
00658
00659 glBindTexture(_textureTarget, _depthAttachmentID);
00660
00661 glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_S, _wrapS);
00662 glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_T, _wrapT);
00663 glTexParameteri(_textureTarget, GL_TEXTURE_MIN_FILTER, _minFilter);
00664 glTexParameteri(_textureTarget, GL_TEXTURE_MAG_FILTER, _magFilter);
00665 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00666
00667 glTexImage2D( _textureTarget,
00668 0,
00669 _internalDepthFormat,
00670 _width,
00671 _height,
00672 0,
00673 _depthFormat,
00674 _depthType,
00675 NULL);
00676
00677
00678
00679
00680 glFramebufferTexture2D(
00681 GL_FRAMEBUFFER,
00682 GL_DEPTH_ATTACHMENT,
00683 _textureTarget,
00684 _depthAttachmentID, 0);
00685
00686 if(!checkFramebufferStatus()) {
00687 std::cerr<<"ERROR: "<<__FILE__<<":"<<__LINE__<<std::endl;
00688 printFramebufferStatus();
00689 }
00690
00691 } else {
00692
00693
00694 glBindRenderbuffer(GL_RENDERBUFFER, _depthAttachmentID);
00695 glRenderbufferStorage( GL_RENDERBUFFER,
00696 _internalDepthFormat,
00697 _width,
00698 _height);
00699
00700
00701 glFramebufferRenderbuffer( GL_FRAMEBUFFER,
00702 GL_STENCIL_ATTACHMENT,
00703 GL_RENDERBUFFER,
00704 _depthAttachmentID );
00705
00706 if(!checkFramebufferStatus()) {
00707 std::cerr<<"ERROR: "<<__FILE__<<":"<<__LINE__<<std::endl;
00708 printFramebufferStatus();
00709 }
00710
00711 }
00712
00713 }
00714
00715
00716
00717
00718
00719
00720
00721 glBindFramebuffer(GL_FRAMEBUFFER, 0);
00722
00723 glPopAttrib();
00724
00725 _bInitialized = true;
00726 _bFBOSupported = true;
00727
00728 return true;
00729 }
00730
00731
00732
00733 bool
00734 FramebufferObject::reInitialize( unsigned int width, unsigned int height, const char *strMode ) {
00735
00736 if(!_bInitialized)
00737 return initialize( width, height );
00738
00739 if(!_bFBOSupported)
00740 return false;
00741
00742
00743
00744
00745 glDeleteFramebuffers(1, &_frameBufferID);
00746
00747 if(_bColorAttachment) {
00748 if(_bColorAttachmentRenderTexture)
00749 glDeleteTextures(1, &_colorAttachmentID[0]);
00750 else
00751 glDeleteRenderbuffers(1, &_colorAttachmentID[0]);
00752 }
00753
00754 if(_bDepthAttachment) {
00755 if(_bDepthAttachmentRenderTexture)
00756 glDeleteTextures(1, &_depthAttachmentID);
00757 else
00758 glDeleteRenderbuffers(1, &_depthAttachmentID);
00759 }
00760
00761
00762
00763 _bInitialized = false;
00764 parseModeString(strMode);
00765 initialize(width, height);
00766
00767 return true;
00768 }
00769
00770
00771
00772 void
00773 FramebufferObject::beginCapture(bool bEnablePassThroughShader) {
00774
00775 glGetIntegerv(GL_VIEWPORT, _viewport);
00776 glViewport(0, 0, _width, _height);
00777
00778 if(_bInitialized)
00779 glBindFramebuffer(GL_FRAMEBUFFER, _frameBufferID);
00780
00781 if(_bFloatColorBuffer && bEnablePassThroughShader) {
00782 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, _passThroughProgram);
00783 glEnable(GL_FRAGMENT_PROGRAM_ARB);
00784 }
00785 }
00786
00787
00788
00789 void
00790 FramebufferObject::endCapture(bool bDisablePassThroughShader) {
00791
00792 glViewport(_viewport[0], _viewport[1], _viewport[2], _viewport[3]);
00793
00794 if(_bInitialized)
00795 glBindFramebuffer(GL_FRAMEBUFFER, 0);
00796
00797 if(_bFloatColorBuffer && bDisablePassThroughShader)
00798 glDisable(GL_FRAGMENT_PROGRAM_ARB);
00799
00800 }
00801
00802
00803
00804 void
00805 FramebufferObject::parseModeString(const char *modeString) {
00806
00807 if (!modeString || strcmp(modeString, "") == 0)
00808 return;
00809
00810
00811
00812
00813
00814
00815
00816 _bColorAttachment = false;
00817 _bDepthAttachment = false;
00818 _bStencilAttachment = false;
00819
00820 _bFloatColorBuffer = false;
00821
00822 char *mode = strdup(modeString);
00823
00824 vector<string> tokens;
00825 char *buf = strtok(mode, " ");
00826 while (buf != NULL)
00827 {
00828 tokens.push_back(buf);
00829 buf = strtok(NULL, " ");
00830 }
00831
00832
00833 for (unsigned int i = 0; i < tokens.size(); i++) {
00834
00835 string token = tokens[i];
00836 KeyVal kv = getKeyValuePair(token);
00837
00838
00839
00840
00841
00842 if ( strcmp(kv.first.c_str(), "rgba") == 0) {
00843
00844 _bColorAttachment = true;
00845 _colorFormat = GL_RGBA;
00846 _internalColorFormat = GL_RGBA;
00847 _colorType = GL_UNSIGNED_BYTE;
00848 _colorAttachmentDepth = RGBA_8;
00849
00850 _minFilter = GL_LINEAR;
00851 _magFilter = GL_LINEAR;
00852
00853 if( strchr(kv.second.c_str(), 't') != NULL ) {
00854 _bColorAttachmentRenderTexture = true;
00855 } else {
00856 _bColorAttachmentRenderTexture = false;
00857 }
00858
00859 if( kv.second.find("16") != kv.second.npos ) {
00860
00861 _colorAttachmentDepth = RGBA_16;
00862
00863 _internalColorFormat = GL_RGBA16F_ARB;
00864 _colorType = GL_HALF_FLOAT_ARB;
00865 _bFloatColorBuffer = true;
00866
00867 }
00868 if( kv.second.find("32") != kv.second.npos ) {
00869
00870 _colorAttachmentDepth = RGBA_32;
00871
00872 _internalColorFormat = GL_RGBA32F_ARB;
00873 _colorType = GL_FLOAT;
00874
00875
00876 _minFilter = GL_NEAREST;
00877 _magFilter = GL_NEAREST;
00878
00879 _bFloatColorBuffer = true;
00880 }
00881
00882
00883
00884
00885 if( kv.second.find("10x") != kv.second.npos ) {
00886 _numColorAttachments = 10;
00887 } else if( kv.second.find("11x") != kv.second.npos ) {
00888 _numColorAttachments = 11;
00889 } else if( kv.second.find("12x") != kv.second.npos ) {
00890 _numColorAttachments = 12;
00891 } else if( kv.second.find("13x") != kv.second.npos ) {
00892 _numColorAttachments = 13;
00893 } else if( kv.second.find("14x") != kv.second.npos ) {
00894 _numColorAttachments = 14;
00895 } else if( kv.second.find("15x") != kv.second.npos ) {
00896 _numColorAttachments = 15;
00897 } else if( kv.second.find("16x") != kv.second.npos ) {
00898 _numColorAttachments = 16;
00899 } else if( kv.second.find("2x") != kv.second.npos ) {
00900 _numColorAttachments = 2;
00901 } else if( kv.second.find("3x") != kv.second.npos ) {
00902 _numColorAttachments = 3;
00903 } else if( kv.second.find("4x") != kv.second.npos ) {
00904 _numColorAttachments = 4;
00905 } else if( kv.second.find("5x") != kv.second.npos ) {
00906 _numColorAttachments = 5;
00907 } else if( kv.second.find("6x") != kv.second.npos ) {
00908 _numColorAttachments = 6;
00909 } else if( kv.second.find("7x") != kv.second.npos ) {
00910 _numColorAttachments = 7;
00911 } else if( kv.second.find("8x") != kv.second.npos ) {
00912 _numColorAttachments = 8;
00913 } else if( kv.second.find("9x") != kv.second.npos ) {
00914 _numColorAttachments = 9;
00915 }
00916
00917
00918
00919
00920
00921
00922 } else if ( strcmp(kv.first.c_str(), "rgb") == 0) {
00923
00924 _bColorAttachment = true;
00925 _colorFormat = GL_RGB;
00926 _internalColorFormat = GL_RGB;
00927 _colorType = GL_UNSIGNED_BYTE;
00928 _colorAttachmentDepth = RGB_8;
00929
00930 _minFilter = GL_LINEAR;
00931 _magFilter = GL_LINEAR;
00932
00933 if( strchr(kv.second.c_str(), 't') != NULL ) {
00934 _bColorAttachmentRenderTexture = true;
00935 } else {
00936 _bColorAttachmentRenderTexture = false;
00937 }
00938
00939 if( kv.second.find("16") != kv.second.npos ) {
00940
00941 _internalColorFormat = GL_RGB16F_ARB;
00942 _colorType = GL_HALF_FLOAT_ARB;
00943
00944 _colorAttachmentDepth = RGB_16;
00945 _bFloatColorBuffer = true;
00946 }
00947 if( kv.second.find("32") != kv.second.npos ) {
00948
00949 _internalColorFormat = GL_RGB32F_ARB;
00950 _colorType = GL_FLOAT;
00951
00952
00953 _minFilter = GL_NEAREST;
00954 _magFilter = GL_NEAREST;
00955
00956 _colorAttachmentDepth = RGB_32;
00957 _bFloatColorBuffer = true;
00958 }
00959
00960
00961
00962
00963 if( kv.second.find("10x") != kv.second.npos ) {
00964 _numColorAttachments = 10;
00965 } else if( kv.second.find("11x") != kv.second.npos ) {
00966 _numColorAttachments = 11;
00967 } else if( kv.second.find("12x") != kv.second.npos ) {
00968 _numColorAttachments = 12;
00969 } else if( kv.second.find("13x") != kv.second.npos ) {
00970 _numColorAttachments = 13;
00971 } else if( kv.second.find("14x") != kv.second.npos ) {
00972 _numColorAttachments = 14;
00973 } else if( kv.second.find("15x") != kv.second.npos ) {
00974 _numColorAttachments = 15;
00975 } else if( kv.second.find("16x") != kv.second.npos ) {
00976 _numColorAttachments = 16;
00977 } else if( kv.second.find("2x") != kv.second.npos ) {
00978 _numColorAttachments = 2;
00979 } else if( kv.second.find("3x") != kv.second.npos ) {
00980 _numColorAttachments = 3;
00981 } else if( kv.second.find("4x") != kv.second.npos ) {
00982 _numColorAttachments = 4;
00983 } else if( kv.second.find("5x") != kv.second.npos ) {
00984 _numColorAttachments = 5;
00985 } else if( kv.second.find("6x") != kv.second.npos ) {
00986 _numColorAttachments = 6;
00987 } else if( kv.second.find("7x") != kv.second.npos ) {
00988 _numColorAttachments = 7;
00989 } else if( kv.second.find("8x") != kv.second.npos ) {
00990 _numColorAttachments = 8;
00991 } else if( kv.second.find("9x") != kv.second.npos ) {
00992 _numColorAttachments = 9;
00993 }
00994
00995
00996
00997 }
00998
00999
01000
01001
01002
01003 else if ( strcmp(kv.first.c_str(), "depth") == 0) {
01004
01005 _bDepthAttachment = true;
01006 _depthFormat = GL_DEPTH_COMPONENT;
01007 _depthType = GL_UNSIGNED_BYTE;
01008 _depthType = GL_FLOAT;
01009 _internalDepthFormat = GL_DEPTH_COMPONENT24;
01010
01011 if( kv.second.find("t") != kv.second.npos ) {
01012 _bDepthAttachmentRenderTexture = true;
01013 } else {
01014 _bDepthAttachmentRenderTexture = false;
01015 }
01016
01017 if( kv.second.find("16") != kv.second.npos )
01018 _internalDepthFormat = GL_DEPTH_COMPONENT16;
01019 if( kv.second.find("24") != kv.second.npos )
01020 _internalDepthFormat = GL_DEPTH_COMPONENT24;
01021 if( kv.second.find("32") != kv.second.npos )
01022 _internalDepthFormat = GL_DEPTH_COMPONENT32;
01023 }
01024
01025
01026
01027
01028
01029 else if ( strcmp(kv.first.c_str(), "stencil") == 0) {
01030
01031 _bStencilAttachment = true;
01032
01033 if( kv.second.find("t") != kv.second.npos ) {
01034 _bStencilAttachmentRenderTexture = true;
01035 } else {
01036 _bStencilAttachmentRenderTexture = false;
01037 }
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052 }
01053
01054 }
01055 }
01056
01057
01058
01059 FramebufferObject::KeyVal
01060 FramebufferObject::getKeyValuePair(string token) {
01061
01062 string::size_type pos = 0;
01063 if ((pos = token.find("=")) != token.npos) {
01064
01065 string key = token.substr(0, pos);
01066 string value = token.substr(pos+1, token.length()-pos+1);
01067 return KeyVal(key, value);
01068 }
01069 else
01070 return KeyVal(token, "");
01071 }
01072
01073
01074
01075 bool
01076 FramebufferObject::checkFramebufferStatus(void) {
01077
01078 _framebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
01079
01080 if(_framebufferStatus == GL_FRAMEBUFFER_COMPLETE)
01081 return true;
01082 else
01083 return false;
01084 }
01085
01086
01087
01088 void
01089 FramebufferObject::printFramebufferStatus(void) {
01090
01091 switch(_framebufferStatus) {
01092
01093 case GL_FRAMEBUFFER_COMPLETE:
01094 cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_COMPLETE" << endl;
01095 break;
01096
01097 case GL_FRAMEBUFFER_UNSUPPORTED:
01098 cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_UNSUPPORTED" << endl;
01099 break;
01100
01101 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
01102 cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT" << endl;
01103 break;
01104
01105 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
01106 cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT" << endl;
01107 break;
01108
01109 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
01110 cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT" << endl;
01111 break;
01112
01113
01114
01115
01116
01117 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
01118 cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT" << endl;
01119 break;
01120
01121 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
01122 cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER" << endl;
01123 break;
01124
01125 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
01126 cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER" << endl;
01127 break;
01128
01129 case GL_FRAMEBUFFER_BINDING:
01130 cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_BINDING" << endl;
01131 break;
01132
01133
01134
01135
01136
01137 default:
01138 cout << "FramebufferObject ERROR: unidentified error!" << endl;
01139 break;
01140 }
01141 }
01142
01143