aboutsummaryrefslogtreecommitdiffstats
path: root/cube_gl
diff options
context:
space:
mode:
Diffstat (limited to 'cube_gl')
-rw-r--r--cube_gl/Makefile14
-rw-r--r--cube_gl/effect.cpp776
-rw-r--r--cube_gl/effect.h26
-rw-r--r--cube_gl/font.cpp109
-rw-r--r--cube_gl/font.h13
-rw-r--r--cube_gl/ledcube.cpp522
-rw-r--r--cube_gl/ledcube.cpp.bak155
7 files changed, 1615 insertions, 0 deletions
diff --git a/cube_gl/Makefile b/cube_gl/Makefile
new file mode 100644
index 0000000..7c21b70
--- /dev/null
+++ b/cube_gl/Makefile
@@ -0,0 +1,14 @@
+CFLAGS=`pkg-config glu --cflags` `sdl-config --cflags` -lglut -ansi -Wall -m32
+LIBS=`pkg-config glu --libs` `sdl-config --libs`
+OBJS=ledcube.o effect.o font.o
+
+%.o:%.cpp
+ g++ $(CFLAGS) -o $@ -c $<
+
+all: ledcube
+
+clean:
+ rm -f ledcube $(OBJS)
+
+ledcube: $(OBJS)
+ g++ $(CFLAGS) $(LIBS) $(OBJS) -o $@
diff --git a/cube_gl/effect.cpp b/cube_gl/effect.cpp
new file mode 100644
index 0000000..4288fa0
--- /dev/null
+++ b/cube_gl/effect.cpp
@@ -0,0 +1,776 @@
+
+#include "effect.h"
+#include "font.h"
+#include <SDL.h>
+#include <cassert>
+#include <cmath>
+
+#define CUBE_SIZE 8
+#define CUBE_BYTES CUBE_SIZE*CUBE_SIZE
+#define AXIS_Z 2
+#define AXIS_Y 1
+#define AXIS_X 0
+
+unsigned char leds[8][8];
+volatile bool led_change = 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};
+
+/*****************************************************************************
+ * ACCESSORS
+ *****************************************************************************/
+
+unsigned char inrange(int x, int y, int z)
+{
+ if (x >= 0 && x < CUBE_SIZE && y >= 0 && y < CUBE_SIZE && z >= 0 && z < CUBE_SIZE)
+ {
+ return 1;
+ } else
+ {
+ // One of the coordinates was outside the cube.
+ return 0;
+ }
+}
+
+bool get_led(unsigned char x, unsigned char y, unsigned char z)
+{
+ /*
+ assert(x >= 0 && x <= 7);
+ assert(y >= 0 && y <= 7);
+ assert(z >= 0 && z <= 7);
+ */
+
+ if (inrange(x, y, z)) {
+ return leds[y][z] & (1 << x);
+ }
+
+ return false;
+}
+
+void set_led(unsigned char x, unsigned char y, unsigned char z, bool on)
+{
+
+ if (!inrange(x, y, z)) {
+ return;
+ }
+
+ /*
+ assert(x >= 0 && x <= 7);
+ assert(y >= 0 && y <= 7);
+ assert(z >= 0 && z <= 7);
+ */
+
+ if (on) {
+ leds[y][z] |= ((unsigned char)1) << x;
+ }
+ else {
+ leds[y][z] &= ~(((unsigned char)1) << x);
+ }
+}
+
+void clear_led()
+{
+ memset(leds, 0, sizeof(leds));
+}
+
+void set_voxel(int x, int y, int z)
+{
+ set_led(x, y, z, true);
+}
+
+void clr_voxel(int x, int y, int z)
+{
+ set_led(x, y, z, false);
+}
+
+void fill(char val)
+{
+ memset(leds, val, sizeof(leds));
+}
+
+void delay(unsigned t)
+{
+ led_change = true;
+ SDL_Delay(t);
+}
+
+/*****************************************************************************
+ * EFFECTS
+ *****************************************************************************/
+
+void test_effect()
+{
+ static int active_layer = 0;
+
+ for (int k = 0; k < 8; ++k) {
+ //std::cout << "boo" << std::endl;
+ for (int j = 0; j < 8; ++j) {
+ //std::cout << "boo2" << std::endl;
+ if (k == active_layer) {
+ //std::cerr << "active" << std::endl;
+ leds[j][k] = 0xFF;
+ }
+ else leds[j][k] = 0;
+ }
+ }
+ ++active_layer;
+ if (active_layer >= 8) {
+ active_layer = 0;
+ }
+}
+
+
+void sendvoxels_z(int x, int y, int z, int delay)
+{
+ assert(z == 0 || z == 7);
+
+ if (z == 7) {
+ for (int i = 0; i < 7; ++i) {
+ set_led(x, y, i, false);
+ set_led(x, y, i+1, true);
+ led_change = true;
+ SDL_Delay(delay);
+ }
+ }
+ else {
+ for(int i = 6; i >= 0; --i) {
+ set_led(x, y, i + 1, false);
+ set_led(x, y, i, true);
+ led_change = true;
+ SDL_Delay(delay);
+ }
+ }
+}
+
+
+void sendvoxels_random_z_effect(int maxiters,
+ int delay, /* speed of movement */
+ int wait) /* delay between 2 movement */
+{
+ clear_led(); // clear the cube
+ for (int j = 0; j < 8; ++j) {
+ for (int i = 0; i < 8; ++i) {
+ if (rand()%2) {
+ set_led(i, j, 0, true);
+ }
+ else {
+ set_led(i, j, 7, true);
+ }
+ }
+ }
+
+ int previous_x = 0, previous_y = 0;
+ for (int n = 0; n < maxiters ; ++n ) {
+ int x = rand()%8, y = rand()%8;
+
+ if (previous_x == x && previous_y == y) {
+ --n;
+ continue;
+ }
+
+ if (get_led(x, y, 0)) {
+ sendvoxels_z(x, y, 7, delay);
+ }
+ else if (get_led(x, y, 7)) {
+ sendvoxels_z(x, y, 0, delay);
+ }
+ SDL_Delay(wait);
+ }
+
+}
+
+void rain_effect(int iterations)
+{
+
+ for (int i = 0; i < iterations ; ++i) {
+
+ // clear layer 7
+ for (int j = 0 ; j < 8; ++j) {
+ leds[j][7] = 0;
+ }
+
+ // place pixels at random x and y coord at layer 7
+ int n = rand()%4;
+ for (int i2 = 0; i2 < n; ++i2) {
+ set_led(rand()%8, rand()%8, 7, 1);
+ }
+
+ led_change = true;
+ SDL_Delay(90);
+
+ // shift down
+ for (int k = 0; k < 7; ++k) {
+ for (int j = 0 ; j < 8; ++j) {
+ leds[j][k] = leds[j][k+1];
+ }
+ }
+ }
+}
+
+void set_plane(int axis, unsigned char index, bool on = true)
+{
+ switch(axis) {
+ case 0: // X
+ for (int k = 0; k < 8; ++k) {
+ for (int j = 0; j < 8; ++j) {
+ set_led(index, j, k, on);
+ }
+ }
+ break;
+ case 1: // Y
+ for (int k = 0; k < 8; ++k) {
+ for (int i = 0; i < 8; ++i) {
+ set_led(i, index, k, on);
+ }
+ }
+ break;
+ case 2: // Z
+ for (int j = 0; j < 8; ++j) {
+ for (int i = 0; i < 8; ++i) {
+ set_led(i, j, index, on);
+ }
+ }
+ break;
+ default:
+ assert(false);
+ }
+}
+
+void planboing(int plane, int speed)
+{
+ for (int i = 0; i < 8; ++i) {
+ clear_led(); // clear cube
+ set_plane(plane, i);
+ led_change = true;
+ SDL_Delay(speed);
+ }
+ for (int i = 7; i >= 0; --i) {
+ clear_led(); // clear cube
+ set_plane(plane, i);
+ led_change = true;
+ SDL_Delay(speed);
+ }
+}
+
+// Shift the entire contents of the cube along an axis
+// This is great for effects where you want to draw something
+// on one side of the cube and have it flow towards the other
+// side. Like rain flowing down the Z axiz.
+void shift (char axis, int direction)
+{
+ int i, x ,y;
+ int ii, iii;
+ //int state;
+
+ for (i = 0; i < CUBE_SIZE; i++) {
+ if (direction == -1) {
+ ii = i;
+ }
+ else {
+ ii = (7-i);
+ }
+
+
+ for (x = 0; x < CUBE_SIZE; x++)
+ {
+ for (y = 0; y < CUBE_SIZE; y++)
+ {
+ if (direction == -1)
+ {
+ iii = ii+1;
+ } else
+ {
+ iii = ii-1;
+ }
+
+ if (axis == 2)
+ {
+ set_led(x, y, ii, get_led(x, y, iii));
+ //state = get_led(x,y,iii);
+ //set_led(x,y,ii,state?false:true);
+ }
+
+ if (axis == 1)
+ {
+ set_led(x, ii, y, get_led(x, iii, y));
+ //state = get_led(x,iii,y);
+ //altervoxel(x,ii,y,state);
+ //set_led(x,ii,y,state?false:true);
+ }
+
+ if (axis == 0)
+ {
+ set_led(ii, y, x, get_led(iii, y, x));
+ //state = get_led(iii,y,x);
+ //set_led(ii,y,x,state?false:true);
+ }
+ }
+ }
+ }
+
+ if (direction == -1) {
+ i = 7;
+ }
+ else {
+ i = 0;
+ }
+
+ /*
+ for (x = 0; x < CUBE_SIZE; x++) {
+ for (y = 0; y < CUBE_SIZE; y++) {
+ if (axis == AXIS_Z) set_led(x,y,i, false);
+ if (axis == AXIS_Y) set_led(x,i,y, false);
+ if (axis == AXIS_X) set_led(i,y,x, false);
+ }
+ }
+
+ */
+ set_plane(axis, i, false);
+}
+
+
+// Flips a byte 180 degrees.
+// MSB becomes LSB, LSB becomes MSB.
+char flipbyte (char byte)
+{
+ char flop = 0x00;
+
+ flop = (flop & 0b11111110) | (0b00000001 & (byte >> 7));
+ flop = (flop & 0b11111101) | (0b00000010 & (byte >> 5));
+ flop = (flop & 0b11111011) | (0b00000100 & (byte >> 3));
+ flop = (flop & 0b11110111) | (0b00001000 & (byte >> 1));
+ flop = (flop & 0b11101111) | (0b00010000 & (byte << 1));
+ flop = (flop & 0b11011111) | (0b00100000 & (byte << 3));
+ flop = (flop & 0b10111111) | (0b01000000 & (byte << 5));
+ flop = (flop & 0b01111111) | (0b10000000 & (byte << 7));
+ return flop;
+}
+
+// Flip the cube 180 degrees along the y axis.
+void mirror_y (void)
+{
+ unsigned char buffer[CUBE_SIZE][CUBE_SIZE];
+ unsigned char x,y,z;
+
+ memcpy(buffer, leds, CUBE_BYTES); // copy the current cube into a buffer.
+
+ //fill(0x00);
+ clear_led();
+ for (z=0; z<CUBE_SIZE; z++)
+ {
+ for (y=0; y<CUBE_SIZE; y++)
+ {
+ for (x=0; x<CUBE_SIZE; x++)
+ {
+ if (buffer[y][z] & (0x01 << x))
+ set_led(x,CUBE_SIZE-1-y,z,true);
+ }
+ }
+ }
+
+}
+
+// Flip the cube 180 degrees along the x axis
+void mirror_x (void)
+{
+ unsigned char buffer[CUBE_SIZE][CUBE_SIZE];
+ unsigned char y,z;
+
+ memcpy(buffer, leds, CUBE_BYTES); // copy the current cube into a buffer.
+
+ //fill(0x00);
+ clear_led();
+
+ for (z=0; z<CUBE_SIZE; z++)
+ {
+ for (y=0; y<CUBE_SIZE; y++)
+ {
+ // This will break with different buffer sizes..
+ leds[y][z] = flipbyte(buffer[y][z]);
+ }
+ }
+}
+
+// flip the cube 180 degrees along the z axis
+void mirror_z (void)
+{
+ unsigned char buffer[CUBE_SIZE][CUBE_SIZE];
+ unsigned char z, y;
+
+ memcpy(buffer, leds, CUBE_BYTES); // copy the current cube into a buffer.
+
+ for (y=0; y<CUBE_SIZE; y++)
+ {
+ for (z=0; z<CUBE_SIZE; z++)
+ {
+ leds[y][CUBE_SIZE-1-z] = buffer[y][z];
+ }
+ }
+}
+
+
+// Makes sure x1 is alwas smaller than x2
+// This is usefull for functions that uses for loops,
+// to avoid infinite loops
+void argorder(int ix1, int ix2, int *ox1, int *ox2)
+{
+ if (ix1>ix2)
+ {
+ int tmp;
+ tmp = ix1;
+ ix1= ix2;
+ ix2 = tmp;
+ }
+ *ox1 = ix1;
+ *ox2 = ix2;
+}
+
+// Returns a byte with a row of 1's drawn in it.
+// byteline(2,5) gives 0b00111100
+char byteline (int start, int end)
+{
+ return ((0xff<<start) & ~(0xff<<(end+1)));
+}
+
+
+// Draw a wireframe box. This only draws the corners and edges,
+// no walls.
+void box_wireframe(
+ int x1, int y1, int z1,
+ int x2, int y2, int z2)
+{
+
+ int iy;
+ int iz;
+
+ argorder(x1, x2, &x1, &x2);
+ argorder(y1, y2, &y1, &y2);
+ argorder(z1, z2, &z1, &z2);
+
+ // Lines along X axis
+ leds[y1][z1] = byteline(x1,x2);
+ leds[y2][z1] = byteline(x1,x2);
+ leds[y1][z2] = byteline(x1,x2);
+ leds[y2][z2] = byteline(x1,x2);
+
+ // Lines along Y axis
+ for (iy=y1;iy<=y2;iy++)
+ {
+ set_led(x1,iy,z1, true);
+ set_led(x1,iy,z2, true);
+ set_led(x2,iy,z1, true);
+ set_led(x2,iy,z2, true);
+ }
+
+ // Lines along Z axis
+ for (iz=z1;iz<=z2;iz++)
+ {
+ set_led(x1,y1,iz, true);
+ set_led(x1,y2,iz, true);
+ set_led(x2,y1,iz, true);
+ set_led(x2,y2,iz, true);
+ }
+}
+
+void box_shrink_grow_effect(int iterations, int rot, int flip, int delay)
+{
+ for (int it = 0; it < iterations ; ++it) {
+ for (int it2 = 0; it2 < 16; ++it2) {
+ int xyz = it2 > 7 ? it2 - 8: 7 - it2;
+
+ clear_led();
+
+ box_wireframe(0, 0, 0, xyz, xyz, xyz);
+
+ if (flip > 0) mirror_z();
+ if (rot == 1 || rot == 3) mirror_y();
+ if (rot == 2 || rot == 3) mirror_x();
+
+ led_change = true;
+ SDL_Delay(delay);
+ }
+ }
+}
+
+void effect_box_woopwoop (int delay, int grow)
+{
+ int i,ii;
+
+ //fill(0x00);
+ clear_led();
+ for (i=0;i<4;i++)
+ {
+ ii = i;
+ if (grow > 0)
+ ii = 3-i;
+
+ box_wireframe(4+ii,4+ii,4+ii,3-ii,3-ii,3-ii);
+ led_change = true;
+ SDL_Delay(delay);
+ clear_led();
+ //delay_ms(delay);
+ //fill(0x00);
+ }
+}
+
+void draw_positions_axis (char axis, unsigned char positions[64], int invert)
+{
+ int x, y, p;
+
+ //fill(0x00);
+ clear_led();
+
+ for (x=0; x<8; x++)
+ {
+ for (y=0; y<8; y++)
+ {
+ if (invert)
+ {
+ p = (7-positions[(x*8)+y]);
+ } else
+ {
+ p = positions[(x*8)+y];
+ }
+
+ //if (axis == AXIS_Z)
+ if (axis == 2)
+ set_led(x,y,p, true);
+
+ if (axis == 1)
+ set_led(x,p,y, true);
+
+ if (axis == 0)
+ set_led(p,y,x, true);
+ }
+ }
+
+}
+
+
+
+void effect_axis_updown_randsuspend(char axis,
+ int delay, int sleep, int invert)
+{
+ unsigned char positions[64];
+ unsigned char destinations[64];
+
+ int i,px;
+
+ // Set 64 random positions
+ for (i=0; i<64; i++)
+ {
+ positions[i] = 0; // Set all starting positions to 0
+ destinations[i] = rand()%8;
+ }
+
+ // Loop 8 times to allow destination 7 to reach all the way
+ for (i=0; i<8; i++)
+ {
+ // For every iteration, move all position one step closer to their destination
+ for (px=0; px<64; px++)
+ {
+ if (positions[px]<destinations[px])
+ {
+ positions[px]++;
+ }
+ }
+ // Draw the positions and take a nap
+ draw_positions_axis (axis, positions,invert);
+ led_change = true;
+ SDL_Delay(delay);
+ //delay_ms(delay);
+ }
+
+ // Set all destinations to 7 (opposite from the side they started out)
+ for (i=0; i<64; i++)
+ {
+ destinations[i] = 7;
+ }
+
+ // Suspend the positions in mid-air for a while
+ //delay_ms(sleep);
+ SDL_Delay(sleep);
+
+ // Then do the same thing one more time
+ for (i=0; i<8; i++)
+ {
+ for (px=0; px<64; px++)
+ {
+ if (positions[px]<destinations[px])
+ {
+ positions[px]++;
+ }
+ if (positions[px]>destinations[px])
+ {
+ positions[px]--;
+ }
+ }
+ draw_positions_axis (axis, positions,invert);
+ led_change = true;
+ SDL_Delay(delay);
+ //delay_ms(delay);
+ }
+}
+
+void effect_stringfly2(const char* str)
+{
+ //int x,y,i;
+ unsigned char x,y,i;
+ unsigned char chr[5];
+ int delay = 80;
+
+ clear_led();
+
+ while (*str)
+ {
+ font_getchar(*str++, chr);
+
+ // Put a character on the back of the cube
+ for (x = 0; x < 5; x++)
+ {
+ for (y = 0; y < 8; y++)
+ {
+ if ((chr[x] & (0x80>>y)))
+ {
+ //setvoxel(7,x+2,y);
+ //set_led(7,x+2,y);
+ set_led(x+2, 7, y);
+ }
+ }
+ }
+
+ //led_change = true;
+ //SDL_Delay(1000);
+ //clear_led();
+ //continue;
+
+ // Shift the entire contents of the cube forward by 6 steps
+ // before placing the next character
+ for (i = 0; i<6; i++)
+ {
+ led_change = true;
+ //delay_ms(1000);
+ //SDL_Delay(1000);
+ SDL_Delay(delay);
+ //shift(AXIS_X,-1);
+ shift(1,-1);
+ //set_plane(1, 7, false);
+ }
+ }
+
+ //return;
+ // Shift the last character out of the cube.
+ for (i = 0; i<8; i++)
+ {
+ led_change = true;
+ SDL_Delay(delay);
+ //delay_ms(1000);
+ //shift(AXIS_X,-1);
+ shift(1,-1);
+ }
+}
+
+float distance2d (float x1, float y1, float x2, float y2)
+{
+ float dist;
+ dist = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
+
+ return dist;
+}
+
+float distance3d (float x1, float y1, float z1, float x2, float y2, float z2)
+{
+ float dist;
+ dist = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2));
+
+ return dist;
+}
+
+
+
+
+// Display a sine wave running out from the center of the cube.
+void ripples (int iterations, int delay)
+{
+ float distance, height, ripple_interval;
+ int x,y,i;
+
+ clear_led();
+ //fill(0x00);
+
+ for (i=0;i<iterations;i++)
+ {
+ for (x=0;x<8;x++)
+ {
+ for (y=0;y<8;y++)
+ {
+ distance = distance2d(3.5,3.5,x,y)/9.899495*8;
+ //distance = distance2d(3.5,3.5,x,y);
+ ripple_interval =1.3;
+ height = 4+sin(distance/ripple_interval+(float) i/50)*4;
+
+ //setvoxel(x,y,(int) height);
+ set_led(x,y,(int) height);
+ }
+ }
+ //delay_ms(delay);
+ led_change = true;
+ SDL_Delay(delay);
+ //fill(0x00);
+ clear_led();
+ }
+}
+
+
+
+/*****************************************************************************
+ * EFFECT LAUNCHER
+ *****************************************************************************/
+
+void launch_effect(int effect)
+{
+ switch(effect) {
+ case 0: rain_effect(100); break;
+ case 1: sendvoxels_random_z_effect(20, 50, 100); break;
+ case 2:
+ break;
+ case 3:
+ break;
+ case 4:
+ break;
+ case 5: ripples(1000, 50); break;
+ case 6:
+ 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);
+ break;
+ case 7:
+ for (int i = 0; i < 6; ++i) {
+ planboing(i%3, 50);
+ }
+ break;
+ case 9:
+ effect_axis_updown_randsuspend(2, 55, 100, 0);
+ effect_axis_updown_randsuspend(2, 55, 100, 1);
+ effect_axis_updown_randsuspend(2, 55, 100, 0);
+ effect_axis_updown_randsuspend(2, 55, 100, 1);
+ effect_axis_updown_randsuspend(0, 55, 100, 0);
+ effect_axis_updown_randsuspend(0, 55, 100, 1);
+ effect_axis_updown_randsuspend(1, 55, 100, 0);
+ effect_axis_updown_randsuspend(1, 55, 100, 1);
+ break;
+ case 12:
+ //clear_led();
+ //set_led(0, 0, 7);
+ //SDL_Delay(1000);
+ effect_stringfly2("Vive Lyly");
+ break;
+ default:
+ break;
+ }
+}
diff --git a/cube_gl/effect.h b/cube_gl/effect.h
new file mode 100644
index 0000000..90319d1
--- /dev/null
+++ b/cube_gl/effect.h
@@ -0,0 +1,26 @@
+#ifndef __EFFECT_H__
+#define __EFFECT_H__
+
+const int TOTAL_EFFECTS = 27;
+
+extern unsigned char leds[8][8];
+extern volatile bool led_change;
+
+bool get_led(unsigned char x, unsigned char y, unsigned char z);
+void set_led(unsigned char x, unsigned char y, unsigned char z, bool on = true);
+void clear_led();
+
+void rain_effect(int iterations);
+
+void planboing(int plane, int speed);
+
+void sendvoxels_random_z_effect(int maxiters,
+ int delay, /* speed of movement */
+ int wait); /* delay between 2 movement */
+
+void box_shrink_grow_effect(int iterations, int rotation, int flip, int delay);
+void effect_box_woopwoop (int delay, int grow);
+
+void launch_effect(int effect);
+
+#endif
diff --git a/cube_gl/font.cpp b/cube_gl/font.cpp
new file mode 100644
index 0000000..f48e4af
--- /dev/null
+++ b/cube_gl/font.cpp
@@ -0,0 +1,109 @@
+#include "font.h"
+//#include <avr/eeprom.h>
+
+volatile const unsigned char font[455] /*EEMEM*/ = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x5f,0x5f,0x00,0x00, // !
+ 0x00,0x03,0x00,0x03,0x00,0x14,0x7f,0x14,0x7f,0x14, // "#
+ 0x24,0x2a,0x7f,0x2a,0x12,0x23,0x13,0x08,0x64,0x62, // $%
+ 0x36,0x49,0x55,0x22,0x50,0x00,0x05,0x03,0x00,0x00, // &'
+ 0x00,0x1c,0x22,0x41,0x00,0x00,0x41,0x22,0x1c,0x00, // ()
+ 0x14,0x08,0x3e,0x08,0x14,0x08,0x08,0x3e,0x08,0x08, // *+
+ 0x00,0x50,0x30,0x00,0x00,0x08,0x08,0x08,0x08,0x08, // ,-
+ 0x00,0x60,0x60,0x00,0x00,0x20,0x10,0x08,0x04,0x02, // ./
+ 0x3e,0x51,0x49,0x45,0x3e,0x00,0x42,0x7f,0x40,0x00, // 01
+ 0x42,0x61,0x51,0x49,0x46,0x21,0x41,0x45,0x4b,0x31, // 23
+ 0x18,0x14,0x12,0x7f,0x10,0x27,0x45,0x45,0x45,0x39, // 45
+ 0x3c,0x4a,0x49,0x49,0x30,0x01,0x71,0x09,0x05,0x03, // 67
+ 0x36,0x49,0x49,0x49,0x36,0x06,0x49,0x49,0x29,0x1e, // 89
+ 0x00,0x36,0x36,0x00,0x00,0x00,0x56,0x36,0x00,0x00, // :;
+ 0x08,0x14,0x22,0x41,0x00,0x14,0x14,0x14,0x14,0x14, // <=
+ 0x00,0x41,0x22,0x14,0x08,0x02,0x01,0x51,0x09,0x06, // >?
+ 0x32,0x49,0x79,0x41,0x3e,0x7e,0x11,0x11,0x11,0x7e, // @A
+ 0x7f,0x49,0x49,0x49,0x36,0x3e,0x41,0x41,0x41,0x22, // BC
+ 0x7f,0x41,0x41,0x22,0x1c,0x7f,0x49,0x49,0x49,0x41, // DE
+ 0x7f,0x09,0x09,0x09,0x01,0x3e,0x41,0x49,0x49,0x7a, // FG
+ 0x7f,0x08,0x08,0x08,0x7f,0x00,0x41,0x7f,0x41,0x00, // HI
+ 0x20,0x40,0x41,0x3f,0x01,0x7f,0x08,0x14,0x22,0x41, // JK
+ 0x7f,0x40,0x40,0x40,0x40,0x7f,0x02,0x0c,0x02,0x7f, // LM
+ 0x7f,0x04,0x08,0x10,0x7f,0x3e,0x41,0x41,0x41,0x3e, // NO
+ 0x7f,0x09,0x09,0x09,0x06,0x3e,0x41,0x51,0x21,0x5e, // PQ
+ 0x7f,0x09,0x19,0x29,0x46,0x46,0x49,0x49,0x49,0x31, // RS
+ 0x01,0x01,0x7f,0x01,0x01,0x3f,0x40,0x40,0x40,0x3f, // TU
+ 0x1f,0x20,0x40,0x20,0x1f,0x3f,0x40,0x38,0x40,0x3f, // VW
+ 0x63,0x14,0x08,0x14,0x63,0x07,0x08,0x70,0x08,0x07, // XY
+ 0x61,0x51,0x49,0x45,0x43,0x00,0x7f,0x41,0x41,0x00, // Z[
+ 0x02,0x04,0x08,0x10,0x20,0x00,0x41,0x41,0x7f,0x00, // \]
+ 0x04,0x02,0x01,0x02,0x04,0x40,0x40,0x40,0x40,0x40, // ^_
+ 0x00,0x01,0x02,0x04,0x00,0x20,0x54,0x54,0x54,0x78, // `a
+ 0x7f,0x48,0x44,0x44,0x38,0x38,0x44,0x44,0x44,0x20, // bc
+ 0x38,0x44,0x44,0x48,0x7f,0x38,0x54,0x54,0x54,0x18, // de
+ 0x08,0x7e,0x09,0x01,0x02,0x0c,0x52,0x52,0x52,0x3e, // fg
+ 0x7f,0x08,0x04,0x04,0x78,0x00,0x44,0x7d,0x40,0x00, // hi
+ 0x20,0x40,0x44,0x3d,0x00,0x7f,0x10,0x28,0x44,0x00, // jk
+ 0x00,0x41,0x7f,0x40,0x00,0x7c,0x04,0x18,0x04,0x78, // lm
+ 0x7c,0x08,0x04,0x04,0x78,0x38,0x44,0x44,0x44,0x38, // no
+ 0x7c,0x14,0x14,0x14,0x08,0x08,0x14,0x14,0x18,0x7c, // pq
+ 0x7c,0x08,0x04,0x04,0x08,0x48,0x54,0x54,0x54,0x20, // rs
+ 0x04,0x3f,0x44,0x40,0x20,0x3c,0x40,0x40,0x20,0x7c, // tu
+ 0x1c,0x20,0x40,0x20,0x1c,0x3c,0x40,0x30,0x40,0x3c, // vw
+ 0x44,0x28,0x10,0x28,0x44,0x0c,0x50,0x50,0x50,0x3c, // xy
+ 0x44,0x64,0x54,0x4c,0x44 // z
+};
+
+
+volatile const unsigned char bitmaps[6][8] /*EEMEM*/ = {
+ {0xc3,0xc3,0x00,0x18,0x18,0x81,0xff,0x7e}, // smiley 3 small
+ {0x3c,0x42,0x81,0x81,0xc3,0x24,0xa5,0xe7}, // Omega
+ {0x00,0x04,0x06,0xff,0xff,0x06,0x04,0x00}, // Arrow
+ {0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81}, // X
+ {0xBD,0xA1,0xA1,0xB9,0xA1,0xA1,0xA1,0x00}, // ifi
+ {0xEF,0x48,0x4B,0x49,0x4F,0x00,0x00,0x00} // TG
+};
+
+const unsigned char paths[44] /*PROGMEM */= {0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x67,0x57,0x47,0x37,0x27,0x17,
+0x04,0x03,0x12,0x21,0x30,0x40,0x51,0x62,0x73,0x74,0x65,0x56,0x47,0x37,0x26,0x15}; // circle, len 16, offset 28
+
+/*
+void font_getpath (unsigned char path, unsigned char *destination, int length)
+{
+ int i;
+ int offset = 0;
+
+ if (path == 1)
+ offset=28;
+
+ for (i = 0; i < length; i++)
+ destination[i] = pgm_read_byte(&paths[i+offset]);
+}
+*/
+
+void font_getchar (char chr, unsigned char dst[5])
+{
+ //uint8_t i;
+ unsigned char i;
+ chr -= 32; // our bitmap font starts at ascii char 32.
+
+ for (i = 0; i < 5; i++)
+ //dst[i] = (unsigned char)eeprom_read_byte((uint8_t*)&font[(chr*5)+i]);
+ dst[i] = font[(chr*5)+i];
+}
+
+/*
+void font_getbitmap (char bitmap, unsigned char dst[8])
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ dst[i] = (unsigned char)eeprom_read_byte((uint8_t*)&bitmaps[(uint8_t)bitmap][(uint8_t)i]);
+
+}
+
+unsigned char font_getbitmappixel ( char bitmap, char x, char y)
+{
+ uint8_t tmp = eeprom_read_byte((uint8_t*)&bitmaps[(uint8_t)bitmap][(uint8_t)x]);
+ return (tmp >> y) & 0x01;
+}
+
+*/
+
+
diff --git a/cube_gl/font.h b/cube_gl/font.h
new file mode 100644
index 0000000..536801e
--- /dev/null
+++ b/cube_gl/font.h
@@ -0,0 +1,13 @@
+#ifndef FONT_H
+#define FONT_H
+
+//#include <avr/pgmspace.h>
+
+void font_getchar (char chr, unsigned char dst[5]);
+//void font_getpath (unsigned char path, unsigned char *destination, int length);
+//void font_getbitmap (char bitmap, unsigned char dst[8]);
+//unsigned char font_getbitmappixel ( char bitmap, char x, char y);
+
+
+
+#endif
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;
+}
diff --git a/cube_gl/ledcube.cpp.bak b/cube_gl/ledcube.cpp.bak
new file mode 100644
index 0000000..2fd6bd7
--- /dev/null
+++ b/cube_gl/ledcube.cpp.bak
@@ -0,0 +1,155 @@
+#include <GL/gl.h>
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <math.h>
+
+//angle of rotation
+float xpos = 0, ypos = 0, zpos = 0, xrot = 0, yrot = 0, angle=0.0;
+
+float lastx, lasty;
+
+//positions of the cubes
+float positionz[10];
+float positionx[10];
+
+void cubepositions (void) { //set the positions of the cubes
+
+ for (int i=0;i<10;i++)
+ {
+ positionz[i] = rand()%5 + 5;
+ positionx[i] = rand()%5 + 5;
+ }
+}
+
+//draw the cube
+void cube (void) {
+ for (int i=0;i<10;i++)
+ {
+ glPushMatrix();
+ glTranslated(-positionx[i + 1] * 10, 0, -positionz[i + 1] *
+ 10); //translate the cube
+ glutSolidCube(2); //draw the cube
+ glPopMatrix();
+ }
+}
+
+void init (void) {
+ cubepositions();
+}
+
+void enable (void) {
+ glEnable (GL_DEPTH_TEST); //enable the depth testing
+ glEnable (GL_LIGHTING); //enable the lighting
+ glEnable (GL_LIGHT0); //enable LIGHT0, our Diffuse Light
+ glShadeModel (GL_SMOOTH); //set the shader to smooth shader
+
+}
+
+void camera (void) {
+ glRotatef(xrot,1.0,0.0,0.0); //rotate our camera on teh x-axis (left and right)
+ glRotatef(yrot,0.0,1.0,0.0); //rotate our camera on the y-axis (up and down)
+ glTranslated(-xpos,-ypos,-zpos); //translate the screen to the position of our camera
+}
+
+void display (void) {
+ glClearColor (1.0,0.0,0.0,1.0); //clear the screen to black
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the color buffer and the depth buffer
+ glLoadIdentity();
+ camera();
+ enable();
+ cube(); //call the cube drawing function
+ glutSwapBuffers(); //swap the buffers
+ angle++; //increase the angle
+}
+
+void reshape (int w, int h) {
+ glViewport (0, 0, (GLsizei)w, (GLsizei)h); //set the viewport to the current window specifications
+ glMatrixMode (GL_PROJECTION); //set the matrix to projection
+
+ glLoadIdentity ();
+ gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 1000.0); //set the perspective (angle of sight, width, height, , depth)
+ glMatrixMode (GL_MODELVIEW); //set the matrix back to model
+
+}
+
+void keyboard (unsigned char key, int x, int y) {
+ if (key=='q')
+ {
+ xrot += 1;
+ if (xrot >360) xrot -= 360;
+ }
+
+ if (key=='z')
+ {
+ xrot -= 1;
+ if (xrot < -360) xrot += 360;
+ }
+
+ if (key=='w')
+ {
+ float xrotrad, yrotrad;
+ yrotrad = (yrot / 180 * 3.141592654f);
+ xrotrad = (xrot / 180 * 3.141592654f);
+ xpos += float(sin(yrotrad)) ;
+ zpos -= float(cos(yrotrad)) ;
+ ypos -= float(sin(xrotrad)) ;
+ }
+
+ if (key=='s')
+ {
+ float xrotrad, yrotrad;
+ yrotrad = (yrot / 180 * 3.141592654f);
+ xrotrad = (xrot / 180 * 3.141592654f);
+ xpos -= float(sin(yrotrad));
+ zpos += float(cos(yrotrad)) ;
+ ypos += float(sin(xrotrad));
+ }
+
+ if (key=='d')
+ {
+ float yrotrad;
+ yrotrad = (yrot / 180 * 3.141592654f);
+ xpos += float(cos(yrotrad)) * 0.2;
+ zpos += float(sin(yrotrad)) * 0.2;
+ }
+
+ if (key=='a')
+ {
+ float yrotrad;
+ yrotrad = (yrot / 180 * 3.141592654f);
+ xpos -= float(cos(yrotrad)) * 0.2;
+ zpos -= float(sin(yrotrad)) * 0.2;
+ }
+
+ if (key==27)
+ {
+ exit(0);
+ }
+}
+
+void mouseMovement(int x, int y) {
+ int diffx=x-lastx; //check the difference between the current x and the last x position
+ int diffy=y-lasty; //check the difference between the current y and the last y position
+ lastx=x; //set lastx to the current x position
+ lasty=y; //set lasty to the current y position
+ xrot += (float) diffy; //set the xrot to xrot with the addition of the difference in the y position
+ yrot += (float) diffx; //set the xrot to yrot with the addition of the difference in the x position
+}
+
+int main (int argc, char **argv) {
+ glutInit (&argc, argv);
+ glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH);
+ glutInitWindowSize (500, 500);
+ glutInitWindowPosition (100, 100);
+ glutCreateWindow ("A basic OpenGL Window");
+ init ();
+ glutDisplayFunc (display);
+ glutIdleFunc (display);
+ glutReshapeFunc (reshape);
+ glutPassiveMotionFunc(mouseMovement); //check for mouse movement
+ glutKeyboardFunc (keyboard);
+ glutMainLoop ();
+ return 0;
+}
+
+