Visualization Library 2.0.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
ReadPixels.hpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
32 #ifndef CameraReadPixels_INCLUDE_ONCE
33 #define CameraReadPixels_INCLUDE_ONCE
34 
35 #include <vlGraphics/Camera.hpp>
36 #include <vlCore/Say.hpp>
37 #include <vlCore/Log.hpp>
40 #include <vlCore/Image.hpp>
41 
42 namespace vl
43 {
44  //-----------------------------------------------------------------------------
45  // vl::readPixels()
46  //-----------------------------------------------------------------------------
54  inline void readPixels(Image* image, int x, int y, int w, int h, EReadDrawBuffer read_buffer, bool store_in_pixel_buffer_object)
55  {
56  // clears OpenGL errors
57  glGetError();
58 
59 #if defined(VL_OPENGL)
60  glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
61 #endif
62 
63  glPixelStorei( GL_PACK_ALIGNMENT, 1);
64 #if defined(VL_OPENGL)
65  glPixelStorei( GL_PACK_ROW_LENGTH, w);
66  glPixelStorei( GL_PACK_SKIP_PIXELS, 0);
67  glPixelStorei( GL_PACK_SKIP_ROWS, 0);
68  glPixelStorei( GL_PACK_SWAP_BYTES, 0);
69  glPixelStorei( GL_PACK_LSB_FIRST, 0);
70  if (Has_GL_Version_1_2||Has_GL_Version_3_0||Has_GL_Version_4_0) // Texture 3D but excluding EOS
71  {
72  glPixelStorei( GL_PACK_IMAGE_HEIGHT, 0 );
73  glPixelStorei( GL_PACK_SKIP_IMAGES, 0 );
74  }
75 
76  int prev = 0;
77  glGetIntegerv( GL_READ_BUFFER, &prev ); VL_CHECK_OGL()
78  glReadBuffer( read_buffer );
79 #endif
80 
81  #ifndef NDEBUG
82  if (glGetError() != GL_NO_ERROR)
83  {
84  Log::print(Say("Image::readPixels() error: %s:%n\n"
85  "You seem to have specified a wrong read buffer for the bound render target,\n"
86  "for example you might have specified a RDB_BACK_LEFT but the active camera\n"
87  "is bound to a FBO (Framebuffer Object) render target or the selected\n"
88  "read buffer is FBO-specific (like RDB_COLOR_ATTACHMENT0_EXT) but the active\n"
89  "camera is not bound to a FBO render target. \n") << __FILE__ << __LINE__
90  );
91  VL_TRAP()
92  }
93  #endif
94 
95  bool supports_pbo = Has_GL_ARB_pixel_buffer_object||Has_GL_EXT_pixel_buffer_object||Has_GL_Version_2_1;
96 
97  if (store_in_pixel_buffer_object && supports_pbo)
98  {
99  // mic fixme: test
100  BufferObject* glbuf = cast<BufferObject>(image->imageBuffer()); VL_CHECK(glbuf);
101 
102  int bytes = image->requiredMemory2D(w, h, 1, image->format(), image->type());
103  // allocates the PBO
104  glbuf->setBufferData( bytes, NULL, glbuf->usage() );
105  // bind the pbo
106  VL_glBindBuffer( GL_PIXEL_PACK_BUFFER, glbuf->handle() );
107  // read pixels into the pbo
108  glReadPixels( x, y, w, h, image->format(), image->type(), 0);
109  // unbind the pbo
110  VL_glBindBuffer( GL_PIXEL_PACK_BUFFER, 0 );
111 
112  // deallocates the local storage and sets up the image configuration
113  image->reset(w, h, 0, 1, image->format(), image->type(), false);
114 
115  // test GPU -> local copy
116  //if (w != image->width() || h != image->height() || image->dimension() != ID_2D || image->pixels() == NULL)
117  // image->allocate2D( w, h, 1, image->format(), image->type() );
118  //glbuf->downloadBufferObject();
119  }
120  else
121  {
122  if (w != image->width() || h != image->height() || image->dimension() != ID_2D || image->pixels() == NULL)
123  image->allocate2D( w, h, 1, image->format(), image->type() );
124  glReadPixels( x, y, w, h, image->format(), image->type(), image->pixels() );
125  }
126 
127 #if defined(VL_OPENGL)
128  // restore read buffer
129  glReadBuffer( prev );
130 
131  glPopClientAttrib();
132 #endif
133 
134  VL_CHECK_OGL()
135  }
136  //-----------------------------------------------------------------------------
137  // ReadPixels
138  //-----------------------------------------------------------------------------
153  {
155 
156  public:
158  mX ( 0 ),
159  mY ( 0 ),
160  mWidth ( 0 ),
161  mHeight ( 0 ),
164  {
165  VL_DEBUG_SET_OBJECT_NAME()
166  }
167 
168  ReadPixels(int x, int y, int width, int height, EReadDrawBuffer read_buffer, Image* image, bool store_in_pbo):
169  mX ( x ),
170  mY ( y ),
171  mWidth ( width ),
172  mHeight ( height ),
173  mReadBuffer ( read_buffer ),
174  mImage ( image ),
175  mStoreInPixelBufferObject( store_in_pbo )
176  {
177  VL_DEBUG_SET_OBJECT_NAME()
178  }
179 
181  {
182  readPixels();
183  return true;
184  }
185 
187  {
188  readPixels();
189  return true;
190  }
191 
192  virtual bool onRendererStarted(const RendererAbstract*)
193  {
194  readPixels();
195  return true;
196  }
197 
199  {
200  readPixels();
201  return true;
202  }
203 
204  void setup(int x, int y, int width, int height, EReadDrawBuffer read_buffer, bool store_in_pbo)
205  {
206  mX = x;
207  mY = y;
208  mWidth = width;
209  mHeight = height;
210  mReadBuffer = read_buffer;
211  mStoreInPixelBufferObject = store_in_pbo;
212  }
213 
214  void setX(int x) { mX = x; }
215  void setY(int y) { mY = y; }
216  void setWidth(int width) { mWidth = width; }
217  void setHeight(int height) { mHeight = height; }
218  void setReadBuffer(EReadDrawBuffer buffer) { mReadBuffer = buffer; }
220  void setSavePath(const String& path) { mSavePath = path; }
221 
222  int x() const { return mX; }
223  int y() const { return mY; }
224  int width() const { return mWidth; }
225  int height() const { return mHeight; }
227  Image* image() { return mImage.get(); }
228  const Image* image() const { return mImage.get(); }
229  const String& savePath() const { return mSavePath; }
230 
231  void setStoreInPixelBufferObject( bool use_pbo ) { mStoreInPixelBufferObject = use_pbo; }
233 
234  protected:
235  void readPixels()
236  {
237  if (mImage.get() == NULL)
238  mImage = new Image;
240  if ( savePath().length() )
241  {
242  if (!saveImage(mImage.get(), savePath()))
243  Log::error( Say("ReadPixels: unknown format for file: '%s'\n") << savePath() );
244  }
245  }
246 
247  protected:
248  int mX;
249  int mY;
250  int mWidth;
251  int mHeight;
256  };
257 }
258 
259 #endif
virtual bool onRenderingFinished(const RenderingAbstract *)
Reimplement to react to this event.
Definition: ReadPixels.hpp:186
const String & savePath() const
Definition: ReadPixels.hpp:229
int y() const
Definition: ReadPixels.hpp:223
void setSavePath(const String &path)
Definition: ReadPixels.hpp:220
EReadDrawBuffer mReadBuffer
Definition: ReadPixels.hpp:252
A simple String formatting class.
Definition: Say.hpp:124
const unsigned char * pixels() const
Raw pointer to pixels.
Definition: Image.hpp:170
The RenderingAbstract class is the base of all the rendering related sub-classes. ...
bool Has_GL_Version_2_1
Definition: OpenGL.cpp:55
The String class implements an advanced UTF16 (Unicode BMP) string manipulation engine.
Definition: String.hpp:62
void reset(int x, int y, int z, int bytealign, EImageFormat format, EImageType type, bool is_cubemap)
Sets up the image configuration & clears the local storage.
Definition: Image.cpp:676
bool mStoreInPixelBufferObject
Definition: ReadPixels.hpp:255
void setStoreInPixelBufferObject(bool use_pbo)
Definition: ReadPixels.hpp:231
static void error(const String &message)
Use this function to provide information about run-time errors: file not found, out of memory...
Definition: Log.cpp:165
bool Has_GL_Version_4_0
Definition: OpenGL.cpp:60
bool Has_GL_Version_3_0
Definition: OpenGL.cpp:56
#define VL_INSTRUMENT_CLASS(ClassName, BaseClass)
Definition: TypeInfo.hpp:122
Image * image()
Definition: ReadPixels.hpp:227
EReadDrawBuffer
Visualization Library main namespace.
virtual bool onRendererFinished(const RendererAbstract *)
Reimplement to react to this event.
Definition: ReadPixels.hpp:198
void setWidth(int width)
Definition: ReadPixels.hpp:216
int length() const
Returns the length of the string.
Definition: String.hpp:133
An abstract class used to react to rendering events.
void setY(int y)
Definition: ReadPixels.hpp:215
int height() const
Definition: Image.hpp:209
#define VL_TRAP()
Definition: checks.hpp:70
virtual bool onRendererStarted(const RendererAbstract *)
Reimplement to react to this event.
Definition: ReadPixels.hpp:192
EBufferObjectUsage usage() const
BufferObject usage flag as specified by setBufferData().
VLCORE_EXPORT bool saveImage(Image *img, VirtualFile *file)
Writes an image on the specified file.
Definition: Image.cpp:1250
virtual bool onRenderingStarted(const RenderingAbstract *)
Reimplement to react to this event.
Definition: ReadPixels.hpp:180
EImageDimension dimension() const
Definition: Image.cpp:372
A RenderEventCallback that copyes a rectangular pixel area from a source buffer to an Image at the en...
Definition: ReadPixels.hpp:152
int width() const
Definition: ReadPixels.hpp:224
static void print(const String &message)
Application message for the user.
Definition: Log.cpp:136
Buffer * imageBuffer()
The buffer used to store the image pixels.
Definition: Image.hpp:164
EReadDrawBuffer readBuffer() const
Definition: ReadPixels.hpp:226
int width() const
Definition: Image.hpp:207
Base class providing all the basic funtionalities of a Renderer.
void setReadBuffer(EReadDrawBuffer buffer)
Definition: ReadPixels.hpp:218
void setImage(Image *image)
Definition: ReadPixels.hpp:219
#define NULL
Definition: OpenGLDefs.hpp:81
void setX(int x)
Definition: ReadPixels.hpp:214
void setup(int x, int y, int width, int height, EReadDrawBuffer read_buffer, bool store_in_pbo)
Definition: ReadPixels.hpp:204
The BufferObject class is a Buffer that can upload its data on the GPU memory.
#define VL_CHECK_OGL()
Definition: OpenGL.hpp:156
unsigned int handle() const
ref< Image > mImage
Definition: ReadPixels.hpp:253
int height() const
Definition: ReadPixels.hpp:225
EImageType type() const
Definition: Image.hpp:217
void setBufferData(EBufferObjectUsage usage, bool discard_local_storage=false)
int x() const
Definition: ReadPixels.hpp:222
void readPixels(Image *image, int x, int y, int w, int h, EReadDrawBuffer read_buffer, bool store_in_pixel_buffer_object)
Reads a rectangular pixel area from the specified read buffer and stores it in an Image...
Definition: ReadPixels.hpp:54
Implements a generic 1d, 2d, 3d and cubemap image that can have mipmaps.
Definition: Image.hpp:54
The ref<> class is used to reference-count an Object.
Definition: Object.hpp:55
void allocate2D(int x, int y, int bytealign, EImageFormat format, EImageType type)
Definition: Image.cpp:608
bool Has_GL_Version_1_2
Definition: OpenGL.cpp:50
ReadPixels(int x, int y, int width, int height, EReadDrawBuffer read_buffer, Image *image, bool store_in_pbo)
Definition: ReadPixels.hpp:168
const Image * image() const
Definition: ReadPixels.hpp:228
void setHeight(int height)
Definition: ReadPixels.hpp:217
#define VL_CHECK(expr)
Definition: checks.hpp:73
bool storeInPixelBufferObject() const
Definition: ReadPixels.hpp:232
static int requiredMemory2D(int x, int y, int bytealign, EImageFormat format, EImageType type)
Definition: Image.hpp:112
EImageFormat format() const
Definition: Image.hpp:215