Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://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 //-----------------------------------------------------------------------------