void ofFbo::setup(Settings settings) { checkGLSupport(); destroy(); if(settings.width == 0) settings.width = ofGetWidth(); if(settings.height == 0) settings.height = ofGetHeight(); this->settings = settings; // create main fbo // this is the main one we bind for drawing into // all the renderbuffers are attached to this (whether MSAA is enabled or not) glGenFramebuffers(1, &fbo); bind(); // If we want both a depth AND a stencil buffer tehn combine them into a single buffer if( settings.useDepth && settings.useStencil ) { stencilBuffer = depthBuffer = createAndAttachRenderbuffer(GL_DEPTH_STENCIL, GL_DEPTH_STENCIL_ATTACHMENT); } else { // if we want a depth buffer, create it, and attach to our main fbo if(settings.useDepth) depthBuffer = createAndAttachRenderbuffer(GL_DEPTH_COMPONENT, GL_DEPTH_ATTACHMENT); // if we want a stencil buffer, create it, and attach to our main fbo if(settings.useStencil) stencilBuffer = createAndAttachRenderbuffer(GL_STENCIL_INDEX, GL_STENCIL_ATTACHMENT); } // if we want MSAA, create a new fbo for textures if(settings.numSamples) glGenFramebuffers(1, &fboTextures); else fboTextures = fbo; // now create all textures and color buffers for(int i=0; i<settings.numColorbuffers; i++) createAndAttachTexture(i); // if textures are attached to a different fbo (e.g. if using MSAA) check it's status if(fbo != fboTextures) { glBindFramebuffer(GL_FRAMEBUFFER, fboTextures); } // check everything is ok with this fbo checkStatus(); // unbind it unbind(); }
void ofFbo::allocate(Settings _settings) { if(!checkGLSupport()) return; destroy(); if(_settings.width == 0) _settings.width = ofGetWidth(); if(_settings.height == 0) _settings.height = ofGetHeight(); if(_settings.numSamples > maxSamples()) { ofLogWarning() << "clamping numSamples (" << _settings.numSamples << ") to maxSamples (" << maxSamples() << ")"; _settings.numSamples = maxSamples(); } settings = _settings; // create main fbo // this is the main one we bind for drawing into // all the renderbuffers are attached to this (whether MSAA is enabled or not) glGenFramebuffers(1, &fbo); retainFB(fbo); bind(); if(settings.depthStencilAsTexture && settings.numSamples){ ofLogWarning() << "multisampling not supported with depth as texture, setting 0 samples"; settings.numSamples = 0; } //currently depth only works if stencil is enabled. // http://forum.openframeworks.cc/index.php/topic,6837.0.html #ifdef TARGET_OPENGLES if(settings.useDepth){ settings.useStencil = true; } if( settings.depthStencilAsTexture ){ settings.depthStencilAsTexture = false; ofLogWarning() << "ofFbo::Settings depthStencilAsTexture is not available for iOS" << endl; } #endif GLenum depthAttachment; GLint depthPixelType; GLint depthFormat; if( settings.useDepth && settings.useStencil ){ depthFormat = GL_DEPTH_STENCIL; settings.depthStencilInternalFormat = GL_DEPTH_STENCIL; depthPixelType = GL_UNSIGNED_INT_24_8; #ifdef TARGET_OPENGLES depthAttachment = GL_DEPTH_ATTACHMENT; #else depthAttachment = GL_DEPTH_STENCIL_ATTACHMENT; #endif }else if(settings.useDepth){ depthPixelType = GL_UNSIGNED_SHORT; if(settings.depthStencilInternalFormat==GL_DEPTH_COMPONENT16){ depthPixelType = GL_UNSIGNED_SHORT; }else if(settings.depthStencilInternalFormat==GL_DEPTH_COMPONENT24){ depthPixelType = GL_UNSIGNED_INT; } #ifdef GL_DEPTH_COMPONENT32 else if(settings.depthStencilInternalFormat==GL_DEPTH_COMPONENT32){ depthPixelType = GL_UNSIGNED_INT; } #endif depthAttachment = GL_DEPTH_ATTACHMENT; depthFormat = GL_DEPTH_COMPONENT; }else if(settings.useStencil){ depthAttachment = GL_STENCIL_ATTACHMENT; settings.depthStencilInternalFormat = GL_STENCIL_INDEX; depthFormat = GL_STENCIL_INDEX; depthPixelType = GL_UNSIGNED_BYTE; } //- USE REGULAR RENDER BUFFER if(!settings.depthStencilAsTexture){ if(settings.useDepth && settings.useStencil){ stencilBuffer = depthBuffer = createAndAttachRenderbuffer(settings.depthStencilInternalFormat, depthAttachment); retainRB(stencilBuffer); retainRB(depthBuffer); }else if(settings.useDepth){ depthBuffer = createAndAttachRenderbuffer(settings.depthStencilInternalFormat, depthAttachment); retainRB(depthBuffer); }else if(settings.useStencil){ stencilBuffer = createAndAttachRenderbuffer(settings.depthStencilInternalFormat, depthAttachment); retainRB(stencilBuffer); } //- INSTEAD USE TEXTURE }else{ if(settings.useDepth || settings.useStencil){ createAndAttachDepthStencilTexture(settings.textureTarget,settings.depthStencilInternalFormat,depthFormat,depthPixelType,depthAttachment); #ifdef TARGET_OPENGLES // if there's depth and stencil the texture should be attached as // depth and stencil attachments // http://www.khronos.org/registry/gles/extensions/OES/OES_packed_depth_stencil.txt if(settings.useDepth && settings.useStencil){ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthBufferTex.texData.textureID, 0); } #endif } } // if we want MSAA, create a new fbo for textures #ifndef TARGET_OPENGLES if(settings.numSamples){ glGenFramebuffers(1, &fboTextures); retainFB(fboTextures); }else{ fboTextures = fbo; } #else fboTextures = fbo; if(settings.numSamples){ ofLog(OF_LOG_WARNING,"ofFbo: multisampling not supported in opengles"); } #endif // now create all textures and color buffers for(int i=0; i<settings.numColorbuffers; i++) createAndAttachTexture(i); // if textures are attached to a different fbo (e.g. if using MSAA) check it's status if(fbo != fboTextures) { glBindFramebuffer(GL_FRAMEBUFFER, fboTextures); } // check everything is ok with this fbo checkStatus(); // unbind it unbind(); bIsAllocated = true; }
int ofFbo::maxSamples() { if(_maxSamples<0) checkGLSupport(); return _maxSamples; }
int ofFbo::maxDrawBuffers() { if(_maxDrawBuffers<0) checkGLSupport(); return _maxDrawBuffers; }
int ofFbo::maxColorAttachments() { if(_maxColorAttachments<0) checkGLSupport(); return _maxColorAttachments; }
//-------------------------------------------------------------- void ofFbo::allocate(Settings _settings) { if(!checkGLSupport()) return; clear(); auto renderer = _settings.renderer.lock(); if(renderer){ settings.renderer = renderer; }else{ settings.renderer = ofGetGLRenderer(); } // check that passed values are correct if(_settings.width <= 0 || _settings.height <= 0){ ofLogError("ofFbo") << "width and height have to be more than 0"; } if(_settings.numSamples > maxSamples() && maxSamples() > -1) { ofLogWarning("ofFbo") << "allocate(): clamping numSamples " << _settings.numSamples << " to maxSamples " << maxSamples() << " for frame buffer object" << fbo; _settings.numSamples = maxSamples(); } if(_settings.depthStencilAsTexture && _settings.numSamples){ ofLogWarning("ofFbo") << "allocate(): multisampling not supported with depthStencilAsTexture, setting 0 samples for frame buffer object " << fbo; _settings.numSamples = 0; } //currently depth only works if stencil is enabled. // http://forum.openframeworks.cc/index.php/topic,6837.0.html #ifdef TARGET_OPENGLES if(_settings.useDepth){ _settings.useStencil = true; } if( _settings.depthStencilAsTexture ){ _settings.depthStencilAsTexture = false; ofLogWarning("ofFbo") << "allocate(): depthStencilAsTexture is not available for iOS"; } #endif GLenum depthAttachment = GL_DEPTH_ATTACHMENT; if( _settings.useDepth && _settings.useStencil ){ _settings.depthStencilInternalFormat = GL_DEPTH_STENCIL; #ifdef TARGET_OPENGLES depthAttachment = GL_DEPTH_ATTACHMENT; #else depthAttachment = GL_DEPTH_STENCIL_ATTACHMENT; #endif }else if(_settings.useDepth){ depthAttachment = GL_DEPTH_ATTACHMENT; }else if(_settings.useStencil){ depthAttachment = GL_STENCIL_ATTACHMENT; _settings.depthStencilInternalFormat = GL_STENCIL_INDEX; } // set needed values for allocation on instance settings // the rest will be set by the corresponding methods during allocation settings.width = _settings.width; settings.height = _settings.height; settings.numSamples = _settings.numSamples; // create main fbo // this is the main one we bind for drawing into // all the renderbuffers are attached to this (whether MSAA is enabled or not) glGenFramebuffers(1, &fbo); retainFB(fbo); GLint previousFboId = 0; // note that we are using a glGetInteger method here, which may stall the pipeline. // in the allocate() method, this is not that tragic since this will not be called // within the draw() loop. Here, we need not optimise for performance, but for // simplicity and readability . glGetIntegerv(GL_FRAMEBUFFER_BINDING, &previousFboId); glBindFramebuffer(GL_FRAMEBUFFER, fbo); //- USE REGULAR RENDER BUFFER if(!_settings.depthStencilAsTexture){ if(_settings.useDepth && _settings.useStencil){ stencilBuffer = depthBuffer = createAndAttachRenderbuffer(_settings.depthStencilInternalFormat, depthAttachment); retainRB(stencilBuffer); retainRB(depthBuffer); }else if(_settings.useDepth){ depthBuffer = createAndAttachRenderbuffer(_settings.depthStencilInternalFormat, depthAttachment); retainRB(depthBuffer); }else if(_settings.useStencil){ stencilBuffer = createAndAttachRenderbuffer(_settings.depthStencilInternalFormat, depthAttachment); retainRB(stencilBuffer); } //- INSTEAD USE TEXTURE }else{ if(_settings.useDepth || _settings.useStencil){ createAndAttachDepthStencilTexture(_settings.textureTarget,_settings.depthStencilInternalFormat,depthAttachment); #ifdef TARGET_OPENGLES // if there's depth and stencil the texture should be attached as // depth and stencil attachments // http://www.khronos.org/registry/gles/extensions/OES/OES_packed_depth_stencil.txt if(_settings.useDepth && _settings.useStencil){ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthBufferTex.texData.textureID, 0); } #endif } } settings.useDepth = _settings.useDepth; settings.useStencil = _settings.useStencil; settings.depthStencilInternalFormat = _settings.depthStencilInternalFormat; settings.depthStencilAsTexture = _settings.depthStencilAsTexture; settings.textureTarget = _settings.textureTarget; settings.wrapModeHorizontal = _settings.wrapModeHorizontal; settings.wrapModeVertical = _settings.wrapModeVertical; settings.maxFilter = _settings.maxFilter; settings.minFilter = _settings.minFilter; // if we want MSAA, create a new fbo for textures #ifndef TARGET_OPENGLES if(_settings.numSamples){ glGenFramebuffers(1, &fboTextures); retainFB(fboTextures); }else{ fboTextures = fbo; } #else fboTextures = fbo; if(_settings.numSamples){ ofLogWarning("ofFbo") << "allocate(): multisampling not supported in OpenGL ES"; } #endif // now create all textures and color buffers if(_settings.colorFormats.size() > 0) { for(int i=0; i<(int)_settings.colorFormats.size(); i++) createAndAttachTexture(_settings.colorFormats[i], i); } else if(_settings.numColorbuffers > 0) { for(int i=0; i<_settings.numColorbuffers; i++) createAndAttachTexture(_settings.internalformat, i); _settings.colorFormats = settings.colorFormats; } else { ofLogWarning("ofFbo") << "allocate(): no color buffers specified for frame buffer object " << fbo; } settings.internalformat = _settings.internalformat; dirty.resize(_settings.colorFormats.size(), true); // we start with all color buffers dirty. // if textures are attached to a different fbo (e.g. if using MSAA) check it's status if(fbo != fboTextures) { glBindFramebuffer(GL_FRAMEBUFFER, fboTextures); } // check everything is ok with this fbo bIsAllocated = checkStatus(); // restore previous framebuffer id glBindFramebuffer(GL_FRAMEBUFFER, previousFboId); /* UNCOMMENT OUTSIDE OF DOING RELEASES // this should never happen if(settings != _settings) ofLogWarning("ofFbo") << "allocation not complete, passed settings not equal to created ones, this is an internal OF bug"; */ #ifdef TARGET_ANDROID ofAddListener(ofxAndroidEvents().reloadGL,this,&ofFbo::reloadFbo); #endif }
void ofFbo::setup(Settings _settings) { checkGLSupport(); destroy(); if(_settings.width == 0) _settings.width = ofGetWidth(); if(_settings.height == 0) _settings.height = ofGetHeight(); settings = _settings; // create main fbo // this is the main one we bind for drawing into // all the renderbuffers are attached to this (whether MSAA is enabled or not) glGenFramebuffers(1, &fbo); retainFB(fbo); bind(); // If we want both a depth AND a stencil buffer tehn combine them into a single buffer #ifndef TARGET_OPENGLES if( settings.useDepth && settings.useStencil ) { stencilBuffer = depthBuffer = createAndAttachRenderbuffer(GL_DEPTH_STENCIL, GL_DEPTH_STENCIL_ATTACHMENT); retainRB(depthBuffer); retainRB(stencilBuffer); }else #endif { // if we want a depth buffer, create it, and attach to our main fbo if(settings.useDepth){ depthBuffer = createAndAttachRenderbuffer(GL_DEPTH_COMPONENT, GL_DEPTH_ATTACHMENT); retainRB(depthBuffer); } // if we want a stencil buffer, create it, and attach to our main fbo if(settings.useStencil){ stencilBuffer = createAndAttachRenderbuffer(GL_STENCIL_INDEX, GL_STENCIL_ATTACHMENT); retainRB(stencilBuffer); } } // if we want MSAA, create a new fbo for textures #ifndef TARGET_OPENGLES if(settings.numSamples){ glGenFramebuffers(1, &fboTextures); retainFB(fboTextures); }else{ fboTextures = fbo; } #else fboTextures = fbo; if(settings.numSamples){ ofLog(OF_LOG_WARNING,"ofFbo: multisampling not supported in opengles"); } #endif // now create all textures and color buffers for(int i=0; i<settings.numColorbuffers; i++) createAndAttachTexture(i); // if textures are attached to a different fbo (e.g. if using MSAA) check it's status if(fbo != fboTextures) { glBindFramebuffer(GL_FRAMEBUFFER, fboTextures); } // check everything is ok with this fbo checkStatus(); // unbind it unbind(); }
void ofFbo::allocate(Settings _settings) { if(!checkGLSupport()) return; destroy(); // check that passed values are correct if(_settings.width == 0) _settings.width = ofGetWidth(); if(_settings.height == 0) _settings.height = ofGetHeight(); if(_settings.numSamples > maxSamples() && maxSamples() > -1) { ofLogWarning("ofFbo") << "allocate(): clamping numSamples " << _settings.numSamples << " to maxSamples " << maxSamples() << " for frame buffer object" << fbo; _settings.numSamples = maxSamples(); } if(_settings.depthStencilAsTexture && _settings.numSamples){ ofLogWarning("ofFbo") << "allocate(): multisampling not supported with depthStencilAsTexture, setting 0 samples for frame buffer object " << fbo; _settings.numSamples = 0; } //currently depth only works if stencil is enabled. // http://forum.openframeworks.cc/index.php/topic,6837.0.html #ifdef TARGET_OPENGLES if(_settings.useDepth){ _settings.useStencil = true; } if( _settings.depthStencilAsTexture ){ _settings.depthStencilAsTexture = false; ofLogWarning("ofFbo") << "allocate(): depthStencilAsTexture is not available for iOS"; } #endif GLenum depthAttachment = GL_DEPTH_ATTACHMENT; if( _settings.useDepth && _settings.useStencil ){ _settings.depthStencilInternalFormat = GL_DEPTH_STENCIL; #ifdef TARGET_OPENGLES depthAttachment = GL_DEPTH_ATTACHMENT; #else depthAttachment = GL_DEPTH_STENCIL_ATTACHMENT; #endif }else if(_settings.useDepth){ depthAttachment = GL_DEPTH_ATTACHMENT; }else if(_settings.useStencil){ depthAttachment = GL_STENCIL_ATTACHMENT; _settings.depthStencilInternalFormat = GL_STENCIL_INDEX; } // set needed values for allocation on instance settings // the rest will be set by the corresponding methods during allocation settings.width = _settings.width; settings.height = _settings.height; settings.numSamples = _settings.numSamples; // create main fbo // this is the main one we bind for drawing into // all the renderbuffers are attached to this (whether MSAA is enabled or not) glGenFramebuffers(1, &fbo); retainFB(fbo); bind(); //- USE REGULAR RENDER BUFFER if(!_settings.depthStencilAsTexture){ if(_settings.useDepth && _settings.useStencil){ stencilBuffer = depthBuffer = createAndAttachRenderbuffer(_settings.depthStencilInternalFormat, depthAttachment); retainRB(stencilBuffer); retainRB(depthBuffer); }else if(_settings.useDepth){ depthBuffer = createAndAttachRenderbuffer(_settings.depthStencilInternalFormat, depthAttachment); retainRB(depthBuffer); }else if(_settings.useStencil){ stencilBuffer = createAndAttachRenderbuffer(_settings.depthStencilInternalFormat, depthAttachment); retainRB(stencilBuffer); } //- INSTEAD USE TEXTURE }else{ if(_settings.useDepth || _settings.useStencil){ createAndAttachDepthStencilTexture(_settings.textureTarget,_settings.depthStencilInternalFormat,depthAttachment); #ifdef TARGET_OPENGLES // if there's depth and stencil the texture should be attached as // depth and stencil attachments // http://www.khronos.org/registry/gles/extensions/OES/OES_packed_depth_stencil.txt if(_settings.useDepth && _settings.useStencil){ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthBufferTex.texData.textureID, 0); } #endif } } settings.useDepth = _settings.useDepth; settings.useStencil = _settings.useStencil; settings.depthStencilInternalFormat = _settings.depthStencilInternalFormat; settings.depthStencilAsTexture = _settings.depthStencilAsTexture; settings.textureTarget = _settings.textureTarget; settings.wrapModeHorizontal = _settings.wrapModeHorizontal; settings.wrapModeVertical = _settings.wrapModeVertical; // if we want MSAA, create a new fbo for textures #ifndef TARGET_OPENGLES if(_settings.numSamples){ glGenFramebuffers(1, &fboTextures); retainFB(fboTextures); }else{ fboTextures = fbo; } #else fboTextures = fbo; if(_settings.numSamples){ ofLogWarning("ofFbo") << "allocate(): multisampling not supported in OpenGL ES"; } #endif // now create all textures and color buffers if(_settings.colorFormats.size() > 0) { for(int i=0; i<(int)_settings.colorFormats.size(); i++) createAndAttachTexture(_settings.colorFormats[i], i); } else if(_settings.numColorbuffers > 0) { for(int i=0; i<_settings.numColorbuffers; i++) createAndAttachTexture(_settings.internalformat, i); _settings.colorFormats = settings.colorFormats; } else { ofLogWarning("ofFbo") << "allocate(): no color buffers specified for frame buffer object " << fbo; } settings.internalformat = _settings.internalformat; // if textures are attached to a different fbo (e.g. if using MSAA) check it's status if(fbo != fboTextures) { glBindFramebuffer(GL_FRAMEBUFFER, fboTextures); } // check everything is ok with this fbo bIsAllocated = checkStatus(); // unbind it unbind(); /* UNCOMMENT OUTSIDE OF DOING RELEASES // this should never happen if(settings != _settings) ofLogWarning("ofFbo") << "allocation not complete, passed settings not equal to created ones, this is an internal OF bug"; */ }
void ofFbo::allocate(Settings _settings) { if(!checkGLSupport()) return; destroy(); if(_settings.width == 0) _settings.width = ofGetWidth(); if(_settings.height == 0) _settings.height = ofGetHeight(); settings = _settings; // create main fbo // this is the main one we bind for drawing into // all the renderbuffers are attached to this (whether MSAA is enabled or not) glGenFramebuffers(1, &fbo); retainFB(fbo); bind(); // If we want both a depth AND a stencil buffer tehn combine them into a single buffer #ifndef TARGET_OPENGLES if( settings.useDepth && settings.useStencil ) { stencilBuffer = depthBuffer = createAndAttachRenderbuffer(GL_DEPTH_STENCIL, GL_DEPTH_STENCIL_ATTACHMENT); retainRB(depthBuffer); retainRB(stencilBuffer); }else #endif { // if we want a depth buffer, create it, and attach to our main fbo if(settings.useDepth){ if(!settings.depthAsTexture){ depthBuffer = createAndAttachRenderbuffer(GL_DEPTH_COMPONENT, GL_DEPTH_ATTACHMENT); retainRB(depthBuffer); }else{ glGenTextures(1, &depthBuffer); //retainRB(depthBuffer); glBindTexture(GL_TEXTURE_2D, depthBuffer); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); #ifndef TARGET_OPENGLES glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); #else glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); #endif glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, settings.width, settings.height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0 ); glBindTexture( GL_TEXTURE_2D, 0 ); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D, depthBuffer, 0); } } // if we want a stencil buffer, create it, and attach to our main fbo if(settings.useStencil){ stencilBuffer = createAndAttachRenderbuffer(GL_STENCIL_INDEX, GL_STENCIL_ATTACHMENT); retainRB(stencilBuffer); } } // if we want MSAA, create a new fbo for textures #ifndef TARGET_OPENGLES if(settings.numSamples){ glGenFramebuffers(1, &fboTextures); retainFB(fboTextures); }else{ fboTextures = fbo; } #else fboTextures = fbo; if(settings.numSamples){ ofLog(OF_LOG_WARNING,"ofFbo: multisampling not supported in opengles"); } #endif // now create all textures and color buffers for(int i=0; i<settings.numColorbuffers; i++) createAndAttachTexture(i); // if textures are attached to a different fbo (e.g. if using MSAA) check it's status if(fbo != fboTextures) { glBindFramebuffer(GL_FRAMEBUFFER, fboTextures); } // check everything is ok with this fbo checkStatus(); // unbind it unbind(); }