aboutsummaryrefslogtreecommitdiffstats
path: root/cube_gl/ledcube.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cube_gl/ledcube.cpp')
-rw-r--r--cube_gl/ledcube.cpp522
1 files changed, 522 insertions, 0 deletions
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 <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <math.h>
+#include <GL/glut.h>
+
+#include <string.h>
+#include <strings.h>
+#include <time.h>
+
+#include "effect.h"
+
+#include <SDL.h>
+#include <SDL_thread.h>
+
+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;
+}