diff options
Diffstat (limited to 'cube_gl')
-rw-r--r-- | cube_gl/Makefile | 14 | ||||
-rw-r--r-- | cube_gl/effect.cpp | 776 | ||||
-rw-r--r-- | cube_gl/effect.h | 26 | ||||
-rw-r--r-- | cube_gl/font.cpp | 109 | ||||
-rw-r--r-- | cube_gl/font.h | 13 | ||||
-rw-r--r-- | cube_gl/ledcube.cpp | 522 | ||||
-rw-r--r-- | cube_gl/ledcube.cpp.bak | 155 |
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; +} + + |