00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef FARSA_USE_YARP_AND_ICUB
00021
00022 #include "wcamera.h"
00023 #include <QApplication>
00024 #include <QGLPixelBuffer>
00025
00026
00027
00028 #ifdef FARSA_MAC
00029 # include <GLUT/glut.h>
00030 #else
00031 # include <GL/glu.h>
00032 #endif
00033
00034 using namespace yarp::dev;
00035 using namespace yarp::sig;
00036 using namespace yarp::os;
00037
00038 #define GLMultMatrix glMultMatrixf
00039
00040
00041 namespace farsa {
00042
00043 RenderCamera::RenderCamera( WCamera* wcamera, WObject* attachTo, unsigned int width, unsigned int height )
00044 : RenderWObjectContainer() {
00045 connect( world(), SIGNAL( removedObject( WObject* ) ),
00046 this, SLOT( slotRemoveObject( WObject* ) ), Qt::DirectConnection );
00047 connect( world(), SIGNAL( addedObject( WObject* ) ),
00048 this, SLOT( slotAddObject( WObject* ) ), Qt::DirectConnection );
00049
00050 this->attachTo = attachTo;
00051 this->widthv = width;
00052 this->heightv = height;
00053 aspectRatio = 112.0f/94.0f;
00054 this->wcamera = wcamera;
00055
00056 frameBuffer = new unsigned char[width*height*3];
00057 frameImage.setQuantum(1);
00058 frameImage.setExternal( frameBuffer, width, height );
00059 frameImage.setTopIsLowIndex( true );
00060 pbuffer = new QGLPixelBuffer( width, height );
00061 initializeGL();
00062 }
00063
00064 RenderCamera::~RenderCamera() {
00065 delete[] frameBuffer;
00066
00067 delete pbuffer;
00068 }
00069
00070 void RenderCamera::moveRotatePointOfView( const wMatrix& tm ) {
00071 QMutexLocker locker(&mutex);
00072
00073
00074
00075
00076 eyep = tm.w_pos + tm.z_ax.scale(0.021f);
00077 atp = eyep + tm.z_ax;
00078 upv = -tm.x_ax;
00079 }
00080
00081 void RenderCamera::initializeGL() {
00082 pbuffer->makeCurrent();
00083 glEnable(GL_LIGHT0);
00084
00085
00086 glDisable(GL_LIGHTING);
00087 glDisable(GL_COLOR_MATERIAL);
00088
00089 glEnable(GL_DEPTH_TEST);
00090 glClearColor( 0.2f, 0.2f, 0.2f, 1.0f );
00091 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00092 glViewport( 0, 0, GLint(widthv), GLint(heightv) );
00093 pbuffer->doneCurrent();
00094 }
00095
00096 void RenderCamera::paintGL() {
00097
00098 ResourcesLocker resourceLocker(this);
00099 QMutexLocker locker(&mutex);
00100
00101 moveRotatePointOfView( wcamera->matrix() );
00102 pbuffer->makeCurrent();
00103 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00104
00105 glMatrixMode(GL_PROJECTION);
00106 glLoadIdentity();
00107 gluPerspective( 94.0, aspectRatio, 0.001 , 1000.0 );
00108
00109 glMatrixMode(GL_MODELVIEW);
00110 glLoadIdentity();
00111 gluLookAt( eyep[0], eyep[1], eyep[2], atp[0], atp[1], atp[2], upv[0], upv[1], upv[2] );
00112
00113
00114 drawSkyGroundBox( (QGLContext*)(QGLContext::currentContext()) );
00115
00116
00117 for( int i=0; i<graphics().size(); i++ ) {
00118 RenderWObject* r = graphics()[i];
00119 if ( r->object() == attachTo ) continue;
00120 if ( r->object() == wcamera ) continue;
00121 if ( r->object()->isInvisible() ) continue;
00122 if ( r->object()->owner() ) continue;
00123 r->render( (QGLContext*)(QGLContext::currentContext()) );
00124 }
00125 glReadPixels( 0, 0, widthv, heightv, GL_RGB, GL_UNSIGNED_BYTE, frameBuffer );
00126 pbuffer->doneCurrent();
00127 }
00128
00129 void RenderCamera::slotRemoveObject( WObject* w ) {
00130 removeObject( w );
00131 }
00132
00133 void RenderCamera::slotAddObject( WObject* w ) {
00134 addObject( w );
00135 }
00136
00137 bool RenderCamera::open( yarp::os::Searchable & ) {
00138 return true;
00139 }
00140
00141 bool RenderCamera::close( ) {
00142 return true;
00143 }
00144
00145 bool RenderCamera::configure( yarp::os::Searchable & ) {
00146 return true;
00147 }
00148
00149 int RenderCamera::height() const {
00150 return heightv;
00151 }
00152
00153 int RenderCamera::width() const {
00154 return widthv;
00155 }
00156
00157 bool RenderCamera::getImage( yarp::sig::ImageOf<yarp::sig::PixelRgb>& image ) {
00158 image.setTopIsLowIndex( false );
00159 image.copy( frameImage );
00160 return true;
00161 }
00162
00163 WCamera::WCamera( World* w, QString name, WObject* attachTo, unsigned int width, unsigned int height )
00164 : YarpObject( w, name ) {
00165
00166
00167
00168 if ( !qApp ) {
00169 images = NULL;
00170 } else {
00171 images = new RenderCamera( this, attachTo, width, height );
00172 images->setWorld(w);
00173 }
00174 setColor( Qt::green );
00175 this->attachTo = attachTo;
00176 setMatrix( attachTo->matrix() );
00177 w->pushObject( this );
00178
00179 porty.open( QString( "/%1/%2" ).arg( world()->name() ).arg( name ).toAscii().data() );
00180 }
00181
00182 WCamera::WCamera( World* w, QString name, unsigned int width, unsigned int height, const wMatrix& tm )
00183 : YarpObject( w, name ) {
00184
00185
00186
00187 if ( !qApp ) {
00188 images = NULL;
00189 } else {
00190 images = new RenderCamera( this, NULL, width, height );
00191 images->setWorld(w);
00192 }
00193 this->attachTo = NULL;
00194 setMatrix( tm );
00195 w->pushObject( this );
00196
00197 porty.open( QString( "/%1/%2" ).arg( world()->name() ).arg( name ).toAscii().data() );
00198 }
00199
00200 WCamera::~WCamera() {
00201 delete images;
00202 }
00203
00204 void WCamera::preUpdate() {
00205 if ( attachTo ) {
00206 setMatrix( attachTo->matrix() );
00207 }
00208 }
00209
00210 void WCamera::postUpdate() {
00211 if ( !images ) return;
00212 images->paintGL();
00213 ImageOf<PixelRgb>& frame = porty.prepare();
00214 images->getImage( frame );
00215 porty.write();
00216 }
00217
00218 }
00219
00220 #endif // FARSA_USE_YARP_AND_ICUB