00001 /*!@file GameBoard/basic-graphics.C some utilities for displaying stimuli*/ 00002 // //////////////////////////////////////////////////////////////////// // 00003 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00004 // University of Southern California (USC) and the iLab at USC. // 00005 // See http://iLab.usc.edu for information about this project. // 00006 // //////////////////////////////////////////////////////////////////// // 00007 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00008 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00009 // in Visual Environments, and Applications'' by Christof Koch and // 00010 // Laurent Itti, California Institute of Technology, 2001 (patent // 00011 // pending; application number 09/912,225 filed July 23, 2001; see // 00012 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00013 // //////////////////////////////////////////////////////////////////// // 00014 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00015 // // 00016 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00017 // redistribute it and/or modify it under the terms of the GNU General // 00018 // Public License as published by the Free Software Foundation; either // 00019 // version 2 of the License, or (at your option) any later version. // 00020 // // 00021 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00022 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00023 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00024 // PURPOSE. See the GNU General Public License for more details. // 00025 // // 00026 // You should have received a copy of the GNU General Public License // 00027 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00028 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00029 // Boston, MA 02111-1307 USA. // 00030 // //////////////////////////////////////////////////////////////////// // 00031 //written by Nader Noori, April 2008 00032 #include <SDL/SDL.h> 00033 #include <SDL/SDL_image.h> 00034 #include "basic-graphics.H" 00035 #include "Component/ModelManager.H" 00036 #include "Image/Image.H" 00037 #include "Psycho/PsychoDisplay.H" 00038 #include "Psycho/EyeTrackerConfigurator.H" 00039 #include "Psycho/EyeTracker.H" 00040 #include "Psycho/PsychoOpts.H" 00041 #include "Component/EventLog.H" 00042 #include "Component/ComponentOpts.H" 00043 #include "Raster/Raster.H" 00044 #include "Util/MathFunctions.H" 00045 #include "Util/Types.H" 00046 #include <iostream> 00047 #include <fstream> 00048 #include <stdio.h> 00049 #include <stdlib.h> 00050 #include <time.h> 00051 #include <sstream> 00052 #include "Psycho/PsychoDisplay.H" 00053 #include "Component/ModelOptionDef.H" 00054 #include "Component/OptionManager.H" 00055 #include "GUI/SDLdisplay.H" 00056 #include "Image/ColorOps.H" 00057 #include "Image/DrawOps.H" 00058 #include "Psycho/EyeTracker.H" 00059 #include "Psycho/PsychoOpts.H" 00060 #include "Util/sformat.H" 00061 00062 using namespace std; 00063 /* 00064 * Set the pixel at (x, y) to the given value 00065 * NOTE: The surface must be locked before calling this! 00066 */ 00067 void putpixel(SDL_Surface* surface, int x, int y, Uint32 pixel) 00068 { 00069 int bpp = surface->format->BytesPerPixel; 00070 /* Here p is the address to the pixel we want to set */ 00071 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; 00072 00073 switch(bpp) { 00074 case 1: 00075 *p = pixel; 00076 break; 00077 00078 case 2: 00079 *(Uint16 *)p = pixel; 00080 break; 00081 00082 case 3: 00083 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { 00084 p[0] = (pixel >> 16) & 0xff; 00085 p[1] = (pixel >> 8) & 0xff; 00086 p[2] = pixel & 0xff; 00087 } else { 00088 p[0] = pixel & 0xff; 00089 p[1] = (pixel >> 8) & 0xff; 00090 p[2] = (pixel >> 16) & 0xff; 00091 } 00092 break; 00093 00094 case 4: 00095 *(Uint32 *)p = pixel; 00096 break; 00097 } 00098 } 00099 00100 ///////////////////////////////////////////// 00101 SDL_Surface *load_image( string filename ) 00102 { 00103 //The image that's loaded 00104 SDL_Surface* loadedImage = NULL; 00105 00106 //The optimized image that will be used 00107 SDL_Surface* optimizedImage = NULL; 00108 00109 //Load the image 00110 loadedImage = IMG_Load( filename.c_str() ); 00111 00112 //If the image loaded 00113 if( loadedImage != NULL ) 00114 { 00115 //Create an optimized image 00116 00117 optimizedImage = SDL_DisplayFormat( loadedImage ); 00118 00119 //Free the old image 00120 SDL_FreeSurface( loadedImage ); 00121 00122 //If the image was optimized just fine 00123 if( optimizedImage != NULL ) 00124 { 00125 //Map the color key 00126 Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ); 00127 00128 //Set all pixels of color R 0, G 0xFF, B 0xFF to be transparent 00129 SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey ); 00130 } 00131 }else{ 00132 00133 } 00134 00135 //Return the optimized image 00136 return optimizedImage; 00137 } 00138 /////////////////////////////////// 00139 00140 SDL_Surface *getABlankSurface(int w , int h){ 00141 00142 00143 SDL_Surface *sur = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, 00144 0x00000000, 0x00000000, 0x00000000, 0x00000000); 00145 return sur ; 00146 00147 } 00148 00149 00150 /////////////////////////////////// 00151 void dumpSurface(SDL_Surface* surface){ 00152 SDL_FreeSurface( surface ); 00153 } 00154 ///////////////////////////////////////////// 00155 void apply_surface( int x, int y, SDL_Surface& source, SDL_Surface& destination , SDL_Rect& clip ) 00156 { 00157 //Make a temporary rectangle to hold the offsets 00158 SDL_Rect offset; 00159 00160 //Give the offsets to the rectangle 00161 offset.x = x; 00162 offset.y = y; 00163 00164 //Blit the surface 00165 SDL_BlitSurface( &source, &clip, &destination, &offset ); 00166 } 00167 00168 00169 ///////////////////////////////////////////// 00170 void fillRectangle(SDL_Surface* surface , const Uint32 pc , uint offX , uint offY , const uint w , const uint h ) { 00171 00172 /* Lock the screen for direct access to the pixels */ 00173 if ( SDL_MUSTLOCK(surface) ) { 00174 if ( SDL_LockSurface(surface) < 0 ) { 00175 fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError()); 00176 return; 00177 } 00178 } 00179 00180 for( uint x = offX ; x <= offX + w ; x++){ 00181 for( uint y = offY ; y < offY + h ; y++){ 00182 if( (x >= offX) && (x <= offX + w) && (y >= offY ) && (y <= offY + h)){ 00183 putpixel(surface, x, y, pc); 00184 00185 } 00186 } 00187 00188 } 00189 00190 if ( SDL_MUSTLOCK(surface) ) { 00191 SDL_UnlockSurface(surface); 00192 } 00193 } 00194 ///////////////////////////////////////////// 00195 00196 void drawCircle(SDL_Surface* surface , const Uint32 pc , uint offX , uint offY , const uint r , const uint d ){ 00197 /* Lock the screen for direct access to the pixels */ 00198 if ( SDL_MUSTLOCK(surface) ) { 00199 if ( SDL_LockSurface(surface) < 0 ) { 00200 fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError()); 00201 return; 00202 } 00203 } 00204 00205 for( float teta = 0.0f ; teta < 6.3f ; teta += 0.05f ){ 00206 for(uint rho = r ; rho <= r+d ; rho++ ) 00207 putpixel(surface, offX + (int)(rho * cos(teta)) , offY + (int)(rho * sin(teta)), pc); 00208 } 00209 /* 00210 for( uint x = offX - r ; x <= offX + r ; x++){ 00211 int yt = (int)sqrt(r*r - (x- offX)*(x-offX)) ; 00212 putpixel(surface, x, yt+offY, pc); 00213 putpixel(surface, x, offY-yt, pc); 00214 }*/ 00215 00216 if ( SDL_MUSTLOCK(surface) ) { 00217 SDL_UnlockSurface(surface); 00218 } 00219 00220 00221 } 00222 ///////////////////////////////////////////// 00223 void drawRectangleFromImage(SDL_Surface* surface , SDL_Surface* patch , uint offX , uint offY , const uint w , const uint h , const uint f){ 00224 /* Lock the screen for direct access to the pixels */ 00225 if ( SDL_MUSTLOCK(surface) ) { 00226 if ( SDL_LockSurface(surface) < 0 ) { 00227 fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError()); 00228 return; 00229 } 00230 } 00231 00232 if ( SDL_MUSTLOCK(patch) ) { 00233 if ( SDL_LockSurface(patch) < 0 ) { 00234 fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError()); 00235 return; 00236 } 00237 } 00238 00239 for(uint x = offX ; x <= offX + w ; x++){ 00240 00241 for( uint d = 1 ; d <= f ; d++){ 00242 Uint32 pixel = get_pixel32( patch, x, offY+d-1 ); 00243 put_pixel32(surface, x, offY+d-1, pixel); 00244 pixel = get_pixel32( patch, x, offY+h-d+1 ); 00245 put_pixel32(surface, x , offY+h-d+1 , pixel) ; 00246 } 00247 } 00248 for( uint y = offY ; y <= offY + h ; y++){ 00249 for( uint d = 1 ; d <= f ; d++){ 00250 00251 Uint32 pixel = get_pixel32( patch, offX+d-1 , y ); 00252 putpixel(surface,offX+d-1,y,pixel) ; 00253 pixel = get_pixel32( patch, offX+w-d+1 , y ); 00254 put_pixel32(surface,offX+w-d+1 ,y ,pixel) ; 00255 } 00256 00257 } 00258 00259 if ( SDL_MUSTLOCK(surface) ) { 00260 SDL_UnlockSurface(surface); 00261 } 00262 if ( SDL_MUSTLOCK(patch) ) { 00263 SDL_UnlockSurface(patch); 00264 } 00265 00266 } 00267 ///////////////////////////////////////////////////////// 00268 Uint32 get_pixel32( SDL_Surface *surface, int x, int y ) 00269 { 00270 //Convert the pixels to 32 bit 00271 Uint32 *pixels = (Uint32 *)surface->pixels; 00272 00273 //Get the requested pixel 00274 return pixels[ ( y * surface->w ) + x ]; 00275 } 00276 /////////////////////////////////////////////////////////// 00277 void put_pixel32( SDL_Surface *surface, int x, int y, Uint32 pixel ) 00278 { 00279 //Convert the pixels to 32 bit 00280 Uint32 *pixels = (Uint32 *)surface->pixels; 00281 00282 //Set the pixel 00283 pixels[ ( y * surface->w ) + x ] = pixel; 00284 } 00285 00286 00287 ///////////////////////////////////////////// 00288 00289 void drawRectangle(SDL_Surface* surface , const Uint32 pc , uint offX , uint offY , const uint w , const uint h , const uint f){ 00290 /* Lock the screen for direct access to the pixels */ 00291 if ( SDL_MUSTLOCK(surface) ) { 00292 if ( SDL_LockSurface(surface) < 0 ) { 00293 fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError()); 00294 return; 00295 } 00296 } 00297 00298 for(uint x = offX ; x <= offX + w ; x++){ 00299 for( uint d = 1 ; d <= f ; d++){ 00300 putpixel(surface, x, offY+d-1, pc); 00301 putpixel(surface, x , offY+h-d+1 , pc) ; 00302 } 00303 } 00304 for( uint y = offY ; y <= offY + h ; y++){ 00305 for( uint d = 1 ; d <= f ; d++){ 00306 putpixel(surface,offX+d-1,y,pc) ; 00307 putpixel(surface,offX+w-d+1 ,y ,pc) ; 00308 } 00309 00310 } 00311 00312 if ( SDL_MUSTLOCK(surface) ) { 00313 SDL_UnlockSurface(surface); 00314 } 00315 00316 } 00317 00318 //////////////////////////////////////////// 00319 void fillOval(SDL_Surface* surface , const Uint32 pc , int offX , uint offY , const int w , const int h ) { 00320 /* Lock the screen for direct access to the pixels */ 00321 if ( SDL_MUSTLOCK(surface) ) { 00322 if ( SDL_LockSurface(surface) < 0 ) { 00323 fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError()); 00324 return; 00325 } 00326 } 00327 00328 float w_2 =((float)w*w)/4.0f ; 00329 float h_2 = ((float) h*h)/4.0f ; 00330 for( float x = offX ; x <= offX+w ; x++){ 00331 for( float y = offY ; y <= offY +h ; y++){ 00332 if( (float)((x-offX-(float)(w)/2)*(x-offX-(float)(w)/2))/w_2 + (float)((y-offY-(float)(h)/2)*(y-offY-(float)(h)/2))/h_2 < 1 ){ 00333 putpixel(surface, (int)x, (int)y, pc); 00334 00335 } 00336 } 00337 00338 } 00339 00340 if ( SDL_MUSTLOCK(surface) ) { 00341 SDL_UnlockSurface(surface); 00342 } 00343 } 00344 00345 00346 00347 void fillCubicRadiant(SDL_Surface* surface , const Uint32 pc , uint offX , uint offY, const int R){ 00348 /* Lock the screen for direct access to the pixels */ 00349 uint b1 = 256 ; 00350 uint b2 = 65536 ; 00351 uint red = pc / b2 ; 00352 uint rem = pc % b2 ; 00353 uint green = rem/b1 ; 00354 uint blue = rem % b1 ; 00355 uint nr = 0 ; 00356 uint ng = 0 ; 00357 uint nb = 0 ; 00358 float factor = 0.0f ; 00359 if ( SDL_MUSTLOCK(surface) ) { 00360 if ( SDL_LockSurface(surface) < 0 ) { 00361 fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError()); 00362 return; 00363 } 00364 } 00365 00366 Uint32 clr = 0 ; 00367 for( float x = offX-R ; x <= offX+R ; x++){ 00368 for( float y = offY-R ; y <= offY +R ; y++){ 00369 float r = sqrt((x-offX)*(x-offX) + (y-offY)*(y-offY)); 00370 factor = (1-(float)r*r*r/((float)R*R*R)) ; 00371 nr = (uint)(red * factor) ; 00372 ng = (uint)(green*factor) ; 00373 nb = (uint)(blue * factor) ; 00374 if(r <= R ){ 00375 00376 clr = (Uint32)(nb+ng*b1+nr*b2) ; 00377 putpixel(surface, (int)x, (int)y, clr); 00378 } 00379 00380 00381 00382 } 00383 00384 } 00385 00386 if ( SDL_MUSTLOCK(surface) ) { 00387 SDL_UnlockSurface(surface); 00388 } 00389 00390 } 00391 00392 00393 00394 00395 00396 void fillQuadricRadiant(SDL_Surface* surface , const Uint32 pc , uint offX , uint offY, const int R){ 00397 /* Lock the screen for direct access to the pixels */ 00398 uint b1 = 256 ; 00399 uint b2 = 65536 ; 00400 uint red = pc / b2 ; 00401 uint rem = pc % b2 ; 00402 uint green = rem/b1 ; 00403 uint blue = rem % b1 ; 00404 uint nr = 0 ; 00405 uint ng = 0 ; 00406 uint nb = 0 ; 00407 float factor = 0.0f ; 00408 if ( SDL_MUSTLOCK(surface) ) { 00409 if ( SDL_LockSurface(surface) < 0 ) { 00410 fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError()); 00411 return; 00412 } 00413 } 00414 00415 Uint32 clr = 0 ; 00416 for( float x = offX-R ; x <= offX+R ; x++){ 00417 for( float y = offY-R ; y <= offY +R ; y++){ 00418 float r = sqrt((x-offX)*(x-offX) + (y-offY)*(y-offY)); 00419 factor = (1-(float)r*r/((float)R*R)) ; 00420 nr = (uint)(red * factor) ; 00421 ng = (uint)(green*factor) ; 00422 nb = (uint)(blue * factor) ; 00423 if(r <= R ){ 00424 00425 clr = (Uint32)(nb+ng*b1+nr*b2) ; 00426 putpixel(surface, (int)x, (int)y, clr); 00427 } 00428 00429 00430 00431 } 00432 00433 } 00434 00435 if ( SDL_MUSTLOCK(surface) ) { 00436 SDL_UnlockSurface(surface); 00437 } 00438 00439 } 00440 00441 00442 void fillLinearRadiant(SDL_Surface* surface , const Uint32 pc , uint offX , uint offY, const int R){ 00443 /* Lock the screen for direct access to the pixels */ 00444 uint b1 = 256 ; 00445 uint b2 = 65536 ; 00446 uint red = pc / b2 ; 00447 uint rem = pc % b2 ; 00448 uint green = rem/b1 ; 00449 uint blue = rem % b1 ; 00450 uint nr = 0 ; 00451 uint ng = 0 ; 00452 uint nb = 0 ; 00453 float factor = 0.0f ; 00454 if ( SDL_MUSTLOCK(surface) ) { 00455 if ( SDL_LockSurface(surface) < 0 ) { 00456 fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError()); 00457 return; 00458 } 00459 } 00460 00461 00462 Uint32 clr = 0 ; 00463 for( float x = offX-R ; x <= offX+R ; x++){ 00464 for( float y = offY-R ; y <= offY +R ; y++){ 00465 float r = sqrt((x-offX)*(x-offX) + (y-offY)*(y-offY)); 00466 factor = (1-(float)r/((float)R)) ; 00467 nr = (uint)(red * factor) ; 00468 ng = (uint)(green*factor) ; 00469 nb = (uint)(blue * factor) ; 00470 if(r <= R ){ 00471 00472 clr = (Uint32)(nb+ng*b1+nr*b2) ; 00473 putpixel(surface, (int)x, (int)y, clr); 00474 } 00475 00476 00477 00478 } 00479 00480 } 00481 00482 if ( SDL_MUSTLOCK(surface) ) { 00483 SDL_UnlockSurface(surface); 00484 } 00485 00486 } 00487 /* 00488 00489 extern "C" int main(int argc, char* argv[] ){ 00490 00491 ModelManager manager("Psycho Skin"); 00492 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager)); 00493 00494 MYLOGVERB = LOG_INFO; // suppress debug messages 00495 00496 manager.addSubComponent(d); 00497 nub::soft_ref<EventLog> el(new EventLog(manager)); 00498 manager.addSubComponent(el); 00499 d->setEventLog(el); 00500 // Parse command-line: 00501 if (manager.parseCommandLine(argc, argv,"<profile.psymap> <path-to-skin> <logfilename>", 0, 3)==false) 00502 return(1); 00503 manager.setOptionValString(&OPT_EventLogFileName,manager.getExtraArg(2).c_str() ); 00504 manager.start(); 00505 d->clearScreen() ; 00506 SDL_Surface* blankSurface = getABlankSurface(200,200) ; 00507 //if(blank == 0) cout<<"====================================null "<<endl ; 00508 Uint32 white = d->getUint32color(PixRGB<byte>(255, 255, 255)); 00509 Uint32 yellow = d->getUint32color(PixRGB<byte>(255, 255, 0)); 00510 //fillOval(blankSurface,white,0,0,80,80) ; 00511 //fillOval(blankSurface,white,0,80,80,80) ; 00512 00513 fillLinearRadiant(blankSurface,white,50,50,40) ; 00514 fillLinearRadiant(blankSurface,white,110,80,2) ; 00515 fillCubicRadiant(blankSurface,white,110,110,2) ; 00516 fillQuadricRadiant(blankSurface,white,110,150,2) ; 00517 fillOval(blankSurface,white,110,180,20,20) ; 00518 fillCubicRadiant(blankSurface,yellow,80,120,15) ; 00519 00520 //fillRectangle(blankSurface,white,150,100,40,40) ; 00521 SDL_Rect offset; 00522 d->clearScreen() ; 00523 //Give the offsets to the rectangle 00524 offset.x = (d->getWidth() - blankSurface->w) /2; 00525 offset.y = (d-> getHeight() - blankSurface->h) /2; 00526 d->displaySDLSurfacePatch(blankSurface , &offset,NULL , -2,false, true); 00527 d->waitForKey() ; 00528 d->displayText("HI"); 00529 d->waitForKey() ; 00530 manager.stop(); 00531 00532 } 00533 */