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