Visualization Library

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

X:/dropbox/visualizationlibrary/src/vlGraphics/DrawPixels.cpp

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 #include <vlGraphics/DrawPixels.hpp>
00033 #include <vlGraphics/Actor.hpp>
00034 #include <vlGraphics/Camera.hpp>
00035 #include <vlGraphics/BufferObject.hpp>
00036 #include <vlCore/Log.hpp>
00037 #include <map>
00038 
00039 using namespace vl;
00040 
00041 //-----------------------------------------------------------------------------
00042 // DrawPixels::Pixels
00043 //-----------------------------------------------------------------------------
00044 DrawPixels::Pixels::Pixels()
00045 {
00046   VL_DEBUG_SET_OBJECT_NAME()
00047   mAlign = AlignBottom | AlignLeft;
00048 }
00049 //-----------------------------------------------------------------------------
00050 DrawPixels::Pixels::Pixels(ImagePBO* img, int scrx, int scry, int startx, int starty, int width, int height, int alignment)
00051 {
00052   VL_DEBUG_SET_OBJECT_NAME()
00053 
00054   mAlign = alignment;
00055 
00056   if (width < 0)
00057     width = img->width()  - startx;
00058 
00059   if (height < 0)
00060     height = img->height() - starty;
00061 
00062   mImage     = img;
00063   mPosition  = ivec2(scrx, scry);
00064   mStart     = ivec2(startx, starty);
00065   mSize      = ivec2(width, height);
00066 }
00067 //-----------------------------------------------------------------------------
00068 DrawPixels::Pixels::Pixels(const Pixels& other): Object(other)
00069 {
00070   VL_DEBUG_SET_OBJECT_NAME()
00071 
00072   *this = other;
00073 }
00074 //-----------------------------------------------------------------------------
00075 DrawPixels::Pixels& DrawPixels::Pixels::operator=(const Pixels& other)
00076 {
00077   mImage = other.mImage;
00078   mPosition = other.mPosition;
00079   mStart = other.mStart;
00080   mSize  = other.mSize;
00081   mAlign = other.mAlign;
00082   return *this;
00083 }
00084 //-----------------------------------------------------------------------------
00085 DrawPixels::Pixels::~Pixels()
00086 {
00087 }
00088 //-----------------------------------------------------------------------------
00089 void DrawPixels::Pixels::deletePixelBufferObject()
00090 {
00091   image()->pixelBufferObject()->deleteBufferObject();
00092 }
00093 //-----------------------------------------------------------------------------
00094 bool DrawPixels::Pixels::generatePixelBufferObject(EBufferObjectUsage usage, bool discard_local_storage)
00095 {
00096   VL_CHECK(image())
00097   if (!image())
00098     return false;
00099   image()->pixelBufferObject()->setBufferData( (GLsizeiptr)image()->imageBuffer()->bytesUsed(), image()->imageBuffer()->ptr(), usage );
00100   if (discard_local_storage)
00101     image()->imageBuffer()->clear();
00102   return true;
00103 }
00104 //-----------------------------------------------------------------------------
00105 bool DrawPixels::Pixels::hasPixelBufferObject() const
00106 {
00107   return image()->pixelBufferObject()->handle() != 0;
00108 }
00109 //-----------------------------------------------------------------------------
00110 // DrawPixels
00111 //-----------------------------------------------------------------------------
00112 DrawPixels::DrawPixels()
00113 {
00114   mUsePixelBufferObject = false;
00115   mDraws.setAutomaticDelete(false);
00116 }
00117 //-----------------------------------------------------------------------------
00118 void DrawPixels::render_Implementation(const Actor* actor, const Shader*, const Camera* camera, OpenGLContext*) const
00119 {
00120   VL_CHECK_OGL()
00121 
00122   int viewport[] = { camera->viewport()->x(), camera->viewport()->y(), camera->viewport()->width(), camera->viewport()->height() };
00123 
00124   glMatrixMode(GL_MODELVIEW);
00125   glPushMatrix();
00126   glLoadIdentity();
00127   VL_CHECK_OGL();
00128 
00129   glMatrixMode(GL_PROJECTION);
00130   glPushMatrix();
00131   glLoadIdentity();
00132   glOrtho( -0.5f, viewport[2]-0.5f, -0.5f, viewport[3]-0.5f, -1.0f, +1.0f ); VL_CHECK_OGL();
00133 
00134   glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); VL_CHECK_OGL();
00135 
00136   for(int i=0; i<(int)mDraws.size(); ++i)
00137   {
00138     const Pixels* cmd = draws()->at(i);
00139 
00140     if (cmd->image() == 0)
00141       continue;
00142 
00143     const BufferObject* glbuf = cmd->image()->pixelBufferObject();
00144 
00145     VL_CHECK( cmd->image() )
00146     VL_CHECK( glbuf )
00147     VL_CHECK( glbuf->handle() || cmd->image()->pixels() )
00148     VL_CHECK( cmd->image()->isValid() )
00149     VL_CHECK( cmd->mStart.x() >= 0 )
00150     VL_CHECK( cmd->mStart.y() >= 0 )
00151 
00152     //VL_CHECK( cmd->mStart.x()+cmd->mSize.x() -1 < cmd->image()->width() )
00153     //VL_CHECK( cmd->mStart.y()+cmd->mSize.y() -1 < cmd->image()->height() )
00154 
00155     int pos_x = cmd->mPosition.x();
00156     int pos_y = cmd->mPosition.y();
00157 
00158     // alignment
00159 
00160     if (cmd->align() & AlignRight)
00161       pos_x -= cmd->mSize.x() -1;
00162     if (cmd->align() & AlignHCenter)
00163       pos_x -= cmd->mSize.x() / 2;
00164     if (cmd->align() & AlignTop)
00165       pos_y -= cmd->mSize.y() -1;
00166     if (cmd->align() & AlignVCenter)
00167       pos_y -= cmd->mSize.y() / 2;
00168 
00169     // transform following
00170 
00171     if ( camera && actor && actor->transform() )
00172     {
00173       vec4 v(0,0,0,1);
00174       v = actor->transform()->worldMatrix() * v;
00175 
00176       camera->project(v,v);
00177 
00178       // from screen space to viewport space
00179       v.x() -= viewport[0];
00180       v.y() -= viewport[1];
00181 
00182       pos_x += int(v.x() + 0.5);
00183       pos_y += int(v.y() + 0.5);
00184     }
00185 
00186     // culling
00187 
00188     if ( pos_x + cmd->mSize.x() -1 < 0 )
00189       continue;
00190 
00191     if ( pos_y + cmd->mSize.y() -1 < 0 )
00192       continue;
00193 
00194     if (pos_x > viewport[2] - 1)
00195       continue;
00196 
00197     if (pos_y > viewport[3] - 1)
00198       continue;
00199 
00200     // clipping
00201 
00202     int clip_left   = pos_x < 0 ? -pos_x : 0;
00203     int clip_bottom = pos_y < 0 ? -pos_y : 0;
00204     int clip_right  = (pos_x+cmd->mSize.x()-1)-( viewport[2]-1 );
00205     int clip_top    = (pos_y+cmd->mSize.y()-1)-( viewport[3]-1 );
00206 
00207     if (clip_right < 0)
00208       clip_right = 0;
00209 
00210     if (clip_top < 0)
00211       clip_top = 0;
00212 
00213     glRasterPos2f( /*0.5f +*/ (float)pos_x + clip_left, /*0.5f +*/ (float)pos_y + clip_bottom );
00214 
00215     // clear the current color, texture, normal
00216     glColor4f(1.0f,1.0f,1.0f,1.0f);
00217     glNormal3f(0,0,1.0f);
00218     glTexCoord3f(0,0,0);
00219     VL_CHECK_OGL()
00220 
00221     glPixelStorei( GL_UNPACK_ALIGNMENT, cmd->image()->byteAlignment() );
00222     glPixelStorei( GL_UNPACK_ROW_LENGTH, cmd->image()->width() );
00223     glPixelStorei( GL_UNPACK_SKIP_PIXELS, cmd->mStart.x() + clip_left );
00224     glPixelStorei( GL_UNPACK_SKIP_ROWS, cmd->mStart.y() + clip_bottom );
00225     VL_CHECK_OGL()
00226 
00227     if ( glbuf->handle() )
00228     {
00229       VL_glBindBuffer( GL_PIXEL_UNPACK_BUFFER, glbuf->handle() ); VL_CHECK_OGL()
00230       glDrawPixels( cmd->mSize.x() -clip_left -clip_right, cmd->mSize.y() -clip_bottom -clip_top, cmd->image()->format(), cmd->image()->type(), 0 );
00231       VL_CHECK_OGL();
00232     }
00233     else
00234     {
00235       VL_glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0 );
00236       glDrawPixels( cmd->mSize.x() -clip_left -clip_right, cmd->mSize.y() -clip_bottom -clip_top, cmd->image()->format(), cmd->image()->type(), cmd->image()->pixels() );
00237       VL_CHECK_OGL();
00238     }
00239   }
00240 
00241   VL_CHECK_OGL();
00242 
00243   VL_glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0 );
00244 
00245   VL_CHECK_OGL()
00246 
00247   // restores the default values
00248   glPopClientAttrib();
00249   VL_CHECK_OGL();
00250 
00251   glMatrixMode(GL_MODELVIEW);
00252   glPopMatrix(); VL_CHECK_OGL()
00253 
00254   glMatrixMode(GL_PROJECTION);
00255   glPopMatrix(); VL_CHECK_OGL()
00256 }
00257 //-----------------------------------------------------------------------------
00259 void DrawPixels::deletePixelBufferObjects()
00260 {
00261   VL_CHECK_OGL()
00262   for(int i=0; i<(int)mDraws.size(); ++i)
00263   {
00264     mDraws[i]->image()->pixelBufferObject()->deleteBufferObject();
00265   }
00266   VL_CHECK_OGL()
00267 }
00268 //-----------------------------------------------------------------------------
00269 void DrawPixels::releaseImages()
00270 {
00271   for(int i=0; i<(int)mDraws.size(); ++i)
00272     mDraws[i]->mImage = NULL;
00273 }
00274 //-----------------------------------------------------------------------------
00276 bool DrawPixels::generatePixelBufferObjects(EBufferObjectUsage usage, bool discard_local_storage)
00277 {
00278   if ( !( Has_GL_ARB_pixel_buffer_object||Has_GL_EXT_pixel_buffer_object ) )
00279     return false;
00280 
00281   // generates PBOs if they have an attached Image
00282 
00283   // avoids to PBO duplicates for the same images
00284   std::map< ref<Image>, unsigned int> pbomap;
00285 
00286   for(int i=0; i<(int)mDraws.size(); ++i)
00287   {
00288     if ( mDraws[i]->hasPixelBufferObject() )
00289       continue;
00290 
00291     if ( mDraws[i]->mImage.get() == NULL )
00292       continue;
00293 
00294     mDraws[i]->generatePixelBufferObject(usage, discard_local_storage);
00295   }
00296   return true;
00297 }
00298 //-----------------------------------------------------------------------------
00299 void DrawPixels::setUsePixelBufferObject(bool use_pbo)
00300 {
00301   if ( (Has_GL_ARB_pixel_buffer_object||Has_GL_EXT_pixel_buffer_object) )
00302     mUsePixelBufferObject = use_pbo;
00303   else
00304     mUsePixelBufferObject = false;
00305 }
00306 //-----------------------------------------------------------------------------

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