/* Revised the code since Attention_test_3.cpp * 2 slabs appear on the groun floor in constant positions, and 4 objects that randomly change positions; * association with the bar has been removed. ISI was removed. * * GOALS: 1. remove the difference between OBJ_NUM_1 and OBJ_NUM_2 because we don't have 2 frames anymore; * 2. figure out how to add the slabs in the drawPolygons() function and randomize them * independent of the other objects. * 3. Clean up code * 4. Change orientation of "slabs" between horizontal and vertical * Q: what is bshow doing here? how do the frame 2 objects disappear? (update: solved, 8/8/2005) */ //#include "stdafx.h" #include #include #include #include //comment for os x compiling #include #include #include #include #include /* for cos(), sin(), and sqrt() */ #include /* OpenGL Utility Toolkit header */ //#include //use this for os x compiling #include //comment for os x compiling #include #include using namespace std; #define FRAMELENGTH 750 // presentation duration of frame 1 & 2; should be 750 char subjStr[100]; //character input for subject name char checkImage1[100][100][3]; //i don't know what this is but used to be char checkImage1[576][576][3]; FILE * infile; FILE * outfile; char infilename[40]; char outfilename[40]; //int abs(float num){return abs((int)num);} //uncomment for os x compiling //maximum number of objects in the scene for this program const unsigned OBJECT_NUM_1 = 4; //# of objects in Frame 1, used for array numOfObjects[0] const unsigned OBJECT_NUM_2 = 4; //# of objects in Frame 2, used for array numOfObjects[2] const unsigned MAX_OBJECT_NUM = OBJECT_NUM_1; //maximum limit to number of objects const unsigned TEXTURE = 0; //0=.002, 1=.003, 2=.004, 3=.005 // 8 x 1 x 1 x 1 x 1 x 1 // (heading, numOfObjects, RandomizedPostion, isi, bar, nearwide, leftright, contrast) const unsigned CONDITIONS = 8; const unsigned REPETITION = 1; //# of times each trial is repeated const unsigned OBJ_RANDOM_NUM = 1; //# of times all trials are repeated const unsigned TOTALTRIALS = CONDITIONS * REPETITION * OBJ_RANDOM_NUM; //TOTAL number of trials in the run const unsigned REPEAT = 10; //add this because of new floor without texture const int SCENE_LEFT_BDR = -50; //defines borders of screen const int SCENE_RIGHT_BDR = 50; const int SCENE_NEAR_BDR = -30; const int SCENE_FAR_BDR = -273; const int FIXED_OBJ_POS = 0; const int RAND_SWITCH_OBJ_POS = 1; const int RAND_MV_OBJ_KEEP_REL = 2; const int RAND_MV_OBJ_NOKEEP_REL = 3; const float L_MARGIN = 5; //defines margin (of screen? or for objects? probably screen) const float R_MARGIN = 5; const float U_MARGIN = 5; const float D_MARGIN = 5; const float VISUAL_ANGLE = 20.0; //i think this is the angle which the objs occupy, if too large, objs will disappear const double M_PI = 3.14159265; //pi value, comment for os x compiling float XX,ZZ; float mv_distance = 24.0; float disp = 0; float circlex[500]; //I need to figure out why these circles are not being drawn; these are supposed to be on the ground floor float circlez[500]; int posMatrix[300][300]; int objorder[MAX_OBJECT_NUM]; int objPlacOrder[MAX_OBJECT_NUM]; int order[TOTALTRIALS]; //for ordering the total number of trials each time the exe. is ran int correct = 0; int frame = 0; int phase = 0; //there are four phases to each trial: frame1, blank, frame2, blank. int ticks1, ticks0; /*clock_t*/ int moving, startx, starty; int lightStartX, lightStartY; int blank = 0; //int duration = 3000; //increase time of frame presentation //1000 int resp = 0; int resp_lock = 1; //when 1, no [4|6] responses will be accepted int ntrials; //number of trials in the block int trial=0; //initialize trial to 0 short ord_change_num, rel_to_eye_change_num; unsigned windW = 1280, windH = 1024; //window width and height /* Variable controlling various rendering modes. */ int stencilReflection = 0, stencilShadow = 1, offsetShadow = 1; int renderShadow = 1, renderPolygons = 1; int linearFiltering = 0, useMipmaps = 1, useTexture = 1; int reportSpeed = 0; GLboolean lightSwitch = GL_TRUE; int directionalLight = 1; int forceExtension = 0; /* Time varying or user-controled variables. */ float lightAngle = -12.0, lightHeight = 25; GLfloat angle = 0; //-150; /* in degrees */ /*angle and angle2 for drawing the bar?*/ GLfloat angle2 = 0; //30; /* in degrees */ typedef struct { /* int kind; //looks like we're not using these variables at the moment * float rot; * float scale; */ float x[2]; //0 is frame 1, 1 is frame 2 float z[2]; } objtype; objtype obj[TOTALTRIALS][MAX_OBJECT_NUM]; /*for every object in frame 1 and for all the trials in the exp, *specify the x and z positions of the objects on the plane */ /*build structure of type Condition with all these variables*/ typedef struct _condition { //float bar_angle; float abs_heading; //4 heading angles float rel_heading; //4 heading angles //float isi; //2 isi conditions int contrast; //1 level of contrast, 180 int obj_num[2]; // number of objects in the first and second frames bool bshow[MAX_OBJECT_NUM];//for every object, should we show it or not int objRandom; } Condition; //32 conditions total, 2 repetitions for each condition Condition trialConditions[TOTALTRIALS]; //creates an array (for all trials) containing the elements defined in structure "conditions" Condition trial_cond; //trial_cond has all the vars. inside the structure Condition enum { MISSING, EXTENSION, ONE_DOT_ONE }; int polygonOffsetVersion; GLfloat lightPosition[4]; GLfloat lightColor[] = {1.0, 1.0, 1.0, 1.0}; /* FUNCTION PROTOTYPES BEGIN!! */ void zeroMatrix(); /* initializes all params of posMatrix[][] to 0 */ void readTrialParams(); void MakeRandomPlacOrder(int, int); /* Shuffle objects... but i don't know how */ void makeSubFile(); void GenerateConditions(); void MakeTrialOrderRandom(int, int); int checkAroundMatrix(int, int); int checkMatrix(float, float); void setPosMatrix(float, float, int); float RandomPosX(); float RandomPosZ(); float RandomPosXZ(float, float, float); unsigned randMVObject(float); void SortOrder(vector & tan_v, vector & order); bool IsRelToEyeChange(objtype); bool IsObjectOutOfView(objtype); bool IsOrdRelChange(objtype); void SetInitialObjPos(int, float); void SetObjectPos(unsigned, int, objtype); void setParams(); void makeCheckImage(); void makeFloorTexture(); void shadowMatrix(GLfloat, GLfloat, GLfloat); void findPlane(GLfloat, GLfloat, GLfloat, GLfloat); void drawPolygons(bool); void drawBlankScreen(); void drawFloor(); void MoveEye(double, float); void redraw(); void motion(int, int); void idle(); void controlLights(int); void visible(int); void key(unsigned char, int, int); int supportsOneDotOne(); /* FUNCTION DEFINITIONS BEGIN!! */ /* *INDENT-ON* */ void zeroMatrix() /* initializes all params of posMatrix[][] to 0 */ { int i,k; for (i=0; i<101; ++i) for (k=0; k<201; ++k) posMatrix[i][k] = 0; } void readTrialParams(void) { ntrials = TOTALTRIALS; printf("ntrials = %i\n", ntrials); //trial_cond.bar_angle = trialConditions[order[trial]].bar_angle; trial_cond.rel_heading = trialConditions[order[trial]].abs_heading; //trial_cond.abs_heading = trial_cond.rel_heading + trialConditions[order[trial]].bar_angle; //trial_cond.isi = trialConditions[order[trial]].isi; trial_cond.contrast = trialConditions[order[trial]].contrast; trial_cond.obj_num[0] = trialConditions[order[trial]].obj_num[0]; //# of objs in Frame 1(?) trial_cond.obj_num[1] = trialConditions[order[trial]].obj_num[1]; //# of objs in Frame 2(?) trial_cond.objRandom = trialConditions[order[trial]].objRandom; unsigned i, obj_num = trial_cond.obj_num[0]; for (i=0; i=0) && (j>=0)) check = posMatrix[i][j] || check; return(check); } int checkMatrix(float X, float Z) { int rX, rZ; rX = (X+50) / STEPX; rZ = abs(Z / STEPZ); //printf("rx %d rZ %d \n",rX,rZ); if ( checkAroundMatrix(rX,rZ) ) { // if position already taken, return NO GOOD return(0); } posMatrix[rX][rZ] = 1; // else set the position as taken, and return GOOD return 1; } void setPosMatrix(float x, float z, int value) { int rX, rZ; rX = (x+50) / STEPX; rZ = abs(z / STEPZ); posMatrix[rX][rZ] = value; } float RandomPosX () { // size of the visiable world is X: -50, 50 unsigned width = abs(SCENE_RIGHT_BDR - SCENE_LEFT_BDR - L_MARGIN - R_MARGIN); return (((float)rand() / (float)(RAND_MAX+1) * width) + SCENE_LEFT_BDR + L_MARGIN); } float RandomPosZ() { // size of the visiable world in Z = -30 to -200 unsigned length = abs(SCENE_NEAR_BDR - SCENE_FAR_BDR - U_MARGIN - D_MARGIN); return (((float)rand() / (float)(RAND_MAX + 1) * length) + SCENE_FAR_BDR + U_MARGIN); } float RandomPosXZ(float *XX, float *ZZ, float dis_x) { float dis_xl_thr = dis_x + L_MARGIN + 10; float dis_xr_thr = dis_x + R_MARGIN + 10; unsigned it = 0; do { for (;;) { *XX = RandomPosX(); if (*XX < 0 && fabs(*XX) > dis_xl_thr || *XX > 0 && *XX > dis_xr_thr) break; } *ZZ = RandomPosZ(); // 40 degrees total, 20 degrees from the center, give 5 deg to be sure if (abs(*XX / *ZZ) < tan(VISUAL_ANGLE / 180.0 * M_PI) ) { if (checkMatrix(*XX, *ZZ) ) { // printf("%3.2f %3.2f \n",*XX,*ZZ); return 1; } } ++it; } while (it < 100); return 0; } unsigned randMVObject(float radius) { zeroMatrix(); unsigned i, move_num, old_move_num = 0; unsigned try_no, try2_no, try3_no, try4_no, try_thr = 100; double direction; unsigned num_object = trial_cond.obj_num[0]; vector move(num_object); unsigned trial_no = order[trial]; for (i=0; i SCENE_RIGHT_BDR - R_MARGIN || zn < SCENE_FAR_BDR + U_MARGIN || zn > SCENE_NEAR_BDR - D_MARGIN) continue; if (checkMatrix(xn, zn)) { obj[trial_no][i].x[1] = xn; obj[trial_no][i].z[1] = zn; ++move_num; move[i] = deg==0 ? 1 : -1; break; } if (try_no > try_thr) { setPosMatrix(obj[trial_no][i].x[0], obj[trial_no][i].z[0], 1); break; } } while(true); } if (move_num < unsigned(num_object)) { if (old_move_num!=move_num) { old_move_num = move_num; try2_no = 0; } else { ++try2_no; if (try2_no==10) { if (++try3_no==10) return 0; try2_no = move_num = old_move_num = 0; zeroMatrix(); for (i=0; i & tan_v, vector & order) { float tan_tmp; short order_tmp; int num_object = trial_cond.obj_num[0]; int i, j; for (i=0; i tan_v[j]) { tan_tmp = tan_v[i]; tan_v[i] = tan_v[j]; tan_v[j] = tan_tmp; order_tmp = order[i]; order[i] = order[j]; order[j] = order_tmp; } } bool IsRelToEyeChange(objtype obj[]) { int num_object = trial_cond.obj_num[0]; vector order_bm(num_object), order_am(num_object); vector tan_bm(num_object), tan_am(num_object); float eyex = mv_distance * sin(trial_cond.abs_heading * M_PI / 180); float eyez = 80.0 - mv_distance * cos(trial_cond.abs_heading * M_PI / 180); float x, z; int i; for (i=0; i 0) x += R_MARGIN; else if (x < 0) x -= L_MARGIN; if (abs(x / z) >= tan(VISUAL_ANGLE / 180.0 * M_PI)) return true; } return false; } bool IsOrdRelChange(objtype obj[]) { int num_object = trial_cond.obj_num[0]; vector > x_order_bm(num_object), x_order_am(num_object); vector > z_order_bm(num_object), z_order_am(num_object); int i, j; for (i=0; i obj[j].x[0]) x_order_bm[i][j] = 1; else x_order_bm[i][j] = 0; if (obj[i].x[1] < obj[j].x[1]) x_order_am[i][j] = -1; else if (obj[i].x[1] > obj[j].x[1]) x_order_am[i][j] = 1; else x_order_am[i][j] = 0; if (obj[i].z[0] < obj[j].z[0]) z_order_bm[i][j] = -1; else if (obj[i].z[0] > obj[j].z[0]) z_order_bm[i][j] = 1; else z_order_bm[i][j] = 0; if (obj[i].z[1] < obj[j].z[1]) z_order_am[i][j] = -1; else if (obj[i].z[1] > obj[j].z[1]) z_order_am[i][j] = 1; else z_order_am[i][j] = 0; } } vector > ord_rel(num_object); for (i=0; i rel(num_object); for (i=0; i.5*RAND_MAX) { temp1 = 90; } else { temp1 = 90; //trialConditions[order[trial]].contrast; } if(rand()>.5*RAND_MAX) { temp2 = 0; } else { temp2 = 1; } if(rand()>.5*RAND_MAX) { temp3=0; } else { temp3=1; } checkImage1[i][100-1-j][0] = temp1; checkImage1[i][100-1-j][1] = temp1; checkImage1[i][100-1-j][2] = temp1; } } } //end new texture code /*Create the floor texture*/ void makeFloorTexture(void) { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); if (useMipmaps) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); gluBuild2DMipmaps(GL_TEXTURE_2D,3,100,40,GL_RGB, GL_UNSIGNED_BYTE, &checkImage1[0][0][0]); } else { if (linearFiltering) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } glTexImage2D(GL_TEXTURE_2D, 0, 3, 16, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, &checkImage1[0][0][0]); } } enum { X, Y, Z, W }; enum { A, B, C, D }; /* Create a matrix that will project the desired shadow. */ void shadowMatrix(GLfloat shadowMat[4][4], GLfloat groundplane[4], GLfloat lightpos[4]) { GLfloat dot; /* Find dot product between light position vector and ground plane normal. */ dot = groundplane[X] * lightpos[X] + groundplane[Y] * lightpos[Y] + groundplane[Z] * lightpos[Z] + groundplane[W] * lightpos[W]; shadowMat[0][0] = dot - lightpos[X] * groundplane[X]; shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y]; shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z]; shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W]; shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X]; shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y]; shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z]; shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W]; shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X]; shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y]; shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z]; shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W]; shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X]; shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y]; shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z]; shadowMat[3][3] = dot - lightpos[W] * groundplane[W]; } /* Find the plane equation given 3 points. */ void findPlane(GLfloat plane[4], GLfloat v0[3], GLfloat v1[3], GLfloat v2[3]) { GLfloat vec0[3], vec1[3]; /* Need 2 vectors to find cross product. */ vec0[X] = v1[X] - v0[X]; vec0[Y] = v1[Y] - v0[Y]; vec0[Z] = v1[Z] - v0[Z]; vec1[X] = v2[X] - v0[X]; vec1[Y] = v2[Y] - v0[Y]; vec1[Z] = v2[Z] - v0[Z]; /* find cross product to get A, B, and C of plane equation */ plane[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y]; plane[B] = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X]); plane[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X]; plane[D] = -(plane[A] * v0[X] + plane[B] * v0[Y] + plane[C] * v0[Z]); } void drawPolygons(bool bShadow) { int i; int object_num = trial_cond.obj_num[0]; //i think this is the max # of objects (in other words, objs in Frame 1 float X, Z; unsigned trial_no; for(i=0; i=FRAMELENGTH){ //phase = 2; ticks0 = (int)(clock()*1000/CLOCKS_PER_SEC); } } //phase 2 is also taken out because it's not necessary; see description in phase 1 else if(phase == 2){ //blank; ISI presentation blank = 1; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); disp = 0; //if ((ticks1-ticks0)>= trial_cond.isi){ phase = 3; // bar_angle = trialConditions[order[trial]].bar_angle; ticks0 = (int)(clock()*1000/CLOCKS_PER_SEC); // } } else if (phase == 3){ //frame2 blank = 0; frame = 2; MoveEye(trial_cond.abs_heading, mv_distance); if ((ticks1-ticks0)>=(FRAMELENGTH-250)); //this isn't doing anything if ((ticks1-ticks0)>=FRAMELENGTH){ phase = 4; resp_lock=0; // responses will be accepted from now til lock is reengaged ticks0 = (int)(clock()*1000/CLOCKS_PER_SEC); } } else if (phase == 4){ //wait for response printf("phase = %i trial = %i\n", phase, trial); blank = 0; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // MoveEye(trial_cond.abs_heading, 0); if(resp!=0){ resp_lock=1; ticks0 = (int)(clock()*1000/CLOCKS_PER_SEC); blank = 1; phase = 5; } } else if (phase == 5){ //inter trial interval (ITI) blank = 1; MoveEye(trial_cond.abs_heading, 0); if (((ticks1-ticks0) >= FRAMELENGTH) && resp != 0){ resp_lock=1;//to prevent multiple responses being entered in the ITI disp = 0; //goes back to 0 position correct = ((resp * trial_cond.rel_heading) / (abs(resp) * abs(trial_cond.rel_heading)) + 1) / 2; fprintf(outfile, "%s, %d, %d, %f, %4.2f, %d, %d, %d, %d, %f, %d, %d, \n", //fprintf(outfile, "%s, %d, %d, %f, %d, %d, %d, %d, %d, \n", subjStr, trial, FRAMELENGTH, trial_cond.rel_heading, //removed trial_cond.isi, trial_cond.obj_num[0], trial_cond.obj_num[1], trial_cond.objRandom, // resp, correct, bar_angle --removed these because these all depend ond the bar angle ord_change_num, rel_to_eye_change_num); //changetype was here fflush(outfile); if (!correct) cout << "\7\n"; resp=0; //remember to write to file before resetting! ++trial; if(trial==ntrials){ fclose(outfile); exit(0); } //makeCheckImage(); //makeFloorTexture(); //setParams(); phase = 3; ticks0 = (int)(clock()*1000/CLOCKS_PER_SEC); } } if (reportSpeed) { start = glutGet(GLUT_ELAPSED_TIME); } /* Clear; default stencil clears to zero. */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); lightPosition[0] = 1000+12*cos(lightAngle); lightPosition[1] = 50*lightHeight; lightPosition[2] = 12*sin(lightAngle); if (directionalLight) { lightPosition[3] = 0.0; } else { lightPosition[3] = 1.0; } shadowMatrix(floorShadow, floorPlane, lightPosition); glPushMatrix(); /* Perform scene rotations based on user mouse input. */ glRotatef(angle2, 1.0, 0.0, 0.0); glRotatef(angle, 0.0, 1.0, 0.0); /* Tell GL new light source position. */ glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); /* Back face culling will get used to only draw either the top or the bottom floor. This let's us get a floor with two distinct appearances. The top floor surface is reflective and kind of red. The bottom floor surface is not reflective and blue. */ /* Draw "bottom" of floor in blue. */ glFrontFace(GL_CW); /* Switch face orientation. */ glColor4f((GLfloat)0.1, (GLfloat)0.1, (GLfloat)0.7, 1.0); glColor4f(1.0, 1.0, 1.0, (GLfloat)0.3); //drawWall(); if (blank!=0) { drawBlankScreen(); } glFrontFace(GL_CCW); if (phase==1 || phase==3 || phase==4 || phase==5){ if (renderShadow) { if (stencilShadow) { // Draw the floor with stencil value 3. This helps us only // draw the shadow once per floor pixel (and only on the // floor pixels). glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, 3, 0xffffffff); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); } } } /* Draw "top" of floor. Use blending to blend in reflection. */ // glEnable(GL_BLEND); // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f((GLfloat)0.7, 0.0, 0.0, (GLfloat)0.3); glColor4f(1.0, 1.0, 1.0, (GLfloat)0.3); drawFloor(); if (blank!=1){//*******************why is this 1, when 0 in other similar cases? drawBlankScreen(); } glDisable(GL_BLEND); if (renderPolygons) { /* Draw "actual" Polygons, not its reflection. */ if (phase==1 || phase==3 || phase==4 || phase==5) { /* don't draw objs when not frame 1 or 2*/ drawPolygons(false); } } if (phase==1 || phase==3 || phase==4 || phase==5){ if (renderShadow) { /* Render the projected shadow. */ if (stencilShadow) { /* Now, only render where stencil is set above 2 (ie, 3 where the top floor is). Update stencil with 2 where the shadow gets drawn so we don't redraw (and accidently reblend) the shadow). */ // glStencilFunc(GL_LESS, 2, 0xffffffff); /* draw if ==1 */ // glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); } /* To eliminate depth buffer artifacts, we use polygon offset to raise the depth of the projected shadow slightly so that it does not depth buffer alias with the floor. */ if (offsetShadow) { switch (polygonOffsetVersion) { #ifdef GL_EXT_polygon_offset case EXTENSION: glEnable(GL_POLYGON_OFFSET_EXT); break; #endif #ifdef GL_VERSION_1_1 case ONE_DOT_ONE: glEnable(GL_POLYGON_OFFSET_FILL); break; #endif case MISSING: /* Oh well. */ break; } } /* Render 50% black shadow color on top of whatever the floor appareance is. */ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_LIGHTING); /* Force the 50% black. */ glColor4f(0.0, 0.0, 0.0, 0.5); glPushMatrix(); /* Project the shadow. */ glMultMatrixf((GLfloat *) floorShadow); drawPolygons(true); glPopMatrix(); glDisable(GL_BLEND); glEnable(GL_LIGHTING); if (offsetShadow) { switch (polygonOffsetVersion) { #ifdef GL_EXT_polygon_offset case EXTENSION: glDisable(GL_POLYGON_OFFSET_EXT); break; #endif #ifdef GL_VERSION_1_1 case ONE_DOT_ONE: glDisable(GL_POLYGON_OFFSET_FILL); break; #endif case MISSING: /* Oh well. */ break; } } if (stencilShadow) { glDisable(GL_STENCIL_TEST); } } } glPopMatrix(); if (reportSpeed) { glFinish(); end = glutGet(GLUT_ELAPSED_TIME); printf("Speed %.3g frames/sec (%d ms)\n", 1000.0/(end-start), end-start); } glutSwapBuffers(); } /* ARGSUSED1 */ void motion(int x, int y) { if (moving) { angle = angle + (x - startx); angle2 = angle2 + (y - starty); startx = x; starty = y; glutPostRedisplay(); } } /* Advance time varying state when idle callback registered. */ void idle(void) { static float time = 0.0; time = glutGet(GLUT_ELAPSED_TIME) / 500.0; glutPostRedisplay(); } enum { M_NONE, M_MOTION, M_LIGHT, M_TEXTURE, M_SHADOWS, M_REFLECTION, M_Polygons, M_STENCIL_REFLECTION, M_STENCIL_SHADOW, M_OFFSET_SHADOW, M_POSITIONAL, M_DIRECTIONAL, M_PERFORMANCE }; void controlLights(int value) { switch (value) { case M_NONE: return; case M_LIGHT: lightSwitch = !lightSwitch; if (lightSwitch) { glEnable(GL_LIGHT0); } else { glDisable(GL_LIGHT0); } break; case M_TEXTURE: useTexture = !useTexture; break; case M_SHADOWS: renderShadow = 1 - renderShadow; break; case M_Polygons: renderPolygons = 1 - renderPolygons; break; case M_STENCIL_REFLECTION: stencilReflection = 1 - stencilReflection; break; case M_STENCIL_SHADOW: stencilShadow = 1 - stencilShadow; break; case M_OFFSET_SHADOW: offsetShadow = 1 - offsetShadow; break; case M_POSITIONAL: directionalLight = 0; break; case M_DIRECTIONAL: directionalLight = 1; // frame2 = 1; break; case M_PERFORMANCE: reportSpeed = 1 - reportSpeed; break; } glutPostRedisplay(); } /* When not visible, stop animating. Restart when visible again. */ void visible(int vis) { glutIdleFunc(idle); } /* Press any key to redraw; good when motion stopped and performance reporting on. */ /* ARGSUSED */ void key(unsigned char c, int x, int y) { switch (c) { case ' ': if (phase==0) { phase = 3; } /* else if (phase==1) phase = 2; else if (phase==2) phase = 3; else if (phase==3 && ph==0) { ph = 1; } else if (ph==1) { ph = 0; phase = 4; } */ break; case '4': if (phase==4 && resp_lock!=1) { resp = -1; } break; case '6': if (phase==4 && resp_lock!=1){ resp = 1; } break; case 27: //esc key exits program exit(0); } glutPostRedisplay(); } int supportsOneDotOne(void) { const char *version; int major, minor; version = (char *) glGetString(GL_VERSION); if (sscanf(version, "%d.%d", &major, &minor) == 2) return major >= 1 && minor >= 1; return 0; /* OpenGL version string malformed! */ } int main(int argc, char **argv) { int i; glutInit(&argc, argv); unsigned seed = (unsigned int)time(NULL); //give me the current time as an integer srand(seed); //sets up rand num generator using the current time as its seed; should be done only once ticks0 = clock()/CLOCKS_PER_SEC*1000; ofstream ofs("seed.txt"); assert(ofs); ofs << "seed = " << seed << '\n'; assert(ofs); ofs.close(); GenerateConditions(); MakeTrialOrderRandom(TOTALTRIALS, order); SetObjectPos(TOTALTRIALS, order, obj); makeSubFile(); setParams(); for (i=1; i