00001 /* 00002 Copyright (c) 2010, The Barbarian Group 00003 All rights reserved. 00004 00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that 00006 the following conditions are met: 00007 00008 * Redistributions of source code must retain the above copyright notice, this list of conditions and 00009 the following disclaimer. 00010 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 00011 the following disclaimer in the documentation and/or other materials provided with the distribution. 00012 00013 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 00014 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00015 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00016 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00017 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00018 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00019 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00020 POSSIBILITY OF SUCH DAMAGE. 00021 */ 00022 00023 #pragma once 00024 00025 #include "cinder/Cinder.h" 00026 #include "cinder/Exception.h" 00027 #include "cinder/gl/gl.h" 00028 #include "cinder/gl/Texture.h" 00029 00030 namespace cinder { namespace gl { 00031 00033 class Fbo { 00034 public: 00035 struct Format; 00036 00038 Fbo() {} 00040 Fbo( int width, int height, Format format = Format() ); 00042 Fbo( int width, int height, bool alpha, bool color = true, bool depth = true ); 00043 00045 int getWidth() const { return mObj->mWidth; } 00047 int getHeight() const { return mObj->mHeight; } 00049 Vec2i getSize() const { return Vec2i( mObj->mWidth, mObj->mHeight ); } 00051 Area getBounds() const { return Area( 0, 0, mObj->mWidth, mObj->mHeight ); } 00053 float getAspectRatio() const { return mObj->mWidth / (float)mObj->mHeight; } 00055 const Format& getFormat() const { return mObj->mFormat; } 00057 GLenum getTarget() const { return mObj->mFormat.mTarget; } 00058 00060 Texture& getTexture(); 00062 Texture& getDepthTexture(); 00063 00065 void bindTexture( int textureUnit = 0 ); 00067 void unbindTexture(); 00069 void bindDepthTexture( int textureUnit = 0 ); 00071 void bindFramebuffer(); 00073 static void unbindFramebuffer(); 00074 00076 static GLint getMaxSamples(); 00077 00078 struct Format { 00079 public: 00081 Format(); 00082 00084 void setTarget( GLenum target ) { mTarget = target; } 00086 void setColorInternalFormat( GLenum colorInternalFormat ) { mColorInternalFormat = colorInternalFormat; } 00088 void setDepthInternalFormat( GLenum depthInternalFormat ) { mDepthInternalFormat = depthInternalFormat; } 00090 void setSamples( int samples ) { mSamples = samples; } 00092 void setCoverageSamples( int coverageSamples ) { mCoverageSamples = coverageSamples; } 00094 void enableColorBuffer( bool colorBuffer = true ) { mColorBuffer = colorBuffer; } 00096 void enableDepthBuffer( bool depthBuffer = true ) { mDepthBuffer = depthBuffer; } 00097 // void enableStencilBuffer( bool stencilBuffer = true ) { mStencilBuffer = stencilBuffer; } 00099 void enableMipmapping( bool enableMipmapping = true ) { mMipmapping = enableMipmapping; } 00100 00102 void setWrap( GLenum wrapS, GLenum wrapT ) { setWrapS( wrapS ); setWrapT( wrapT ); } 00105 void setWrapS( GLenum wrapS ) { mWrapS = wrapS; } 00108 void setWrapT( GLenum wrapT ) { mWrapT = wrapT; } 00111 void setMinFilter( GLenum minFilter ) { mMinFilter = minFilter; } 00114 void setMagFilter( GLenum magFilter ) { mMagFilter = magFilter; } 00115 00116 00118 GLenum getTarget() const { return mTarget; } 00120 GLenum getColorInternalFormat() const { return mColorInternalFormat; } 00122 GLenum getDepthInternalFormat() const { return mDepthInternalFormat; } 00124 int getSamples() const { return mSamples; } 00126 int getCoverageSamples() const { return mCoverageSamples; } 00128 bool hasColorBuffer() const { return mColorBuffer; } 00130 bool hasDepthBuffer() const { return mDepthBuffer; } 00131 // bool hasStencilBuffer() const { return mStencilBuffer; } 00133 bool hasMipMapping() const { return mMipmapping; } 00134 00135 protected: 00136 GLenum mTarget; 00137 GLenum mColorInternalFormat, mDepthInternalFormat; 00138 int mSamples; 00139 int mCoverageSamples; 00140 bool mMipmapping; 00141 bool mColorBuffer, mDepthBuffer, mStencilBuffer; 00142 GLenum mWrapS, mWrapT; 00143 GLenum mMinFilter, mMagFilter; 00144 00145 friend class Fbo; 00146 }; 00147 00148 protected: 00149 void init(); 00150 bool initMultisample( bool csaa ); 00151 void resolveTexture() const; 00152 void updateMipmaps( bool bindFirst ) const; 00153 bool checkStatus( class FboExceptionInvalidSpecification *resultExc ); 00154 00155 struct Obj { 00156 Obj(); 00157 Obj( int aWidth, int aHeight ); 00158 ~Obj(); 00159 00160 int mWidth, mHeight; 00161 Format mFormat; 00162 GLuint mId, mColorTextureId, mDepthTextureId; 00163 GLuint mColorRenderBufferId, mDepthRenderBufferId, mResolveFramebufferId; 00164 Texture mColorTexture, mDepthTexture; 00165 mutable bool mNeedsResolve, mNeedsMipmapUpdate; 00166 }; 00167 00168 shared_ptr<Obj> mObj; 00169 00170 static GLint sMaxSamples; 00171 00172 public: 00174 00175 typedef shared_ptr<Obj> Fbo::*unspecified_bool_type; 00176 operator unspecified_bool_type() { return ( mObj.get() == 0 ) ? 0 : &Fbo::mObj; } 00177 void reset() { mObj.reset(); } 00179 }; 00180 00181 class FboException : public Exception { 00182 }; 00183 00184 class FboExceptionInvalidSpecification : public FboException { 00185 public: 00186 FboExceptionInvalidSpecification() : FboException() { mMessage[0] = 0; } 00187 FboExceptionInvalidSpecification( const std::string &message ) throw(); 00188 00189 virtual const char * what() const throw() { return mMessage; } 00190 00191 private: 00192 char mMessage[256]; 00193 }; 00194 00195 } // namespace gl 00196 } // namespace cinder