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 #ifndef CopyTexSubImage_INCLUDE_ONCE
00033 #define CopyTexSubImage_INCLUDE_ONCE
00034
00035 #include <vlGraphics/Camera.hpp>
00036 #include <vlGraphics/Texture.hpp>
00037 #include <vlGraphics/RenderEventCallback.hpp>
00038
00039 namespace vl
00040 {
00041
00042
00043
00056 class CopyTexSubImage: public RenderEventCallback
00057 {
00058 VL_INSTRUMENT_ABSTRACT_CLASS(vl::CopyTexSubImage, RenderEventCallback)
00059
00060 public:
00061 CopyTexSubImage(): mReadBuffer(RDB_BACK_LEFT)
00062 {
00063 VL_DEBUG_SET_OBJECT_NAME()
00064 }
00065
00067 EReadDrawBuffer readBuffer() const { return mReadBuffer; }
00068
00070 void setReadBuffer(EReadDrawBuffer render_buffer) { mReadBuffer = render_buffer; }
00071
00072 virtual bool onRenderingStarted(const RenderingAbstract*)
00073 {
00074 copyPixels();
00075 return true;
00076 }
00077
00078 virtual bool onRenderingFinished(const RenderingAbstract*)
00079 {
00080 copyPixels();
00081 return true;
00082 }
00083
00084 virtual bool onRendererStarted(const RendererAbstract*)
00085 {
00086 copyPixels();
00087 return true;
00088 }
00089
00090 virtual bool onRendererFinished(const RendererAbstract*)
00091 {
00092 copyPixels();
00093 return true;
00094 }
00095
00099 virtual void copyPixels() = 0;
00100
00101 protected:
00102 EReadDrawBuffer mReadBuffer;
00103 };
00104
00106 class CopyTexSubImage1D: public CopyTexSubImage
00107 {
00108 VL_INSTRUMENT_CLASS(vl::CopyTexSubImage1D, CopyTexSubImage)
00109
00110 public:
00111 CopyTexSubImage1D(int level, int xoffset, int x, int y, int width, Texture* texture=NULL, EReadDrawBuffer read_buffer=RDB_BACK_LEFT)
00112 {
00113 VL_DEBUG_SET_OBJECT_NAME()
00114 mLevel = level;
00115 mXOffset = xoffset;
00116 mX = x;
00117 mY = y;
00118 mWidth = width;
00119 mTexture = texture;
00120 setReadBuffer(read_buffer);
00121 }
00122
00123 void setTexture(Texture* tex) { mTexture = tex; }
00124 void setLevel(int level) { mLevel = level; }
00125 void setXOffset(int xoffset) { mXOffset = xoffset; }
00126 void setX(int x) { mX = x; }
00127 void setY(int y) { mY = y; }
00128 void setWidth(int width) { mWidth = width; }
00129
00130 Texture* texture() { return mTexture.get(); }
00131 const Texture* texture() const { return mTexture.get(); }
00132 int level() const { return mLevel; }
00133 int xoffset() const { return mXOffset; }
00134 int x() const { return mX; }
00135 int y() const { return mY; }
00136 int width() const { return mWidth; }
00137
00138 virtual void copyPixels()
00139 {
00140 VL_CHECK_OGL()
00141 VL_CHECK(texture()->dimension() == TD_TEXTURE_1D)
00142
00143 VL_CHECK(texture()->handle())
00144 VL_CHECK(xoffset() >= 0)
00145 VL_CHECK(x() >= 0)
00146 VL_CHECK(y() >= 0)
00147 VL_CHECK(xoffset()+width() <= texture()->width())
00148
00149 #if defined(VL_OPENGL)
00150 int read_buffer = 0;
00151 if (!texture()->isDepthTexture())
00152 {
00153 glGetIntegerv(GL_READ_BUFFER, &read_buffer); VL_CHECK_OGL()
00154 glReadBuffer(readBuffer()); VL_CHECK_OGL()
00155 }
00156 #endif
00157
00158 glBindTexture(TD_TEXTURE_1D, texture()->handle() ); VL_CHECK_OGL()
00159 glCopyTexSubImage1D(TD_TEXTURE_1D, level(), xoffset(), x(), y(), width()); VL_CHECK_OGL()
00160 glBindTexture(TD_TEXTURE_1D, 0 ); VL_CHECK_OGL()
00161
00162 #if defined(VL_OPENGL)
00163 if (read_buffer)
00164 {
00165 glReadBuffer( read_buffer ); VL_CHECK_OGL()
00166 }
00167 #endif
00168 }
00169
00170 protected:
00171 ref<Texture> mTexture;
00172 int mLevel;
00173 int mXOffset;
00174 int mX;
00175 int mY;
00176 int mWidth;
00177 };
00178
00180 class CopyTexSubImage2D: public CopyTexSubImage
00181 {
00182 VL_INSTRUMENT_CLASS(vl::CopyTexSubImage2D, CopyTexSubImage)
00183
00184 public:
00185 CopyTexSubImage2D(int level, int xoffset, int yoffset, int x, int y, int width, int height, Texture* texture=NULL, ETex2DTarget target=T2DT_TEXTURE_2D, EReadDrawBuffer read_buffer=RDB_BACK_LEFT)
00186 {
00187 VL_DEBUG_SET_OBJECT_NAME()
00188
00189 mLevel = level;
00190 mXOffset = xoffset;
00191 mYOffset = yoffset;
00192 mX = x;
00193 mY = y;
00194 mWidth = width;
00195 mHeight = height;
00196 mTexture = texture;
00197 mTarget = target;
00198 setReadBuffer(read_buffer);
00199 }
00200
00201 void setTexture(Texture* tex) { mTexture = tex; }
00202 void setLevel(int level) { mLevel = level; }
00203 void setXOffset(int xoffset) { mXOffset = xoffset; }
00204 void setYOffset(int yoffset) { mYOffset = yoffset; }
00205 void setX(int x) { mX = x; }
00206 void setY(int y) { mY = y; }
00207 void setWidth(int width) { mWidth = width; }
00208 void setHeight(int height) { mHeight = height; }
00209 void setTarget(ETex2DTarget target) { mTarget = target; }
00210
00211 Texture* texture() { return mTexture.get(); }
00212 const Texture* texture() const { return mTexture.get(); }
00213 int level() const { return mLevel; }
00214 int xoffset() const { return mXOffset; }
00215 int yoffset() const { return mYOffset; }
00216 int x() const { return mX; }
00217 int y() const { return mY; }
00218 int width() const { return mWidth; }
00219 int height() const { return mHeight; }
00220 ETex2DTarget target() const { return mTarget; }
00221
00222 virtual void copyPixels()
00223 {
00224 VL_CHECK_OGL()
00225
00226 VL_CHECK(texture()->handle())
00227 VL_CHECK(xoffset() >= 0)
00228 VL_CHECK(yoffset() >= 0)
00229 VL_CHECK(x() >= 0)
00230 VL_CHECK(y() >= 0)
00231 VL_CHECK(xoffset()+width() <= texture()->width())
00232 VL_CHECK(yoffset()+height() <= texture()->height())
00233
00234 #if defined(VL_OPENGL)
00235 int read_buffer = 0;
00236 if (!texture()->isDepthTexture())
00237 {
00238 glGetIntegerv(GL_READ_BUFFER, &read_buffer); VL_CHECK_OGL()
00239 glReadBuffer(readBuffer()); VL_CHECK_OGL()
00240 }
00241 #endif
00242
00243 int bind_target = 0;
00244 switch( target() )
00245 {
00246 case T2DT_TEXTURE_CUBE_MAP_POSITIVE_X:
00247 case T2DT_TEXTURE_CUBE_MAP_NEGATIVE_X:
00248 case T2DT_TEXTURE_CUBE_MAP_POSITIVE_Y:
00249 case T2DT_TEXTURE_CUBE_MAP_NEGATIVE_Y:
00250 case T2DT_TEXTURE_CUBE_MAP_POSITIVE_Z:
00251 case T2DT_TEXTURE_CUBE_MAP_NEGATIVE_Z:
00252 bind_target = GL_TEXTURE_CUBE_MAP;
00253 break;
00254 default:
00255 bind_target = target();
00256 };
00257
00258 glBindTexture( bind_target, texture()->handle() ); VL_CHECK_OGL()
00259 glCopyTexSubImage2D( target(), level(), xoffset(), yoffset(), x(), y(), width(), height() ); VL_CHECK_OGL()
00260 glBindTexture( bind_target, 0 ); VL_CHECK_OGL()
00261
00262 #if defined(VL_OPENGL)
00263 if (read_buffer)
00264 {
00265 glReadBuffer( read_buffer ); VL_CHECK_OGL()
00266 }
00267 #endif
00268 }
00269
00270 protected:
00271 ref<Texture> mTexture;
00272 int mLevel;
00273 int mXOffset;
00274 int mYOffset;
00275 int mX;
00276 int mY;
00277 int mWidth;
00278 int mHeight;
00279 ETex2DTarget mTarget;
00280 };
00281
00283 class CopyTexSubImage3D: public CopyTexSubImage
00284 {
00285 VL_INSTRUMENT_CLASS(vl::CopyTexSubImage3D, CopyTexSubImage)
00286
00287 public:
00288 CopyTexSubImage3D(int level, int xoffset, int yoffset, int zoffset, int x, int y, int width, int height, Texture* texture, EReadDrawBuffer read_buffer=RDB_BACK_LEFT)
00289 {
00290 VL_DEBUG_SET_OBJECT_NAME()
00291
00292 mLevel = level;
00293 mXOffset = xoffset;
00294 mYOffset = yoffset;
00295 mZOffset = zoffset;
00296 mX = x;
00297 mY = y;
00298 mWidth = width;
00299 mHeight = height;
00300 mTexture = texture;
00301 setReadBuffer(read_buffer);
00302 }
00303
00304 void setTexture(Texture* tex) { mTexture = tex; }
00305 void setLevel(int level) { mLevel = level; }
00306 void setXOffset(int xoffset) { mXOffset = xoffset; }
00307 void setYOffset(int yoffset) { mYOffset = yoffset; }
00308 void setZOffset(int zoffset) { mZOffset = zoffset; }
00309 void setX(int x) { mX = x; }
00310 void setY(int y) { mY = y; }
00311 void setWidth(int width) { mWidth = width; }
00312 void setHeight(int height) { mHeight = height; }
00313
00314 Texture* texture() { return mTexture.get(); }
00315 const Texture* texture() const { return mTexture.get(); }
00316 int level() const { return mLevel; }
00317 int xoffset() const { return mXOffset; }
00318 int yoffset() const { return mYOffset; }
00319 int zoffset() const { return mZOffset; }
00320 int x() const { return mX; }
00321 int y() const { return mY; }
00322 int width() const { return mWidth; }
00323 int height() const { return mHeight; }
00324
00325 virtual void copyPixels()
00326 {
00327 if (Has_Texture_3D)
00328 {
00329 VL_CHECK_OGL()
00330 VL_CHECK( texture()->dimension() == TD_TEXTURE_3D )
00331
00332 VL_CHECK(texture()->handle())
00333 VL_CHECK(xoffset() >= 0)
00334 VL_CHECK(yoffset() >= 0)
00335 VL_CHECK(zoffset() >= 0)
00336 VL_CHECK(x() >= 0)
00337 VL_CHECK(y() >= 0)
00338 VL_CHECK(xoffset()+width() <= texture()->width())
00339 VL_CHECK(yoffset()+height() <= texture()->height())
00340 VL_CHECK(zoffset() < texture()->depth())
00341
00342 #if defined(VL_OPENGL)
00343 int read_buffer = 0;
00344 if (!texture()->isDepthTexture())
00345 {
00346 glGetIntegerv(GL_READ_BUFFER, &read_buffer); VL_CHECK_OGL()
00347 glReadBuffer(readBuffer()); VL_CHECK_OGL()
00348 }
00349 #endif
00350
00351 glBindTexture(texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
00352 VL_glCopyTexSubImage3D(texture()->dimension(), level(), xoffset(), yoffset(), zoffset(), x(), y(), width(), height()); VL_CHECK_OGL()
00353 glBindTexture(texture()->dimension(), 0 );
00354
00355 #if defined(VL_OPENGL)
00356 if (read_buffer)
00357 {
00358 glReadBuffer( read_buffer ); VL_CHECK_OGL()
00359 }
00360 #endif
00361 }
00362 else
00363 Log::error("CopyTexSubImage3D requires OpenGL 1.2!\n");
00364 }
00365
00366 protected:
00367 ref<Texture> mTexture;
00368 int mLevel;
00369 int mXOffset;
00370 int mYOffset;
00371 int mZOffset;
00372 int mX;
00373 int mY;
00374 int mWidth;
00375 int mHeight;
00376 };
00377
00378 }
00379
00380 #endif