GLImagePainter.cpp
Go to the documentation of this file.
00001 /*******************************************************************************
00002  *  GLImagePainter.cpp
00003  *
00004  *  (C) 2006 AG Aktives Sehen <agas@uni-koblenz.de>
00005  *           Universitaet Koblenz-Landau
00006  ******************************************************************************/
00007 
00008 
00009 // TODO
00010 // #include "Architecture/Config/Config.h"
00011 #include "../../Workers/Puma2/ThermalToColorOperator.h"
00012 #include "../../Workers/Puma2/Y8UV8ToRGB8Operator.h"
00013 //#include "../../Workers/Puma2/ImageWriter.h"  // TODO
00014 
00015 #include "GLImagePainter.h"
00016 
00017 #include <sstream>
00018 #include <QMouseEvent>
00019 
00020 using namespace puma2;
00021 
00022 #define THIS GLImagePainter
00023 
00024 THIS::THIS()
00025 {
00026   m_ImageWidth = 1;
00027   m_ImageHeight = 1;
00028 
00029   setPixelAspectRatio ( 1.0 );
00030 
00031   m_TextureId = -1;
00032   m_TextureData = 0;
00033   m_TextureResolution = 0;
00034   m_TextureFormat = ImageGrabber::GRAY8;
00035   m_TextureByteSize = 0;
00036 }
00037 
00038 THIS::~THIS()
00039 {
00040   if ( m_TextureData )
00041   {
00042     // TRACE_SYSTEMINFO ( "Deleting texture memory" ) // TODO
00043     delete m_TextureData;
00044   }
00045   if ( int ( m_TextureId ) != -1 )
00046   {
00047     // TRACE_SYSTEMINFO ( "Deleting OpenGL texture" ) // TODO
00048     glDeleteTextures ( 1, &m_TextureId );
00049   }
00050 }
00051 
00052 void THIS::paintImage( float alpha )
00053 {
00054 
00055   //TRACE_INFO( "paintImage()" );
00056 
00057 
00058   glEnable ( GL_BLEND );
00059   glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
00060 
00061   glColor4f ( 1.0, 1.0, 1.0, alpha );
00062   //glColor3f ( 1.0, 1.0, 1.0 );
00063 
00064   if ( m_TextureData )
00065   {
00066 
00067     if ( int ( m_TextureId ) == -1 )
00068     {
00069       glGenTextures ( 1, &m_TextureId );
00070       std::ostringstream stream;
00071       stream << "Using OpenGL texture # " << m_TextureId;
00072       //TRACE_INFO ( stream.str() ); // TODO
00073     }
00074     else
00075     {
00076       glDeleteTextures ( 1, &m_TextureId );
00077       glGenTextures ( 1, &m_TextureId );
00078     }
00079 
00080     std::ostringstream stream;
00081     stream << "Loading texture data to texture ID " << m_TextureId;
00082     // TRACE_SYSTEMINFO ( stream.str() ) // TODO
00083 
00084     glPolygonMode ( GL_FRONT_AND_BACK, GL_FILL );
00085     glEnable ( GL_TEXTURE_2D );
00086     glBindTexture ( GL_TEXTURE_2D, m_TextureId );
00087 
00088     if ( m_TextureFormat == ImageGrabber::RGB8 )
00089     {
00090       glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB, m_TextureResolution, m_TextureResolution, 0, GL_RGB, GL_UNSIGNED_BYTE, m_TextureData );
00091     }
00092     else
00093     {
00094       glTexImage2D ( GL_TEXTURE_2D, 0, GL_LUMINANCE, m_TextureResolution, m_TextureResolution, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_TextureData );
00095     }
00096 
00097     glTexParameterf ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
00098     glTexParameterf ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
00099     glTexEnvf ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
00100 
00101     float usedTextureY = float ( m_ImageHeight ) / float ( m_TextureResolution );
00102     float usedTextureX = float ( m_ImageWidth ) / float ( m_TextureResolution );
00103 
00104     //draw
00105     glBegin ( GL_POLYGON );
00106     glTexCoord2f ( 0.0,  0.0 );
00107     glVertex3f ( -0.5, 0.5, 0.0 );
00108     glTexCoord2f ( 0.0,  usedTextureY );
00109     glVertex3f ( -0.5, -0.5, 0.0 );
00110     glTexCoord2f ( usedTextureX, usedTextureY );
00111     glVertex3f ( 0.5, -0.5, 0.0 );
00112     glTexCoord2f ( usedTextureX,  0.0 );
00113     glVertex3f ( 0.5, 0.5, 0.0 );
00114     glEnd();
00115 
00116     glDisable ( GL_TEXTURE_2D );
00117   }
00118 
00119 
00120 }
00121 
00122 
00123 void THIS::paintVectorObjects()
00124 {
00125   glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE );
00126 
00127   //paint white border
00128   glColor3f ( 1.0, 1.0, 1.0 );
00129   glLineWidth( 1.0 );
00130   glBegin ( GL_POLYGON );
00131   glVertex3f ( -0.5, -0.5, 0.0 );
00132   glVertex3f ( -0.5, 0.5, 0.0 );
00133   glVertex3f ( 0.5, 0.5, 0.0 );
00134   glVertex3f ( 0.5, -0.5, 0.0 );
00135   glEnd();
00136 
00137   glColor3f ( 1.0, 1.0, 1.0 );
00138   glPushMatrix();
00139   //scale to fit [-0.5..0.5]
00140   glScalef ( 1.0 , -1.0, 1.0 );
00141   glTranslatef ( -0.5, -0.5, 0.0 );
00142   //scale to fit [0..1]
00143   glScalef ( 1.0 / m_ImageWidth, 1.0 / m_ImageHeight, 1.0 );
00144   //translate vertex coordinates to pixel centers (instead of top-left pixel corner)
00145   glTranslatef ( 0.5, 0.5, 0.0 );
00146 
00147   std::list< VectorObject2D >::iterator vectorObjectIt;
00148   vectorObjectIt = m_VectorObjects.begin();
00149   while ( vectorObjectIt != m_VectorObjects.end() )
00150   {
00151     vectorObjectIt->paintGl();
00152     vectorObjectIt++;
00153   }
00154 
00155   glPopMatrix();
00156 }
00157 
00158 
00159 void THIS::setColorImage ( const ColorImageRGB8* image, float aspect )
00160 {
00161   if ( !image )
00162   {
00163     //TRACE_ERROR ( "Received 0-pointer!" ); // TODO
00164     return;
00165   }
00166   setPixelAspectRatio ( aspect );
00167   updateTexture ( ( unsigned char* ) ( const_cast<ColorImageRGB8*> ( image )->unsafeRowPointerArray() [0][0] ), image->getWidth(), image->getHeight(), ImageGrabber::RGB8 );
00168 }
00169 
00170 void THIS::setColorImage ( const GrayLevelImage8* yImage, const ColorImageUV8* uvImage, float aspect )
00171 {
00172   if ( ( !yImage ) || ( !uvImage ) )
00173   {
00174     //TRACE_ERROR ( "Received 0-pointer!" ); // TODO
00175     return;
00176   }
00177 
00178   ColorImageRGB8 rgbImage;
00179   Y8UV8ToRGB8Operator o ( *yImage, *uvImage, rgbImage );
00180   setPixelAspectRatio ( aspect );
00181   updateTexture ( ( unsigned char* ) ( rgbImage.unsafeRowPointerArray() [0][0] ), rgbImage.getWidth(), rgbImage.getHeight(), ImageGrabber::RGB8 );
00182 }
00183 
00184 void THIS::setGrayLevelImage ( const puma2::GrayLevelImage8* image, float aspect )
00185 {
00186   if ( !image )
00187   {
00188     //TRACE_ERROR ( "Received 0-pointer!" ); // TODO
00189     return;
00190   }
00191 
00192   setPixelAspectRatio ( aspect );
00193   updateTexture ( ( unsigned char* ) ( const_cast<GrayLevelImage8*> ( image )->unsafeRowPointerArray() [0] ), image->getWidth(), image->getHeight(), ImageGrabber::GRAY8 );
00194 }
00195 
00196 void THIS::setThermalImage ( const puma2::GrayLevelImage8* image, float roomTemp )
00197 {
00198   if ( !image )
00199   {
00200     //TRACE_ERROR ( "Received 0-pointer!" ); // TODO
00201     return;
00202   }
00203   //TRACE_INFO ( "Received a new ThermalImage" ); // TODO
00204 
00205   ColorImageRGB8 coloredThermalImage;
00206   ThermalToColorOperator ( *image, coloredThermalImage, roomTemp - 20, roomTemp + 100 );
00207 
00208   //by default, stretch to display as 4:3 image
00209   float width = image->getWidth();
00210   float height = image->getHeight();
00211   float correctAspect = 4.0 / 3.0;
00212   float imageAspect = float ( width ) / float ( height );
00213   setColorImage ( &coloredThermalImage, correctAspect / imageAspect );
00214 }
00215 
00216 void THIS::setAnaglyphImage ( const puma2::GrayLevelImage8* leftYImage, const puma2::GrayLevelImage8* rightYImage, float aspect )
00217 {
00218   if ( !leftYImage || !rightYImage )
00219   {
00220     // TRACE_ERROR ( "Received 0-pointer!" ); // TODO
00221     return;
00222   }
00223 
00224   int w = leftYImage->getWidth();
00225   int h = leftYImage->getHeight();
00226 
00227   setPixelAspectRatio ( aspect );
00228 
00229   unsigned char* tempImage = new unsigned char[w*h*3];
00230   unsigned char* left = ( unsigned char* ) ( const_cast<GrayLevelImage8*> ( leftYImage )->unsafeRowPointerArray() [0] );
00231   unsigned char* right = ( unsigned char* ) ( const_cast<GrayLevelImage8*> ( rightYImage )->unsafeRowPointerArray() [0] );
00232 
00233 
00234   int anaglyphOffset = 1; // TODO Config::getInt ( "Gui.iAnaglyphOffset" );
00235 
00236   //Move left image <anaglyphOffset> pixels to the left and put into R channel
00237   //Move right image <anaglyphOffset> pixels to the right and put into G+B channel
00238 
00239   for ( int y = 0; y < h; y++ )
00240   {
00241     int i = y * w;
00242     int j = i * 3;
00243     for ( int x = 0; x < w - anaglyphOffset; x++ )
00244     {
00245       tempImage[j] = left[i+anaglyphOffset];
00246       i++;
00247       j += 3;
00248     }
00249     for ( int x = w - anaglyphOffset; x < w; x++ )
00250     {
00251       tempImage[j] = 0;
00252       j += 3;
00253     }
00254   }
00255   for ( int y = 0; y < h; y++ )
00256   {
00257     int i = y * w;
00258     int j = i * 3;
00259     for ( int x = 0; x < anaglyphOffset; x++ )
00260     {
00261       tempImage[j+1] = 0;
00262       tempImage[j+2] = 0;
00263       j += 3;
00264       i++;
00265     }
00266     for ( int x = anaglyphOffset; x < w; x++ )
00267     {
00268       tempImage[j+1] = right[i-anaglyphOffset];
00269       tempImage[j+2] = right[i-anaglyphOffset];
00270       j += 3;
00271       i++;
00272     }
00273   }
00274 
00275   updateTexture ( tempImage, w, h, ImageGrabber::RGB8 );
00276 
00277   delete tempImage;
00278 }
00279 
00280 
00281 void THIS::addVectorObject ( VectorObject2D vectorObject )
00282 {
00283   m_VectorObjects.push_back ( vectorObject );
00284 }
00285 
00286 
00287 void THIS::clearForms()
00288 {
00289   m_VectorObjects.clear();
00290 }
00291 
00292 
00293 // INTERNAL FUNCTIONS/////////////////////////////////////////////////////////////////////////////////////
00294 
00295 void THIS::updateTexture ( unsigned char* imageData, unsigned width, unsigned height, ImageGrabber::ColorFormat format )
00296 {
00297   unsigned char* texturePos;
00298   unsigned char* imagePos;
00299 
00300   // recreate texture if necessary
00301   unsigned newTextureResolution = GLImagePainter::calcTextureSize ( width, height );
00302   if ( ( m_TextureData == 0 ) || ( m_TextureResolution != newTextureResolution ) )
00303   {
00304     std::ostringstream stream;
00305     int newTextureRes = GLImagePainter::calcTextureSize ( width, height );
00306     stream << "Resizing Texture to " << newTextureRes << "x" << newTextureRes;
00307     //TRACE_SYSTEMINFO ( stream.str() ); // TODO
00308     initTexture ( newTextureRes, width, height, format );
00309   }
00310   //clear texture if image size has changed but texture size doesn't have to change
00311   else if ( ( m_ImageWidth != width ) || ( m_ImageHeight != height ) )
00312   {
00313     clearTexture();
00314   }
00315 
00316   std::ostringstream stream;
00317   stream << "Updating  texture";
00318   // TRACE_SYSTEMINFO ( stream.str() ) // TODO
00319 
00320   m_ImageWidth = width;
00321   m_ImageHeight = height;
00322   m_TextureFormat = format;
00323 
00324   unsigned bytesPerPixel = 1;
00325   if ( format == ImageGrabber::RGB8 ) { bytesPerPixel = 3; }
00326 
00327   //draw in top-left corner of the texture
00328   texturePos = m_TextureData;
00329   imagePos = imageData;
00330 
00331   //draw new image in the center
00332   for ( unsigned y = 0; y < height ; y++ )
00333   {
00334     memcpy ( texturePos, imagePos, width*bytesPerPixel );
00335     //jump to next row in texture
00336     texturePos += m_TextureResolution * bytesPerPixel;
00337     imagePos += width * bytesPerPixel;
00338   }
00339 }
00340 
00341 void THIS::clearTexture()
00342 {
00343   memset ( m_TextureData, 128, m_TextureByteSize );
00344 }
00345 
00346 
00347 void THIS::initTexture ( unsigned resolution, unsigned imageWidth, unsigned imageHeight, ImageGrabber::ColorFormat textureFormat )
00348 {
00349   m_ImageWidth = imageWidth;
00350   m_ImageHeight = imageHeight;
00351 
00352   unsigned bytesPerPixel = 1;
00353   if ( textureFormat == ImageGrabber::RGB8 ) { bytesPerPixel = 3; }
00354 
00355   m_TextureResolution = resolution;
00356 
00357   if ( m_TextureData ) { delete m_TextureData; }
00358   m_TextureByteSize = m_TextureResolution * m_TextureResolution * bytesPerPixel;
00359   m_TextureData = new unsigned char[ m_TextureByteSize ];
00360   clearTexture();
00361 }
00362 
00363 
00364 void THIS::saveImage ( std::string filename )
00365 {
00366   if ( !m_TextureData )
00367   {
00368     //TRACE_ERROR ( "No image set!" ); // TODO
00369     return;
00370   }
00371   // TRACE_INFO ( "Saving texture image to " + filename ); // TODO
00372   switch ( m_TextureFormat )
00373   {
00374     case ImageGrabber::RGB8:
00375     {
00376       ColorImageRGB8 image ( m_ImageWidth, m_ImageHeight );
00377       //copy from top-left corner of the texture
00378       for ( unsigned y = 0; y < m_ImageHeight ; y++ )
00379       {
00380         for ( unsigned x = 0; x < m_ImageWidth; x++ )
00381         {
00382           image[y][x][0] = m_TextureData[x*3+y*m_TextureResolution*3];
00383           image[y][x][1] = m_TextureData[x*3+y*m_TextureResolution*3+1];
00384           image[y][x][2] = m_TextureData[x*3+y*m_TextureResolution*3+2];
00385         }
00386       }
00387       //ImageWriter::writeImage ( image, filename ); // TODO
00388       break;
00389     }
00390     case ImageGrabber::GRAY8:
00391     {
00392       GrayLevelImage8 image ( m_ImageWidth, m_ImageHeight );
00393       //copy from top-left corner of the texture
00394       for ( unsigned y = 0; y < m_ImageHeight ; y++ )
00395       {
00396         for ( unsigned x = 0; x < m_ImageWidth; x++ )
00397         {
00398           image[y][x] = m_TextureData[x+y*m_TextureResolution];
00399         }
00400       }
00401      // ImageWriter::writeImage ( image, filename ); // TODO
00402       break;
00403     }
00404     default:
00405       // TRACE_ERROR ( "Cannot save image: Invalid format!" ); // TODO
00406       break;
00407   }
00408 }
00409 
00410 
00411 // TODO this method is from RobbieGLWidget --> leave here or find better location for it
00412 int THIS::calcTextureSize( int width, int height )
00413 {
00414     int sizeSqared = 2;
00415     //find the next potence of two into which the image fits
00416     while ( ( sizeSqared < width || sizeSqared < height ) && ( sizeSqared <= 256*256 ) )
00417     {
00418       sizeSqared = sizeSqared * 2;
00419     }
00420     return sizeSqared;
00421 }
00422 
00423 
00424 
00425 #undef THIS


obj_rec_gui
Author(s): AGAS/agas@uni-koblenz.de
autogenerated on Mon Oct 6 2014 02:53:43