/* * Copyright 2010 - Jean-Baptiste Fasquel * ISTIA - Angers university * Jean-Baptiste.Fasquel@univ-angers.fr */ //#include "stdafx.h" #include #include #include #include #include #include #include #include #include #include "effect.h" #include #include volatile bool thread_must_quit = false; //unsigned char pow2[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; //const unsigned char pow2[8] = {128, 64, 32, 16, 8, 4, 2, 1}; const float ViewedPointX = 0.0; const float ViewedPointY = 0.0; const float ViewedPointZ = 0.0; const float CurrentViewUpX = 0; const float CurrentViewUpY = 1; const float CurrentViewUpZ = 0; float CurrentCameraPosX; float CurrentCameraPosY; float CurrentCameraPosZ; int nbCaseX = 10; int nbCaseZ = 10; // 3.14159 const float CPI = M_PI; const float C2PI = 2*CPI; float current_angle = CPI/2; float current_angle2 = 0;//CPI/2; const float angle_delta = 0.2; float dist = 20; const float dist_delta = 1; enum direction_en { D_LEFT, D_RIGHT }; void update_camera() { //CurrentCameraPosX = dist * cosf(current_angle); //CurrentCameraPosZ = dist * sinf(current_angle); CurrentCameraPosX = dist*cosf(current_angle)*cosf(current_angle2); CurrentCameraPosZ = dist*sinf(current_angle)*cosf(current_angle2); CurrentCameraPosY = dist*sinf(current_angle2); //* cosf(current_angle); //CurrentCameraPosX = dist*sinf(current_angle)*sinf(current_angle2); //CurrentCameraPosZ = dist*sinf(current_angle)*cosf(current_angle2); //CurrentCameraPosY = dist*cosf(current_angle2); //glRotatef(current_angle, 0, 0, 1); //glRotatef(current_angle2, 0, 1, 0); glutPostRedisplay(); } void rotate_camera(direction_en dir) { switch(dir) { case D_LEFT: current_angle += angle_delta; break; case D_RIGHT: current_angle -= angle_delta; break; } if (current_angle > C2PI) { current_angle -= C2PI; } else if (current_angle < -C2PI) { current_angle += C2PI; } } /// Draw axis void drawAxis() { glDisable(GL_LIGHTING); glLineWidth(1); glBegin(GL_LINES); //(0,x) en rouge glColor3d(1,0,0); glVertex3i(0,0,0); glVertex3i(1,0,0); //(O,y) en vert glColor3d(0,1,0); glVertex3i(0,0,0); glVertex3i(0,1,0); //(O,z) en bleu glColor3d(0,0,1); glVertex3i(0,0,0); glVertex3i(0,0,1); glEnd(); glEnable(GL_LIGHTING); } /// DrawQuad void drawQuad() { glBegin(GL_QUADS); glVertex3f(0.0,0.0,0.0); glVertex3f(0.0,0.0,1.0); glVertex3f(1.0,0.0,1.0); glVertex3f(1.0,0.0,0.0); glEnd(); } /// DrawDamier void drawDamier() { float black[3]={0.0,0.0,0.0}; float white[3]={1.0,1.0,1.0}; for( int i = -nbCaseX ; i <= nbCaseX ; i++ ) { for( int k = -nbCaseZ ; k <= nbCaseZ ; k++ ) { int c=pow((float)(-1),i+k); // (-1)^{i+k} c < 0 ? glColor3fv(white) : glColor3fv(black); ; glPushMatrix(); glTranslatef((GLfloat )i,0.0,(GLfloat )k); drawQuad(); glPopMatrix(); } } } float led_size = 0.1; float led_spacing = 1.4; void draw_led(bool on) { glPushMatrix(); //glTranslatef(4, 0, 4); //glTranslatef(0.05,0.05,0.05); //glColor3f(on?1.0:0.3, 0.2, 0.2); glColor4f(on?1.0:0.5, on?0.6:0.4, on?0.6:0.4, on?1:0.3); glutSolidCube(led_size); glPopMatrix(); } void draw_ledcube() { glPushMatrix(); float translate_size = -led_spacing*8/2; glTranslatef(translate_size, translate_size, -translate_size); for (int k = 0; k < 8; ++k) { glPushMatrix(); for (int j = 0; j < 8; ++j) { glPushMatrix(); for (int i = 0; i < 8; ++i) { //draw_led((i+j*k)%2); //draw_led(leds[j][k] & pow2[i]); //if (i == j && j == k && k == 0) draw_led(true); else draw_led(get_led(i, j, k)); glTranslatef(led_spacing, 0, 0); } glPopMatrix(); glTranslatef(0, 0, -led_spacing); } glPopMatrix(); glTranslatef(0, led_spacing, 0); } glPopMatrix(); } ///(Re)Configure la caméra et affiche le contenu de la scène void Displayfct() { glClearColor(0,0,0,0); // selectionne la couleur noire (qui est celle par défaut) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Model view pour définir la caméra glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Restaure la matrice de modélisation-visualisation //glRotatef(current_angle, 0, 1, 0); //glRotatef(current_angle2, 1, 0, 1); gluLookAt(CurrentCameraPosX, CurrentCameraPosY , CurrentCameraPosZ, ViewedPointX, ViewedPointY, ViewedPointZ, CurrentViewUpX, CurrentViewUpY, CurrentViewUpZ); //Draw axis //drawAxis(); //Draw damier //drawDamier(); //Draw ilot //drawIlot(); // draw led cube draw_ledcube(); //vide tous les buffers et exécute toutes les commandes en attente //glFlush(); glutSwapBuffers(); } ///Invoqué pour le changement de taille de la fenêtre avant le Displayfct() void ReshapeFunc(int w,int h) { //printf("ReshapeFunc: %d, %d\n",w,h); glViewport(0,0,w,h); // Ajustement de la taille de la fenêtre glMatrixMode(GL_PROJECTION); // Choisit la matrice de projection glLoadIdentity(); glFrustum(-1.,1.,-1.,1.,1.,40.); } void animation(int x) { ((void)x); //test_effect(); // 100 ms //rain_effect(); // 100 ms //plane_effect(); // 50ms if (led_change) { led_change = false; glutPostRedisplay(); } glutTimerFunc(40, animation, 0); } void IdleFunct() { static int nbRedisplay = 0 ; //Pour éviter de surcharger la machine pendant trop longtemps if( nbRedisplay < 100 ) { rotate_camera(D_RIGHT); update_camera(); nbRedisplay = 0; } else { ++nbRedisplay ; } } ///Gère les menus void MainMenuCallBack(int selection) { static bool idle_active = false; static bool light0_active = true; static bool light1_active = true; switch(selection) { case 0: if (idle_active) { idle_active = false; glutIdleFunc(0); } else { idle_active = true; glutIdleFunc(IdleFunct); } break; case 1 : thread_must_quit = true; exit(0); break; case 2 : /* toggle light 0 */ if (light0_active) { glDisable(GL_LIGHT0); light0_active = false; } else { glEnable(GL_LIGHT0); light0_active = true; } glutPostRedisplay(); break; case 3 : /* toggle light 1 */ if (light1_active) { glDisable(GL_LIGHT1); light1_active = false; } else { glEnable(GL_LIGHT1); light1_active = true; } glutPostRedisplay(); break; default: return; break; } } void initgl() { glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glShadeModel(GL_SMOOTH) ; //en GL_FLAT: on voit les détails de la sphère glEnable(GL_DEPTH_TEST) ; glEnable(GL_LIGHTING); glEnable(GL_COLOR_MATERIAL); //sinon, pas de couleurs ///Light0 GLfloat lightColor0[4] = {1.0,1.0,0.5,1.0}; glLightfv(GL_LIGHT0,GL_AMBIENT,lightColor0); GLfloat lightPos0[4] = {1.0,0.0,1.0,0.0}; glLightfv(GL_LIGHT0,GL_POSITION,lightPos0); glEnable(GL_LIGHT0) ; ///Light1 GLfloat lightColor1[4] = {0.5,1.0,1.0,1.0}; glLightfv(GL_LIGHT1,GL_AMBIENT,lightColor1); GLfloat lightPos1[4] = {-1.0,0.0,1.0,0.0}; glLightfv(GL_LIGHT1,GL_POSITION,lightPos1); glEnable(GL_LIGHT1) ; //CurrentCameraPosX = dist * cosf(current_angle); //CurrentCameraPosZ = dist * sinf(current_angle); glEnable(GL_BLEND); // activation blending pour la transparence glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* for (int i = 0; i < 8; ++i) { for (int j = 0; j < 8; ++j) { leds[i][j] = 0xF0; } } */ srand(time(0)); animation(0); update_camera(); } void keyboardfunc(unsigned char key, int x, int y) { if (key == 0x1b || key == 'q' || key == 'Q') { thread_must_quit = true; exit(0); } } void specialfunc(int key, int x, int y) { switch(key) { case GLUT_KEY_UP: dist -= dist_delta; break; case GLUT_KEY_DOWN: dist += dist_delta; break; case GLUT_KEY_LEFT: rotate_camera(D_LEFT); break; case GLUT_KEY_RIGHT: rotate_camera(D_RIGHT); break; } if (dist < 1) { dist = 1; } update_camera(); } bool mouse_update_camera = false; int mouse_x; int mouse_y; #if !defined(GLUT_WHEEL_UP) # define GLUT_WHEEL_UP 3 # define GLUT_WHEEL_DOWN 4 #endif void mousefunc(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { mouse_x = x; mouse_y = y; mouse_update_camera = true; } else if (button == GLUT_WHEEL_UP && state == GLUT_UP) { dist -= dist_delta; update_camera(); } else if (button == GLUT_WHEEL_DOWN && state == GLUT_UP) { dist += dist_delta; update_camera(); } else { //std::cerr << "button : " << button << std::endl; mouse_update_camera = false; } } void motionfunc(int x, int y) { if (mouse_update_camera) { int diff_x = x - mouse_x; int diff_y = y - mouse_y; mouse_x = x; mouse_y = y; //std::cout << mouse_x - x << " " << mouse_y - y << std::endl; float scale_factor = 0.05; current_angle += diff_x * scale_factor; current_angle2 += diff_y * scale_factor; if (current_angle2 >= CPI/2) { current_angle2 = CPI/2 - 0.0001; } else if(current_angle2 <= -CPI/2) { current_angle2 = - CPI/2 + 0.0001; } //CurrentCameraPosY += diff_y * 0.2; //CurrentCameraPosY += diff_y * 0.2; update_camera(); } } SDL_Thread* thread = 0; void sdl_exit_thread() { if (thread) { ; //SDL_WaitThread(thread, 0); } } int thread_func(void* unused) { ((void)unused); while (!thread_must_quit) { launch_effect(rand()%TOTAL_EFFECTS); //launch_effect(12); //rain_effect(1000); //for (int i = 0; i < 6; ++i) { // //planboing(i%3, 50); //} ////sendvoxels_random_z_effect(1000, 50, 100); //for (int i = 0; i < 8; ++i) { // box_shrink_grow_effect(1, i%4, i & 0x4, 50); //} //effect_box_woopwoop(80, 0); //effect_box_woopwoop(80, 1); //effect_box_woopwoop(80, 0); //effect_box_woopwoop(80, 1); //SDL_Delay(40); } return 0; } int main(int argc,char **argv) { //Initialisation de la fenêtre glutInit(&argc,argv); glutInitWindowPosition(100,100); glutInitWindowSize(400,400); glutInitDisplayMode(GLUT_RGBA |GLUT_DOUBLE | GLUT_DEPTH); glutCreateWindow("TD1"); if (SDL_Init(SDL_INIT_TIMER) < 0) { std::cerr << "Error: " << SDL_GetError() << std::endl; exit(1); } atexit(SDL_Quit); //Initialisation d'opengl initgl(); //Menu glutCreateMenu(MainMenuCallBack); glutAddMenuEntry("Toggle animation", 0); glutAddMenuEntry("Toggle light 0", 2); glutAddMenuEntry("Toggle light 1", 3); glutAddMenuEntry("Quitter",1); glutAttachMenu(GLUT_RIGHT_BUTTON); //Callbacks glutDisplayFunc(Displayfct); glutReshapeFunc(ReshapeFunc); glutSpecialFunc(specialfunc); glutKeyboardFunc(keyboardfunc); glutMouseFunc(mousefunc); glutMotionFunc(motionfunc); // thread thread = SDL_CreateThread(thread_func, 0); if (!thread) { std::cerr << "Error creating thread : " << SDL_GetError() << std::endl; exit(1); } atexit(sdl_exit_thread); //Infinite loop glutMainLoop(); thread_must_quit = true; return 0; }