From f847ebb221922b36280001479ff6e46706071df8 Mon Sep 17 00:00:00 2001 From: Michael Georgoulopoulos Date: Sun, 16 Oct 2016 23:43:56 +0300 Subject: [PATCH] Many thunders from origin to random points on a rotating sphere --- src/thunder.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 134 insertions(+), 13 deletions(-) diff --git a/src/thunder.c b/src/thunder.c index 08c094e..db25bb2 100644 --- a/src/thunder.c +++ b/src/thunder.c @@ -16,19 +16,40 @@ #define BLUR_BUFFER_SIZE (BLUR_BUFFER_WIDTH * BLUR_BUFFER_HEIGHT) static unsigned char *blurBuffer, *blurBuffer2; -#define THUNDER_RECT_SIZE 4 -#define THUNDER_RANDOMNESS 80 +#define BLUR_DARKEN 4 + +#define THUNDER_RECT_SIZE 2 +#define THUNDER_RANDOMNESS 16 #define THUNDER_SECONDS 0.1f +#define VERTEX_COUNT 12 +#define PERSPECTIVE_NEUTRAL_DEPTH 0.5f +#define NEAR_PLANE 0.01f +#define ROTATION_SPEED 1.5f + +#define PI 3.14159f + /* TODO: Load palette from file */ static unsigned short palette[256]; +typedef struct { + float x,y,z; +} MyVertex ; + +MyVertex vertexBuffer[VERTEX_COUNT]; +MyVertex vertexBufferAnimated[VERTEX_COUNT]; +MyVertex vertexBufferProjected[VERTEX_COUNT]; + void clearBlurBuffer(); -void drawPatternOnBlurBuffer(int seed); void applyBlur(); void blitEffect(); void thunder(int x0, int y0, int x1, int y1, int seed, int randomness, int depth); +void initMesh(); +void projectMesh(); +void animateMesh(); +void renderMesh(int seed); + static int init(void); static void destroy(void); static void start(long trans_time); @@ -62,9 +83,11 @@ static int init(void) /* For now, map to blue */ for (i = 0; i < 256; i++) { - palette[i] = i >> 3; + palette[i] = (i * i) >> 11; } + initMesh(); + return 0; } @@ -97,12 +120,16 @@ static void draw(void) remainingThunderDuration = THUNDER_SECONDS; } + animateMesh(); + projectMesh(); + renderMesh(thunderPattern); - drawPatternOnBlurBuffer(thunderPattern); applyBlur(); blitEffect(); + + swap_buffers(0); } @@ -112,9 +139,6 @@ void clearBlurBuffer() { memset(blurBuffer2, 0, BLUR_BUFFER_SIZE); } -void drawPatternOnBlurBuffer(int seed) { - thunder(20, 20, 140, 100, seed, THUNDER_RANDOMNESS, 6); -} void applyBlur() { int i, j; @@ -125,8 +149,10 @@ void applyBlur() { for (j = 0; j < 120; j++) { for (i = 0; i < 160; i++) { *dst = (*(src - 1) + *(src + 1) + *(src - BLUR_BUFFER_WIDTH) + *(src + BLUR_BUFFER_WIDTH)) >> 2; - if (*dst > 4) *dst -= 4; + + if (*dst > BLUR_DARKEN) *dst -= BLUR_DARKEN; else *dst = 0; + dst++; src++; } @@ -177,12 +203,16 @@ void blitEffect() { } void thunder(int x0, int y0, int x1, int y1, int seed, int randomness, int depth) { - int mx = ((x0 + x1) >> 1) + rand() % randomness - randomness / 2; - int my = ((y0 + y1) >> 1) + rand() % randomness - randomness / 2; - int i, j; - unsigned char *dst = blurBuffer + BLUR_BUFFER_WIDTH + 1 + mx + my * BLUR_BUFFER_WIDTH; + int mx, my, i, j; + unsigned char *dst; + + if (randomness <= 0) randomness = 1; + mx = ((x0 + x1) >> 1) + rand() % randomness - randomness / 2; + my = ((y0 + y1) >> 1) + rand() % randomness - randomness / 2; + dst = blurBuffer + BLUR_BUFFER_WIDTH + 1 + mx + my * BLUR_BUFFER_WIDTH; if (depth <= 0) return; + if (mx < THUNDER_RECT_SIZE || mx >= 160 - THUNDER_RECT_SIZE || my < THUNDER_RECT_SIZE || my >= 120 - THUNDER_RECT_SIZE) return; srand(seed); @@ -195,5 +225,96 @@ void thunder(int x0, int y0, int x1, int y1, int seed, int randomness, int depth thunder(mx, my, x1, y1, rand(), randomness >> 1, depth - 1); } +MyVertex randomVertex() { + MyVertex ret; + float l; + + ret.x = rand() % 200 - 100; if (ret.x == 0) ret.x = 1; + ret.y = rand() % 200 - 100; if (ret.y == 0) ret.y = 1; + ret.z = rand() % 200 - 100; if (ret.z == 0) ret.z = 1; + + // Normalize + l = sqrt(ret.x * ret.x + ret.y * ret.y + ret.z * ret.z); + ret.x /= l; + ret.y /= l; + ret.z /= l; + + return ret; +} + +void initMesh() { + int i; + + for (i = 0; i < VERTEX_COUNT; i++) { + vertexBuffer[i] = randomVertex(); + } +} + +void animateMesh() { + int i = 0; + MyVertex bx, by, bz; + float yRot; + + yRot = ROTATION_SPEED * time_msec / 1000.0f; + + /* Create rotated basis */ + bx.x = cos(yRot); + bx.y = 0.0f; + bx.z = sin(yRot); + + by.x = 0.0f; + by.y = 1.0f; + by.z = 0.0f; + + bz.x = cos(yRot + PI/2.0f); + bz.y = 0.0f; + bz.z = sin(yRot + PI/2.0f); + + for (i = 0; i < VERTEX_COUNT; i++) { + MyVertex v1, v2; + v1 = vertexBuffer[i]; + + /* O re panaia mou */ + v2.x = v1.x * bx.x + v1.y * by.x + v1.z * bz.x; + v2.y = v1.x * bx.y + v1.y * by.y + v1.z * bz.y; + v2.z = v1.x * bx.z + v1.y * by.z + v1.z * bz.z; + + + v2.z += 1.00f; + + vertexBufferAnimated[i] = v2; + } +} + +void projectMesh() { + int i = 0; + for (i = 0; i < VERTEX_COUNT; i++) { + if (vertexBufferAnimated[i].z <= NEAR_PLANE) { + vertexBufferProjected[i].x = vertexBufferProjected[i].y = 1000.0f; + vertexBufferProjected[i].z = -1.0f; + continue; + } + + vertexBufferProjected[i].x = vertexBufferAnimated[i].x * PERSPECTIVE_NEUTRAL_DEPTH / vertexBufferAnimated[i].z; + vertexBufferProjected[i].y = vertexBufferAnimated[i].y * PERSPECTIVE_NEUTRAL_DEPTH / vertexBufferAnimated[i].z; + } +} + +void renderMesh(int seed) { + int vertex, j; + int sx, sy; + unsigned char *dst; + + srand(seed); + + for (vertex = 0; vertex < VERTEX_COUNT; vertex++) { + sx = (int)(vertexBufferProjected[vertex].x * 80) + 80; + sy = (int)(vertexBufferProjected[vertex].y * 60) + 60; + + /*if (sx < THUNDER_RECT_SIZE || sx >= 160 - THUNDER_RECT_SIZE || sy < THUNDER_RECT_SIZE || sy >= 120 - THUNDER_RECT_SIZE) return;*/ + + thunder(80, 60, sx, sy, rand(), THUNDER_RANDOMNESS, 5); + } +} \ No newline at end of file -- 1.7.10.4