/***********************************************************************\ * Graphics thread for the LaLanne program, the BOINC API Exerciser * * Can be used with/without GLUT -- just set USE_GLUT to use GLUT, * or if left unset then use GL without GLUT. * * Eric Myers - 23 July 2004 * @(#) last tested with version 5.02 of 14 August 2006 \***********************************************************************/ #ifdef _WIN32 /* Windows */ # include "boinc_win.h" # define M_PI 3.1415926535897 #else /* Unix */ # include # include #endif #define PI2 2.0*M_PI #ifdef BOINC_APP_GRAPHICS # ifdef __APPLE_CC__ /* Apple (what, no GLUT?) */ # include # include # include "mac_carbon_gl.h" # elif _WIN32 /* Windows */ # include # else /* Unix */ # include # endif # # include "graphics_api.h" /* General graphics API for BOINC */ # #endif // BOINC_APP_GRAPHICS #include "boinc_api.h" #include "eah_poster.h" /* for poster functions */ bool is_ending=false; /* signal that we are to wrap it up... */ bool gfx_inited=false; /* signal that graphics were used */ /* Unused BOINC callbacks: */ void boinc_app_mouse_button(int x, int y, int which, int is_down) {} void boinc_app_mouse_move(int x, int y, int left, int middle, int right) {} void app_graphics_reread_prefs(){} #ifndef BOINC_APP_GRAPHICS void app_graphics_init() {}; void app_graphics_resize(int w, int h) {}; void app_graphics_render(int xs, int ys, double time_of_day){}; void boinc_app_key_press(int, int) {}; void boinc_app_key_release(int, int) {}; #else #ifndef USE_GLUT /* Draw a wire cube similar to glutWireCube() */ void WireCube (GLfloat size){ glPushMatrix(); glBegin(GL_LINES); /* draws lines between *pairs* of vertices */ /* back face */ glVertex3f(-0.5, -0.5, -0.5); glVertex3f(-0.5, +0.5, -0.5); glVertex3f(+0.5, -0.5, -0.5); glVertex3f(+0.5, +0.5, -0.5); glVertex3f(-0.5, -0.5, -0.5); glVertex3f(+0.5, -0.5, -0.5); glVertex3f(+0.5, +0.5, -0.5); glVertex3f(-0.5, +0.5, -0.5); /* front face */ glVertex3f(-0.5, -0.5, +0.5); glVertex3f(-0.5, +0.5, +0.5); glVertex3f(+0.5, -0.5, +0.5); glVertex3f(+0.5, +0.5, +0.5); glVertex3f(-0.5, -0.5, +0.5); glVertex3f(+0.5, -0.5, +0.5); glVertex3f(+0.5, +0.5, +0.5); glVertex3f(-0.5, +0.5, +0.5); /* join back to front */ glVertex3f(-0.5, -0.5, -0.5); glVertex3f(-0.5, -0.5, +0.5); glVertex3f(-0.5, +0.5, -0.5); glVertex3f(-0.5, +0.5, +0.5); glVertex3f(+0.5, -0.5, -0.5); glVertex3f(+0.5, -0.5, +0.5); glVertex3f(+0.5, +0.5, -0.5); glVertex3f(+0.5, +0.5, +0.5); glEnd(); glPopMatrix(); } #endif // USE_GLUT #ifdef USE_GLUT /******************************* * Write text from string at current raster position using given font */ void write_text(char *string, void *font){ int len, i; len = (int) strlen(string); for (i = 0; i < len; i++) { glutBitmapCharacter(font, string[i]); } } #endif // USE_GLUT /*************************************************** * BOINC Graphics callbacks: * */ /* Object ID for demonstrating GLUT Display List */ GLuint ObjID1; /******************************* * What to do when graphics are "initialized" */ void app_graphics_init() { fprintf(stderr,"GFX: app_graphics_init() called. \n"); gfx_inited=true; /* Drawing setup: */ glClearColor(0.0, 0.0, 0.30, 0.0); glShadeModel(GL_FLAT); /* Enable depth buffering for 3D graphics */ glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glFrustum (-1.0, 1.0, -1.0, 1.0, 1.0, 20.0); glMatrixMode (GL_MODELVIEW); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); #ifdef USE_GLUT /* Create an object stored in a Display List */ ObjID1 = glGenLists(1); glNewList(ObjID1, GL_COMPILE); glutWireSphere(0.25, 10, 8); glEndList(); #endif glFlush(); } /******************************* * How to respond to window resize? */ void app_graphics_resize(int w, int h) { fprintf(stderr,"GFX: app_graphics_resize(%d, %d) called. \n", w, h); glViewport(0, 0, w, h); } /******************************* * Rendering routine: this is what does the drawing: */ void app_graphics_render(int xs, int ys, double time_of_day){ double t, x, y, z, dt = 0; double g, b, alpha; /* rectangle colors */ double theta, r = 2.00; /* how far out to view from */ static double start_time=-1.0, last_time=-1.0; /* Calculate the time t since we started (or reset) and the * time dt since the last render() call. Both may be useful * for timing animations. */ if ( start_time < 0.0 ) start_time = time_of_day; t = time_of_day - start_time; if (last_time < 0.0) last_time = time_of_day - 0.01; dt = time_of_day - last_time; last_time = time_of_day; /* Start from a clean slate... */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity (); /* clear the transformation matrix */ /* Time to quit? Then just show the poster */ if(is_ending) { eah_poster_render(); return; } /* Animation: Decide on a viewpoint */ theta = PI2/20.0 * t; x = r * cos(theta); z = r * sin(theta); y = 0.73* cos(theta/2.3748); gluLookAt ( x, y, z, /* eyes position */ 0.0, 0.0, 0.0, /* looking toward here */ 0.0, 1.0, 0.0); /* which way is up? y axis! */ /* Draw the wire cube */ glColor3f (1.0, 1.0, 0.0); // Yellow glLineWidth(4.0); #ifdef USE_GLUT glutWireCube (1.0); #else WireCube (1.0); #endif glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); /* A 2D rectangle inside the cube */ b = (int(t*17) % 256) / 256.0; // Blue and Green change g = (int(t*11) % 256) / 256.0; // ... as time goes by alpha = 0.5 + 0.5*cos( t/4.0); glColor4f(1.0, g, b, alpha); glRectf(-0.25, -0.25, 0.25, 0.25); // Rectangle glDisable(GL_BLEND); #ifdef USE_GLUT /* Text annotation using GLUT bitmap font */ glRasterPos3f(-0.25, -1.5, 0.0); write_text("Pirates@Home", GLUT_BITMAP_TIMES_ROMAN_24); #endif /* Points to mark the x,y,z axes */ glPointSize(8.0); glBegin(GL_POINTS); glColor3f(1.0, 1.0, 1.0); /* WHITE */ glVertex3f(0.0, 0.0, 0.0); /* at the origin */ glColor3f(1.0, 0.0, 0.0); /* RED */ glVertex3f(0.75, 0.0, 0.0); /* marks the x axis */ glColor3f(0.0, 1.0, 0.0); /* GREEN */ glVertex3f(0.0, .75, 0.0); /* marks the y axis */ glColor3f(0.0, 0.0, 1.0); /* BLUE */ glVertex3f(0.0, 0.0, 0.75); /* marks the z axis */ glEnd(); #ifdef USE_GLUT /* play back Object from display list */ glTranslatef(0.0, -0.25, 0.0); glLineWidth(1.0); glColor3f(1.0, 1.0, 1.0); glCallList(ObjID1); #endif glFlush(); } /******************************* * How to handle key pressed/released events: */ void boinc_app_key_press(int key, int lParam) { fprintf(stderr,"GFX: boinc_app_key_press(%d,%d)\n", key, lParam); if(key==16) fprintf(stderr," SHIFT key\n"); if(key==112) fprintf(stderr," F1 key\n"); if(key==65) fprintf(stderr," A key\n"); } void boinc_app_key_release(int key, int lParam) { fprintf(stderr,"GFX: boinc_app_key_release(%d,%d)\n", key, lParam); } #endif /* APP_BOINC_GRAPICS */ /* EOF */