/************************************************/ /* File: fixview.cpp */ /* Author: Andrew R. Freed */ /* Modified date: 5/6/03 */ /* */ /* This file plays back fixations on top of */ /* telephone interface bitmaps */ /************************************************/ #include #include //You may need to go find these on the web, as well as other //files needed for OpenGL development #include #include #include //The interfaces we did eye-tracking on were displayed at 1024x768 const int WINDOW_WIDTH = 1024; const int WINDOW_HEIGHT = 768; //How big to make the fixation crosses/lines const int CROSS_LENGTH = 8; const int LINE_WIDTH = 10; //Used to simulate real-time eye-tracking //This will slow the playback down to nearly real-time const int TIME_WASTING = 100000000; void init(); void draw(); void reshape(int,int); void drawAllPoints(); void drawFixationPoint(double,double,double); void wasteTime(double fixtime); GLubyte *tex1; static GLuint TexObj[1]; int subrun; char subtask; int subphone; int xoffset; int yoffset; //To play connect-the-dots with fixations, we need // to know where the last one was double oldFixX=0.0; double oldFixY=0.0; void init() { //Set white as background color, blue as fixation color glClearColor(1.0,1.0,1.0,0.0); glColor3f(0.0,0.0,1.0); //background image stuff FILE* texf; char line[256]; char bmp[256]; glGenTextures(1,TexObj); tex1 = (GLubyte*)malloc(1024*768*3); //This sprintf can be replaced with just storing your filename //into "bmp". //Replace these pathnames with the ones you are using if(subphone < 10) sprintf(bmp,"C:\\Documents and Settings\\arf132\\My Documents\\Thesis\\eyetrack\\phone-images\\0%d.bmp",subphone); else sprintf(bmp,"C:\\Documents and Settings\\arf132\\My Documents\\Thesis\\eyetrack\\phone-images\\%d.bmp",subphone); texf = fopen(bmp,"rb"); cout << "Bitmap: [" << bmp << "]" << endl; //This is EXTREMELY naughty. The Windows .BMP format contains a //BMP header. For my 1024*768*24bpp format, the header was 54 bytes //I skip over the header because I already know the file structure //If you are not using 1024*768*24bpp bitmaps, this will NOT work fgets(line,54,texf); //Read in the bitmap bytes for(int i=0;i<1024*768*3;i++) tex1[i] = (GLubyte) getc(texf); fclose(texf); } void draw() { //Sets our background to white glClear(GL_COLOR_BUFFER_BIT); //Draws the phone on the screen glDrawPixels(1024,768,GL_RGB,GL_UNSIGNED_BYTE,tex1); //A red point to mark the middle of the screen glColor3f(1.0,0.0,0.0); glPointSize(5); glBegin(GL_POINTS); glVertex2i(WINDOW_WIDTH/2,WINDOW_HEIGHT/2); glEnd(); //This will draw the fixations drawAllPoints(); //Finally, flush the results to screen glFlush(); } void reshape(int width, int height) { //Any standard OpenGL reference initializes a window similar to this //Note that the top-left corner is 0,0 -- defined by gluOrtho2D glViewport(0,0,WINDOW_WIDTH, WINDOW_HEIGHT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0,WINDOW_WIDTH,WINDOW_HEIGHT, 0); glMatrixMode(GL_MODELVIEW); oldFixX=0.0; oldFixY=0.0; } void drawAllPoints() { fstream fin; char phonefile[12]; sprintf(phonefile,"s8t%dp%d.txt",subrun,subphone); //sprintf(phonefile,"s8t%cp%d.txt",subtask,subphone); cout << "Data file: [" << phonefile << "]" << endl; fin.open(phonefile,ios::in); int i; double oldTime=100.0; double time,x,y; while(fin >> i >> time >> x >> y) { cout << i << " " << time << " " << x << " " << y << endl; //I've noticed that the fixation points are off by //different amounts in different parts of the screen drawFixationPoint(x-xoffset,y-yoffset,time-oldTime); oldTime=time; } } void drawFixationPoint(double x, double y, double time) { //Draws a blue cross at x,y glColor3f(0.0,0.0,1.0); glLineWidth(LINE_WIDTH*time/2); glBegin(GL_LINES); glVertex2f(x-CROSS_LENGTH, y); glVertex2f(x+CROSS_LENGTH, y); glEnd(); glBegin(GL_LINES); glVertex2f(x, y-CROSS_LENGTH); glVertex2f(x, y+CROSS_LENGTH); glEnd(); //Connects present fixation to previous fixation if(oldFixX > 1.0 && oldFixY > 1.0) { glLineWidth(1); glBegin(GL_LINES); glVertex2f(oldFixX, oldFixY); glVertex2f(x,y); glEnd(); } oldFixX = (double) x; oldFixY = (double) y; glFlush(); //Simulate real-time interaction wasteTime(time); } void wasteTime(double fixtime) { if(fixtime < 0.1) return; //This function should execute in ~fixtime seconds int length = (int) ((double)TIME_WASTING * fixtime); for(int i=0;i 3){ xoffset = atoi(argv[3]); yoffset = atoi(argv[4]); } else{ xoffset = 0; yoffset = 0; } */ xoffset=yoffset=0.0; subrun=1; subphone=4; init(); //Standard OpenGL initialization glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE); //Create our custom window glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); glutCreateWindow("Fixation Viewer"); //Register our drawing functions with OpenGL glutDisplayFunc(draw); glutReshapeFunc(reshape); //Another standard OpenGL step glutMainLoop(); return 0; }