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 Renderbuffer { 00034 public: 00036 Renderbuffer() {} 00038 #if defined( CINDER_GLES ) 00039 Renderbuffer( int width, int height, GLenum internalFormat = GL_RGBA8_OES ); 00040 #else 00041 Renderbuffer( int width, int height, GLenum internalFormat = GL_RGBA8 ); 00042 #endif 00043 00044 Renderbuffer( int width, int height, GLenum internalFormat, int msaaSamples, int coverageSamples = 0 ); 00045 00047 int getWidth() const { return mObj->mWidth; } 00049 int getHeight() const { return mObj->mHeight; } 00051 Vec2i getSize() const { return Vec2i( mObj->mWidth, mObj->mHeight ); } 00053 Area getBounds() const { return Area( 0, 0, mObj->mWidth, mObj->mHeight ); } 00055 float getAspectRatio() const { return mObj->mWidth / (float)mObj->mHeight; } 00056 00058 GLuint getId() const { return mObj->mId; } 00060 GLenum getInternalFormat() const { return mObj->mInternalFormat; } 00062 int getSamples() const { return mObj->mSamples; } 00064 int getCoverageSamples() const { return mObj->mCoverageSamples; } 00065 00066 private: 00067 struct Obj { 00068 Obj(); 00069 Obj( int aWidth, int aHeight, GLenum internalFormat, int msaaSamples, int coverageSamples ); 00070 ~Obj(); 00071 00072 int mWidth, mHeight; 00073 GLuint mId; 00074 GLenum mInternalFormat; 00075 int mSamples, mCoverageSamples; 00076 }; 00077 00078 std::shared_ptr<Obj> mObj; 00079 00080 public: 00082 00083 typedef std::shared_ptr<Obj> Renderbuffer::*unspecified_bool_type; 00084 operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &Renderbuffer::mObj; } 00085 void reset() { mObj.reset(); } 00087 }; 00088 00090 class Fbo { 00091 public: 00092 struct Format; 00093 00095 Fbo() {} 00097 Fbo( int width, int height, Format format = Format() ); 00099 Fbo( int width, int height, bool alpha, bool color = true, bool depth = true ); 00100 00102 int getWidth() const { return mObj->mWidth; } 00104 int getHeight() const { return mObj->mHeight; } 00106 Vec2i getSize() const { return Vec2i( mObj->mWidth, mObj->mHeight ); } 00108 Area getBounds() const { return Area( 0, 0, mObj->mWidth, mObj->mHeight ); } 00110 float getAspectRatio() const { return mObj->mWidth / (float)mObj->mHeight; } 00112 const Format& getFormat() const { return mObj->mFormat; } 00114 GLenum getTarget() const { return mObj->mFormat.mTarget; } 00115 00117 Texture& getTexture( int attachment = 0 ); 00119 Texture& getDepthTexture(); 00120 00122 void bindTexture( int textureUnit = 0, int attachment = 0 ); 00124 void unbindTexture(); 00126 void bindDepthTexture( int textureUnit = 0 ); 00128 void bindFramebuffer(); 00130 static void unbindFramebuffer(); 00131 00133 GLuint getId() const { return mObj->mId; } 00134 00135 #if ! defined( CINDER_GLES ) 00136 00137 GLuint getResolveId() const { if( mObj->mResolveFramebufferId ) return mObj->mResolveFramebufferId; else return mObj->mId; } 00138 00140 void blitTo( Fbo dst, const Area &srcArea, const Area &dstArea, GLenum filter = GL_NEAREST, GLbitfield mask = GL_COLOR_BUFFER_BIT ) const; 00142 void blitToScreen( const Area &srcArea, const Area &dstArea, GLenum filter = GL_NEAREST, GLbitfield mask = GL_COLOR_BUFFER_BIT ) const; 00144 void blitFromScreen( const Area &srcArea, const Area &dstArea, GLenum filter = GL_NEAREST, GLbitfield mask = GL_COLOR_BUFFER_BIT ); 00145 #endif 00146 00148 static GLint getMaxSamples(); 00150 static GLint getMaxAttachments(); 00151 00152 struct Format { 00153 public: 00155 Format(); 00156 00158 void setTarget( GLenum target ) { mTarget = target; } 00160 void setColorInternalFormat( GLenum colorInternalFormat ) { mColorInternalFormat = colorInternalFormat; } 00162 void setDepthInternalFormat( GLenum depthInternalFormat ) { mDepthInternalFormat = depthInternalFormat; } 00164 void setSamples( int samples ) { mSamples = samples; } 00166 void setCoverageSamples( int coverageSamples ) { mCoverageSamples = coverageSamples; } 00168 void enableColorBuffer( bool colorBuffer = true, int numColorBuffers = 1 ); 00170 void enableDepthBuffer( bool depthBuffer = true, bool asTexture = true ); 00171 // void enableStencilBuffer( bool stencilBuffer = true ) { mStencilBuffer = stencilBuffer; } 00173 void enableMipmapping( bool enableMipmapping = true ) { mMipmapping = enableMipmapping; } 00174 00176 void setWrap( GLenum wrapS, GLenum wrapT ) { setWrapS( wrapS ); setWrapT( wrapT ); } 00179 void setWrapS( GLenum wrapS ) { mWrapS = wrapS; } 00182 void setWrapT( GLenum wrapT ) { mWrapT = wrapT; } 00185 void setMinFilter( GLenum minFilter ) { mMinFilter = minFilter; } 00188 void setMagFilter( GLenum magFilter ) { mMagFilter = magFilter; } 00189 00191 GLenum getTarget() const { return mTarget; } 00193 GLenum getColorInternalFormat() const { return mColorInternalFormat; } 00195 GLenum getDepthInternalFormat() const { return mDepthInternalFormat; } 00197 int getSamples() const { return mSamples; } 00199 int getCoverageSamples() const { return mCoverageSamples; } 00201 bool hasColorBuffer() const { return mNumColorBuffers > 0; } 00203 int getNumColorBuffers() const { return mNumColorBuffers; } 00205 bool hasDepthBuffer() const { return mDepthBuffer; } 00207 bool hasDepthBufferTexture() const { return mDepthBufferAsTexture; } 00208 // bool hasStencilBuffer() const { return mStencilBuffer; } 00210 bool hasMipMapping() const { return mMipmapping; } 00211 00212 protected: 00213 GLenum mTarget; 00214 GLenum mColorInternalFormat, mDepthInternalFormat; 00215 int mSamples; 00216 int mCoverageSamples; 00217 bool mMipmapping; 00218 bool mDepthBuffer, mDepthBufferAsTexture, mStencilBuffer; 00219 int mNumColorBuffers; 00220 GLenum mWrapS, mWrapT; 00221 GLenum mMinFilter, mMagFilter; 00222 00223 friend class Fbo; 00224 }; 00225 00226 protected: 00227 void init(); 00228 bool initMultisample( bool csaa ); 00229 void resolveTextures() const; 00230 void updateMipmaps( bool bindFirst, int attachment ) const; 00231 bool checkStatus( class FboExceptionInvalidSpecification *resultExc ); 00232 00233 struct Obj { 00234 Obj(); 00235 Obj( int aWidth, int aHeight ); 00236 ~Obj(); 00237 00238 int mWidth, mHeight; 00239 Format mFormat; 00240 GLuint mId; 00241 GLuint mResolveFramebufferId; 00242 std::vector<Renderbuffer> mMultisampleColorRenderbuffers; 00243 Renderbuffer mMultisampleDepthRenderbuffer; 00244 std::vector<Texture> mColorTextures; 00245 Texture mDepthTexture; 00246 Renderbuffer mDepthRenderbuffer; 00247 mutable bool mNeedsResolve, mNeedsMipmapUpdate; 00248 }; 00249 00250 std::shared_ptr<Obj> mObj; 00251 00252 static GLint sMaxSamples, sMaxAttachments; 00253 00254 public: 00256 00257 typedef std::shared_ptr<Obj> Fbo::*unspecified_bool_type; 00258 operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &Fbo::mObj; } 00259 void reset() { mObj.reset(); } 00261 }; 00262 00263 class FboException : public Exception { 00264 }; 00265 00266 class FboExceptionInvalidSpecification : public FboException { 00267 public: 00268 FboExceptionInvalidSpecification() : FboException() { mMessage[0] = 0; } 00269 FboExceptionInvalidSpecification( const std::string &message ) throw(); 00270 00271 virtual const char * what() const throw() { return mMessage; } 00272 00273 private: 00274 char mMessage[256]; 00275 }; 00276 00277 } } // namespace cinder::gl