00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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
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 } }