00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
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
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
00153
00154
00155 int pos_x = cmd->mPosition.x();
00156 int pos_y = cmd->mPosition.y();
00157
00158
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
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
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
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
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( (float)pos_x + clip_left, (float)pos_y + clip_bottom );
00214
00215
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
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
00282
00283
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