69 lines
1.8 KiB
C
69 lines
1.8 KiB
C
#include "math.h"
|
|
|
|
#define HEIGHT 600
|
|
#define WIDTH 800
|
|
#define SQ_SIZE 100
|
|
|
|
typedef struct { double x, y; } Vec2d;
|
|
typedef struct { unsigned char r, g, b, a; } Color;
|
|
|
|
Color gradient[SQ_SIZE*SQ_SIZE] = {0};
|
|
Color buffer[WIDTH*HEIGHT] = {0};
|
|
Vec2d pos = {0};
|
|
double time = 0;
|
|
|
|
Color* get_buffer_ptr() {
|
|
return buffer;
|
|
}
|
|
|
|
int get_buffer_len() {
|
|
return WIDTH*HEIGHT;
|
|
}
|
|
|
|
void compute_gradient(Color* output_buffer, int width, int height) {
|
|
for (int y = 0; y < height; y++) {
|
|
for (int x = 0; x < width; x++) {
|
|
output_buffer[y*width+x] = (Color){
|
|
.r = (x * 255) / (width - 1),
|
|
.g = (y * 255) / (height - 1),
|
|
.b = 0,
|
|
.a = 255
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
void init() {
|
|
compute_gradient(gradient, SQ_SIZE, SQ_SIZE);
|
|
}
|
|
|
|
void render_frame(double dt) {
|
|
time += dt;
|
|
double x = 0.5 + cos(2.0 * PI / 10.0 * time) * 0.5;
|
|
double y = 0.5 + sin(2.0 * PI / 10.0 * time) * 0.5;
|
|
pos.x = x * (WIDTH - SQ_SIZE);
|
|
pos.y = y * (HEIGHT - SQ_SIZE);
|
|
|
|
// Clear the framebuffer before drawing the next frame.
|
|
__builtin_memset(buffer, 0, sizeof(buffer));
|
|
|
|
// Clamp coordinates before indexing the framebuffer to avoid a bad
|
|
// coordinate from turning into an out-of-bounds write.
|
|
int pos_x = (int)pos.x;
|
|
int pos_y = (int)pos.y;
|
|
if (pos_x < 0) pos_x = 0;
|
|
if (pos_y < 0) pos_y = 0;
|
|
if (pos_x > WIDTH - SQ_SIZE) pos_x = WIDTH - SQ_SIZE;
|
|
if (pos_y > HEIGHT - SQ_SIZE) pos_y = HEIGHT - SQ_SIZE;
|
|
|
|
for (int y = pos_y; y < pos_y + SQ_SIZE; ++y) {
|
|
for (int x = pos_x; x < pos_x + SQ_SIZE; ++x) {
|
|
// Sample point from gradient
|
|
int local_x = x - pos_x;
|
|
int local_y = y - pos_y;
|
|
Color c = gradient[local_y * SQ_SIZE + local_x];
|
|
buffer[y * WIDTH + x] = c;
|
|
}
|
|
}
|
|
}
|