From 66dcf910bd4744d8ced56cb9586aa937a1a2d4c5 Mon Sep 17 00:00:00 2001 From: vg Date: Tue, 7 Jul 2020 16:24:01 +0200 Subject: first commit --- cube_gl/ledcube.cpp | 522 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 522 insertions(+) create mode 100644 cube_gl/ledcube.cpp (limited to 'cube_gl/ledcube.cpp') diff --git a/cube_gl/ledcube.cpp b/cube_gl/ledcube.cpp new file mode 100644 index 0000000..91c869c --- /dev/null +++ b/cube_gl/ledcube.cpp @@ -0,0 +1,522 @@ +/* +* 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; +} -- cgit v1.2.3