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]
DrawPixels.cpp
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 
33 #include <vlGraphics/Actor.hpp>
34 #include <vlGraphics/Camera.hpp>
36 #include <vlCore/Log.hpp>
37 #include <map>
38 
39 using namespace vl;
40 
41 //-----------------------------------------------------------------------------
42 // DrawPixels::Pixels
43 //-----------------------------------------------------------------------------
45 {
46  VL_DEBUG_SET_OBJECT_NAME()
48 }
49 //-----------------------------------------------------------------------------
50 DrawPixels::Pixels::Pixels(ImagePBO* img, int scrx, int scry, int startx, int starty, int width, int height, int alignment)
51 {
52  VL_DEBUG_SET_OBJECT_NAME()
53 
54  mAlign = alignment;
55 
56  if (width < 0)
57  width = img->width() - startx;
58 
59  if (height < 0)
60  height = img->height() - starty;
61 
62  mImage = img;
63  mPosition = ivec2(scrx, scry);
64  mStart = ivec2(startx, starty);
65  mSize = ivec2(width, height);
66 }
67 //-----------------------------------------------------------------------------
69 {
70  VL_DEBUG_SET_OBJECT_NAME()
71 
72  *this = other;
73 }
74 //-----------------------------------------------------------------------------
76 {
77  mImage = other.mImage;
78  mPosition = other.mPosition;
79  mStart = other.mStart;
80  mSize = other.mSize;
81  mAlign = other.mAlign;
82  return *this;
83 }
84 //-----------------------------------------------------------------------------
86 {
87 }
88 //-----------------------------------------------------------------------------
90 {
92 }
93 //-----------------------------------------------------------------------------
95 {
96  VL_CHECK(image())
97  if (!image())
98  return false;
99  image()->pixelBufferObject()->setBufferData( (GLsizeiptr)image()->imageBuffer()->bytesUsed(), image()->imageBuffer()->ptr(), usage );
100  if (discard_local_storage)
101  image()->imageBuffer()->clear();
102  return true;
103 }
104 //-----------------------------------------------------------------------------
106 {
107  return image()->pixelBufferObject()->handle() != 0;
108 }
109 //-----------------------------------------------------------------------------
110 // DrawPixels
111 //-----------------------------------------------------------------------------
113 {
114  mUsePixelBufferObject = false;
115  mDraws.setAutomaticDelete(false);
116 }
117 //-----------------------------------------------------------------------------
118 void DrawPixels::render_Implementation(const Actor* actor, const Shader*, const Camera* camera, OpenGLContext*) const
119 {
120  VL_CHECK_OGL()
121 
122  int viewport[] = { camera->viewport()->x(), camera->viewport()->y(), camera->viewport()->width(), camera->viewport()->height() };
123 
124  glMatrixMode(GL_MODELVIEW);
125  glPushMatrix();
126  glLoadIdentity();
127  VL_CHECK_OGL();
128 
129  glMatrixMode(GL_PROJECTION);
130  glPushMatrix();
131  glLoadIdentity();
132  glOrtho( -0.5f, viewport[2]-0.5f, -0.5f, viewport[3]-0.5f, -1.0f, +1.0f ); VL_CHECK_OGL();
133 
134  glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); VL_CHECK_OGL();
135 
136  for(int i=0; i<(int)mDraws.size(); ++i)
137  {
138  const Pixels* cmd = draws()->at(i);
139 
140  if (cmd->image() == 0)
141  continue;
142 
143  const BufferObject* glbuf = cmd->image()->pixelBufferObject();
144 
145  VL_CHECK( cmd->image() )
146  VL_CHECK( glbuf )
147  VL_CHECK( glbuf->handle() || cmd->image()->pixels() )
148  VL_CHECK( cmd->image()->isValid() )
149  VL_CHECK( cmd->mStart.x() >= 0 )
150  VL_CHECK( cmd->mStart.y() >= 0 )
151 
152  //VL_CHECK( cmd->mStart.x()+cmd->mSize.x() -1 < cmd->image()->width() )
153  //VL_CHECK( cmd->mStart.y()+cmd->mSize.y() -1 < cmd->image()->height() )
154 
155  int pos_x = cmd->mPosition.x();
156  int pos_y = cmd->mPosition.y();
157 
158  // alignment
159 
160  if (cmd->align() & AlignRight)
161  pos_x -= cmd->mSize.x() -1;
162  if (cmd->align() & AlignHCenter)
163  pos_x -= cmd->mSize.x() / 2;
164  if (cmd->align() & AlignTop)
165  pos_y -= cmd->mSize.y() -1;
166  if (cmd->align() & AlignVCenter)
167  pos_y -= cmd->mSize.y() / 2;
168 
169  // transform following
170 
171  if ( camera && actor && actor->transform() )
172  {
173  vec4 v(0,0,0,1);
174  v = actor->transform()->worldMatrix() * v;
175 
176  camera->project(v,v);
177 
178  // from screen space to viewport space
179  v.x() -= viewport[0];
180  v.y() -= viewport[1];
181 
182  pos_x += int(v.x() + 0.5);
183  pos_y += int(v.y() + 0.5);
184  }
185 
186  // culling
187 
188  if ( pos_x + cmd->mSize.x() -1 < 0 )
189  continue;
190 
191  if ( pos_y + cmd->mSize.y() -1 < 0 )
192  continue;
193 
194  if (pos_x > viewport[2] - 1)
195  continue;
196 
197  if (pos_y > viewport[3] - 1)
198  continue;
199 
200  // clipping
201 
202  int clip_left = pos_x < 0 ? -pos_x : 0;
203  int clip_bottom = pos_y < 0 ? -pos_y : 0;
204  int clip_right = (pos_x+cmd->mSize.x()-1)-( viewport[2]-1 );
205  int clip_top = (pos_y+cmd->mSize.y()-1)-( viewport[3]-1 );
206 
207  if (clip_right < 0)
208  clip_right = 0;
209 
210  if (clip_top < 0)
211  clip_top = 0;
212 
213  glRasterPos2f( /*0.5f +*/ (float)pos_x + clip_left, /*0.5f +*/ (float)pos_y + clip_bottom );
214 
215  // clear the current color, texture, normal
216  glColor4f(1.0f,1.0f,1.0f,1.0f);
217  glNormal3f(0,0,1.0f);
218  glTexCoord3f(0,0,0);
219  VL_CHECK_OGL()
220 
221  glPixelStorei( GL_UNPACK_ALIGNMENT, cmd->image()->byteAlignment() );
222  glPixelStorei( GL_UNPACK_ROW_LENGTH, cmd->image()->width() );
223  glPixelStorei( GL_UNPACK_SKIP_PIXELS, cmd->mStart.x() + clip_left );
224  glPixelStorei( GL_UNPACK_SKIP_ROWS, cmd->mStart.y() + clip_bottom );
225  VL_CHECK_OGL()
226 
227  if ( glbuf->handle() )
228  {
229  VL_glBindBuffer( GL_PIXEL_UNPACK_BUFFER, glbuf->handle() ); VL_CHECK_OGL()
230  glDrawPixels( cmd->mSize.x() -clip_left -clip_right, cmd->mSize.y() -clip_bottom -clip_top, cmd->image()->format(), cmd->image()->type(), 0 );
231  VL_CHECK_OGL();
232  }
233  else
234  {
235  VL_glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0 );
236  glDrawPixels( cmd->mSize.x() -clip_left -clip_right, cmd->mSize.y() -clip_bottom -clip_top, cmd->image()->format(), cmd->image()->type(), cmd->image()->pixels() );
237  VL_CHECK_OGL();
238  }
239  }
240 
241  VL_CHECK_OGL();
242 
243  VL_glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0 );
244 
245  VL_CHECK_OGL()
246 
247  // restores the default values
248  glPopClientAttrib();
249  VL_CHECK_OGL();
250 
251  glMatrixMode(GL_MODELVIEW);
252  glPopMatrix(); VL_CHECK_OGL()
253 
254  glMatrixMode(GL_PROJECTION);
255  glPopMatrix(); VL_CHECK_OGL()
256 }
257 //-----------------------------------------------------------------------------
260 {
261  VL_CHECK_OGL()
262  for(int i=0; i<(int)mDraws.size(); ++i)
263  {
264  mDraws[i]->image()->pixelBufferObject()->deleteBufferObject();
265  }
266  VL_CHECK_OGL()
267 }
268 //-----------------------------------------------------------------------------
270 {
271  for(int i=0; i<(int)mDraws.size(); ++i)
272  mDraws[i]->mImage = NULL;
273 }
274 //-----------------------------------------------------------------------------
276 bool DrawPixels::generatePixelBufferObjects(EBufferObjectUsage usage, bool discard_local_storage)
277 {
278  if ( !( Has_GL_ARB_pixel_buffer_object||Has_GL_EXT_pixel_buffer_object ) )
279  return false;
280 
281  // generates PBOs if they have an attached Image
282 
283  // avoids to PBO duplicates for the same images
284  std::map< ref<Image>, unsigned int> pbomap;
285 
286  for(int i=0; i<(int)mDraws.size(); ++i)
287  {
288  if ( mDraws[i]->hasPixelBufferObject() )
289  continue;
290 
291  if ( mDraws[i]->mImage.get() == NULL )
292  continue;
293 
294  mDraws[i]->generatePixelBufferObject(usage, discard_local_storage);
295  }
296  return true;
297 }
298 //-----------------------------------------------------------------------------
300 {
301  if ( (Has_GL_ARB_pixel_buffer_object||Has_GL_EXT_pixel_buffer_object) )
302  mUsePixelBufferObject = use_pbo;
303  else
304  mUsePixelBufferObject = false;
305 }
306 //-----------------------------------------------------------------------------
const Collection< Pixels > * draws() const
Definition: DrawPixels.hpp:142
Associates a Renderable object to an Effect and Transform.
Definition: Actor.hpp:130
int y() const
Definition: Viewport.hpp:67
Vector2< int > ivec2
A 2 components vector with int precision.
Definition: Vector2.hpp:278
const T_Scalar & x() const
Definition: Vector4.hpp:101
Transform * transform()
Returns the Transform bound tho an Actor.
Definition: Actor.hpp:190
const unsigned char * pixels() const
Raw pointer to pixels.
Definition: Image.hpp:170
void releaseImages()
Iterates on the Pixels objects and sets their Image references to NULL.
Definition: DrawPixels.cpp:269
bool mUsePixelBufferObject
Definition: DrawPixels.hpp:167
const BufferObject * pixelBufferObject() const
The associated OpenGL Buffer Object.
Definition: ImagePBO.hpp:71
Represents an OpenGL context, possibly a widget or a pbuffer, which can also respond to keyboard...
bool generatePixelBufferObject(EBufferObjectUsage usage, bool discard_local_storage)
Generates a pixel buffer object for the associated Image calling image()->bufferObject()->setBufferDa...
Definition: DrawPixels.cpp:94
void clear()
Definition: Buffer.hpp:119
bool isValid() const
Returns true if the image has valid width/height/depth, pitch and byte alignment, type/format combina...
Definition: Image.cpp:135
EBufferObjectUsage
void setUsePixelBufferObject(bool use_pbo)
Definition: DrawPixels.cpp:299
void deletePixelBufferObjects()
deallocate PBOs
Definition: DrawPixels.cpp:259
int byteAlignment() const
Returns the byte-alignment of the row of the image.
Definition: Image.cpp:540
Viewport * viewport()
The viewport bound to a camera.
Definition: Camera.hpp:141
Visualization Library main namespace.
Represents a bitmap to be drawn on the screen.
Definition: DrawPixels.hpp:71
bool project(const vec4 &in_world, vec4 &out_viewp) const
Projects a vector from world coordinates to viewport coordinates.
Definition: Camera.cpp:248
int height() const
Definition: Viewport.hpp:71
int height() const
Definition: Image.hpp:209
int width() const
Definition: Viewport.hpp:69
The base class for all the reference counted objects.
Definition: Object.hpp:158
Buffer * imageBuffer()
The buffer used to store the image pixels.
Definition: Image.hpp:164
Represents a vl::Image with an associated Pixel Buffer Object.
Definition: ImagePBO.hpp:44
int width() const
Definition: Image.hpp:207
const T_Scalar & y() const
Definition: Vector4.hpp:102
int x() const
Definition: Viewport.hpp:65
bool generatePixelBufferObjects(EBufferObjectUsage usage, bool discard_local_storage)
generates PBOs only for Pixels objects without a PBO handle
Definition: DrawPixels.cpp:276
#define NULL
Definition: OpenGLDefs.hpp:81
const mat4 & worldMatrix() const
Returns the world matrix used for rendering.
Definition: Transform.hpp:168
Manages most of the OpenGL rendering states responsible of the final aspect of the rendered objects...
Definition: Shader.hpp:1830
void render_Implementation(const Actor *actor, const Shader *shader, const Camera *camera, OpenGLContext *gl_context) const
Renders the bitamps.
Definition: DrawPixels.cpp:118
bool hasPixelBufferObject() const
Definition: DrawPixels.cpp:105
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< ImagePBO > mImage
Definition: DrawPixels.hpp:124
Pixels & operator=(const Pixels &other)
Definition: DrawPixels.cpp:75
EImageType type() const
Definition: Image.hpp:217
void setBufferData(EBufferObjectUsage usage, bool discard_local_storage=false)
const T_Scalar & x() const
Definition: Vector2.hpp:132
Represents a virtual camera defining, among other things, the point of view from which scenes can be ...
Definition: Camera.hpp:50
Collection< Pixels > mDraws
Definition: DrawPixels.hpp:166
const T_Scalar & y() const
Definition: Vector2.hpp:133
#define VL_CHECK(expr)
Definition: checks.hpp:73
EImageFormat format() const
Definition: Image.hpp:215