Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlGraphics/ReadPixels.hpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #ifndef CameraReadPixels_INCLUDE_ONCE
00033 #define CameraReadPixels_INCLUDE_ONCE
00034 
00035 #include <vlGraphics/Camera.hpp>
00036 #include <vlCore/Say.hpp>
00037 #include <vlCore/Log.hpp>
00038 #include <vlGraphics/RenderEventCallback.hpp>
00039 #include <vlGraphics/BufferObject.hpp>
00040 #include <vlCore/Image.hpp>
00041 
00042 namespace vl
00043 {
00044   //-----------------------------------------------------------------------------
00045   // vl::readPixels()
00046   //-----------------------------------------------------------------------------
00054   inline void readPixels(Image* image, int x, int y, int w, int h, EReadDrawBuffer read_buffer, bool store_in_pixel_buffer_object)
00055   {
00056     // clears OpenGL errors
00057     glGetError();
00058 
00059 #if defined(VL_OPENGL)
00060     glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
00061 #endif
00062 
00063     glPixelStorei( GL_PACK_ALIGNMENT,   1);
00064 #if defined(VL_OPENGL)
00065     glPixelStorei( GL_PACK_ROW_LENGTH,  w);
00066     glPixelStorei( GL_PACK_SKIP_PIXELS, 0);
00067     glPixelStorei( GL_PACK_SKIP_ROWS,   0);
00068     glPixelStorei( GL_PACK_SWAP_BYTES,  0);
00069     glPixelStorei( GL_PACK_LSB_FIRST,   0);
00070     if (Has_GL_Version_1_2||Has_GL_Version_3_0||Has_GL_Version_4_0) // Texture 3D but excluding EOS
00071     {
00072       glPixelStorei( GL_PACK_IMAGE_HEIGHT, 0 );
00073       glPixelStorei( GL_PACK_SKIP_IMAGES,  0 );
00074     }
00075 
00076     int prev = 0;
00077     glGetIntegerv( GL_READ_BUFFER, &prev ); VL_CHECK_OGL()
00078     glReadBuffer( read_buffer );
00079 #endif
00080 
00081     #ifndef NDEBUG
00082       if (glGetError() != GL_NO_ERROR)
00083       {
00084         Log::print(Say("Image::readPixels() error: %s:%n\n"
00085           "You seem to have specified a wrong read buffer for the bound render target,\n"
00086           "for example you might have specified a RDB_BACK_LEFT but the active camera\n"
00087           "is bound to a FBO (Framebuffer Object) render target or the selected\n"
00088           "read buffer is FBO-specific (like RDB_COLOR_ATTACHMENT0_EXT) but the active\n"
00089           "camera is not bound to a FBO render target. \n") << __FILE__ << __LINE__
00090         );
00091         VL_TRAP()
00092       }
00093     #endif
00094 
00095     bool supports_pbo = Has_GL_ARB_pixel_buffer_object||Has_GL_EXT_pixel_buffer_object||Has_GL_Version_2_1;
00096 
00097     if (store_in_pixel_buffer_object && supports_pbo)
00098     {
00099       // mic fixme: test
00100       BufferObject* glbuf = cast<BufferObject>(image->imageBuffer()); VL_CHECK(glbuf);
00101 
00102       int bytes = image->requiredMemory2D(w, h, 1, image->format(), image->type());
00103       // allocates the PBO
00104       glbuf->setBufferData( bytes, NULL, glbuf->usage() );
00105       // bind the pbo
00106       VL_glBindBuffer( GL_PIXEL_PACK_BUFFER, glbuf->handle() );
00107       // read pixels into the pbo
00108       glReadPixels( x, y, w, h, image->format(), image->type(), 0);
00109       // unbind the pbo
00110       VL_glBindBuffer( GL_PIXEL_PACK_BUFFER, 0 );
00111 
00112       // deallocates the local storage and sets up the image configuration
00113       image->reset(w, h, 0, 1, image->format(), image->type(), false);
00114 
00115       // test GPU -> local copy
00116       //if (w != image->width() || h != image->height() || image->dimension() != ID_2D || image->pixels() == NULL)
00117       //  image->allocate2D( w, h, 1, image->format(), image->type() );
00118       //glbuf->downloadBufferObject();
00119     }
00120     else
00121     {
00122       if (w != image->width() || h != image->height() || image->dimension() != ID_2D || image->pixels() == NULL)
00123         image->allocate2D( w, h, 1, image->format(), image->type() );
00124       glReadPixels( x, y, w, h, image->format(), image->type(), image->pixels() );
00125     }
00126 
00127 #if defined(VL_OPENGL)
00128     // restore read buffer
00129     glReadBuffer( prev );
00130 
00131     glPopClientAttrib();
00132 #endif
00133 
00134     VL_CHECK_OGL()
00135   }
00136   //-----------------------------------------------------------------------------
00137   // ReadPixels
00138   //-----------------------------------------------------------------------------
00152   class ReadPixels: public RenderEventCallback
00153   {
00154     VL_INSTRUMENT_CLASS(vl::ReadPixels, RenderEventCallback)
00155 
00156   public:
00157     ReadPixels():
00158       mX ( 0 ),
00159       mY ( 0 ),
00160       mWidth ( 0 ),
00161       mHeight ( 0 ),
00162       mReadBuffer ( RDB_BACK_LEFT ),
00163       mStoreInPixelBufferObject(false)
00164     {
00165       VL_DEBUG_SET_OBJECT_NAME()
00166     }
00167 
00168     ReadPixels(int x, int y, int width, int height, EReadDrawBuffer read_buffer, Image* image, bool store_in_pbo):
00169       mX ( x ),
00170       mY ( y ),
00171       mWidth  ( width ),
00172       mHeight ( height ),
00173       mReadBuffer ( read_buffer ),
00174       mImage ( image ),
00175       mStoreInPixelBufferObject( store_in_pbo )
00176     {
00177       VL_DEBUG_SET_OBJECT_NAME()
00178     }
00179 
00180     virtual bool onRenderingStarted(const RenderingAbstract*)
00181     {
00182       readPixels();
00183       return true;
00184     }
00185 
00186     virtual bool onRenderingFinished(const RenderingAbstract*)
00187     {
00188       readPixels();
00189       return true;
00190     }
00191 
00192     virtual bool onRendererStarted(const RendererAbstract*)
00193     {
00194       readPixels();
00195       return true;
00196     }
00197 
00198     virtual bool onRendererFinished(const RendererAbstract*)
00199     {
00200       readPixels();
00201       return true;
00202     }
00203 
00204     void setup(int x, int y, int width, int height, EReadDrawBuffer read_buffer, bool store_in_pbo)
00205     {
00206       mX = x;
00207       mY = y;
00208       mWidth  = width;
00209       mHeight = height;
00210       mReadBuffer = read_buffer;
00211       mStoreInPixelBufferObject = store_in_pbo;
00212     }
00213 
00214     void setX(int x) { mX = x; }
00215     void setY(int y) { mY = y; }
00216     void setWidth(int width) { mWidth = width; }
00217     void setHeight(int height) { mHeight = height; }
00218     void setReadBuffer(EReadDrawBuffer buffer) { mReadBuffer = buffer; }
00219     void setImage(Image* image) { mImage = image; }
00220     void setSavePath(const String& path) { mSavePath = path; }
00221 
00222     int x() const { return mX; }
00223     int y() const { return mY; }
00224     int width() const { return mWidth; }
00225     int height() const { return mHeight; }
00226     EReadDrawBuffer readBuffer() const { return mReadBuffer; }
00227     Image* image() { return mImage.get(); }
00228     const Image* image() const { return mImage.get(); }
00229     const String& savePath() const { return mSavePath; }
00230 
00231     void setStoreInPixelBufferObject( bool use_pbo ) { mStoreInPixelBufferObject = use_pbo; }
00232     bool storeInPixelBufferObject() const { return mStoreInPixelBufferObject; }
00233 
00234   protected:
00235     void readPixels()
00236     {
00237       if (mImage.get() == NULL)
00238         mImage = new Image;
00239       vl::readPixels(mImage.get(), mX, mY, mWidth, mHeight, mReadBuffer, storeInPixelBufferObject() );
00240       if ( savePath().length() )
00241       {
00242         if (!saveImage(mImage.get(), savePath()))
00243           Log::error( Say("ReadPixels: unknown format for file: '%s'\n") << savePath() );
00244       }
00245     }
00246 
00247   protected:
00248     int mX;
00249     int mY;
00250     int mWidth;
00251     int mHeight;
00252     EReadDrawBuffer mReadBuffer;
00253     ref<Image> mImage;
00254     String mSavePath;
00255     bool mStoreInPixelBufferObject;
00256   };
00257 }
00258 
00259 #endif

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:40.
Permission is granted to use this page to write and publish articles regarding Visualization Library.