aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c272
1 files changed, 0 insertions, 272 deletions
diff --git a/main.c b/main.c
deleted file mode 100644
index b25c212..0000000
--- a/main.c
+++ /dev/null
@@ -1,272 +0,0 @@
-#include <limits.h>
-#include <float.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <math.h>
-
-typedef enum {
- kRetSucc,
- kRetFail,
-} Ret;
-
-typedef struct {
- int width;
- int height;
- float *buffer;
-} Picture;
-
-typedef struct {
- float r;
- float g;
- float b;
-} Color;
-
-typedef struct {
- int x;
- int y;
-} Vec2i;
-
-
-Picture new_picture(int width, int height) {
- Picture ret;
- ret.width = width;
- ret.height = height;
- ret.buffer = malloc(sizeof(float) * width * height * 3);
- return ret;
-}
-
-void delete_picture(Picture pic) {
- free(pic.buffer);
-}
-
-void set_pixel(Picture pic, Vec2i pos, Color c) {
- int idx = pos.y * pic.width * 3 + pos.x * 3;
- pic.buffer[idx] = c.b;
- pic.buffer[idx+1] = c.g;
- pic.buffer[idx+2] = c.r;
-}
-
-Ret fwrite_word16le(FILE* fp, uint16_t x) {
- uint8_t buf[2];
- buf[0] = x & 0xff;
- buf[1] = (x >> 8) & 0xff;
- int r = fwrite(buf, 1, 2, fp);
- if (r != 2) return kRetFail;
- return kRetSucc;
-}
-
-Ret fwrite_word32le(FILE* fp, uint32_t x) {
- Ret ret;
- uint16_t buf[2];
-
- buf[0] = x & 0xffff;
- buf[1] = (x >> 16) & 0xffff;
- ret = fwrite_word16le(fp, buf[0]);
- if (ret != kRetSucc) return ret;
- ret = fwrite_word16le(fp, buf[1]);
- if (ret != kRetSucc) return ret;
- return kRetSucc;
-}
-
-
-Ret writeBMP(const char* filename, Picture pic) {
- Ret ret = kRetFail;
- FILE *fp = NULL;
- uint8_t *databuf = NULL;
-
- fp = fopen(filename, "wb");
- if (!fp) goto end;
-
- int row_data_len = 3 * pic.width;
- int padding = (4 - row_data_len % 4) % 4;
- int row_len = row_data_len + padding;
- int img_len = row_len * pic.height;
- int file_len = 53 + img_len;
-
- ret = fwrite_word16le(fp, 0x4d42);
- if (ret != kRetSucc) goto end;
- ret = fwrite_word32le(fp, file_len);
- if (ret != kRetSucc) goto end;
- ret = fwrite_word32le(fp, 0);
- if (ret != kRetSucc) goto end;
- ret = fwrite_word32le(fp, 54);
- if (ret != kRetSucc) goto end;
-
- ret = fwrite_word32le(fp, 40);
- if (ret != kRetSucc) goto end;
- ret = fwrite_word32le(fp, pic.width);
- if (ret != kRetSucc) goto end;
- ret = fwrite_word32le(fp, -pic.height);
- if (ret != kRetSucc) goto end;
- ret = fwrite_word16le(fp, 1);
- if (ret != kRetSucc) goto end;
- ret = fwrite_word16le(fp, 24);
- if (ret != kRetSucc) goto end;
- ret = fwrite_word32le(fp, 0); // BI_RGB
- if (ret != kRetSucc) goto end;
- ret = fwrite_word32le(fp, img_len);
- if (ret != kRetSucc) goto end;
- ret = fwrite_word32le(fp, 0);
- if (ret != kRetSucc) goto end;
- ret = fwrite_word32le(fp, 0);
- if (ret != kRetSucc) goto end;
- ret = fwrite_word32le(fp, 0);
- if (ret != kRetSucc) goto end;
- ret = fwrite_word32le(fp, 0);
- if (ret != kRetSucc) goto end;
-
- databuf = malloc(img_len);
- memset(databuf, 0, img_len);
- for (int i = 0; i < pic.height; i++) {
- for (int j = 0; j < pic.width * 3; j++) {
- int fromidx = i * pic.width * 3 + j;
- int toidx = i * row_len + j;
- float value = pic.buffer[fromidx];
- if (value < 0) databuf[toidx] = 0;
- else if (value > 1.0) {
- databuf[toidx] = 255;
- } else databuf[toidx] = 255 * value;
- }
- }
- if (fwrite(databuf, 1, img_len, fp) != img_len) {
- ret = kRetFail;
- goto end;
- }
- ret = kRetSucc;
-
-end:
- if (databuf != NULL) free(databuf);
- if (fp != NULL) fclose(fp);
- return ret;
-}
-
-typedef struct {
- float x;
- float y;
- float z;
-} Vec3f;
-
-Vec3f screen_proj(int width, int height, Vec2i sp) {
- Vec3f ret;
- float maxlen = width > height ? width : height;
- ret.z = 1;
- ret.x = (sp.x - width / 2.0) / maxlen;
- ret.y = (-sp.y + height / 2.0) / maxlen;
- return ret;
-}
-
-Color icolor(int r, int g, int b) {
- return (Color){.r = r/255.0, .g = g/255.0, .b = b/255.0};
-}
-
-typedef struct {
- Vec3f center;
- float r;
- Color color;
-} Ball;
-
-Ball balls[] = {
- {
- .center = {.x = 0, .y = -1, .z = 3},
- .r = 1,
- },
- {
- .center = {.x = 2, .y = 0, .z = 4},
- .r = 1,
- },
- {
- .center = {.x = -2, .y = 0, .z = 4},
- .r = 1,
- },
-};
-
-
-Color gBackgroupColor = {0,0,0};
-
-void init_color() {
- balls[0].color = icolor(0x95, 0xe1, 0xe3);
- balls[1].color = icolor(0xfc, 0xe3, 0x8a);
- balls[2].color = icolor(0xf3, 0x81, 0x81);
- gBackgroupColor = icolor(0xea, 0xea, 0xea);
-}
-
-Vec3f vec3f_sub(Vec3f lhs, Vec3f rhs) {
- return (Vec3f){
- .x = lhs.x - rhs.x,
- .y = lhs.y - rhs.y,
- .z = lhs.z - rhs.z,
- };
-}
-
-float vec3f_dot(Vec3f lhs, Vec3f rhs) {
- return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;
-}
-
-float ball_intersect(Vec3f start, Vec3f ray, Ball *ball) {
- Vec3f sc = vec3f_sub(start, ball->center);
- float a = vec3f_dot(ray, ray);
- float b = 2 * vec3f_dot(sc, ray);
- float c = vec3f_dot(sc, sc) - ball->r * ball->r;
- float delta = b*b - 4*a*c;
- if (delta < 0) {
- return -1;
- }
- float t1 = (-b + sqrt(delta)) / 2*a;
- float t2 = (-b - sqrt(delta)) / 2*a;
- return t1 < t2 ? t1 : t2;
-}
-
-Color calc_color(Vec3f v) {
- Vec3f start = {.x = 0, .y = 0, .z = 0};
- float tmin = 0.1;
- float tmax = FLT_MAX;
-
- int nearest_idx = -1;
- float t_nearest = FLT_MAX;
- for (int i = 0; i < sizeof(balls) / sizeof(Ball); i++) {
- float t = ball_intersect(start, v, &balls[i]);
- // printf("t:%f\n", t);
- if (t < t_nearest && t < tmax && t > tmin) {
- t_nearest = t;
- nearest_idx = i;
- }
- }
- if (nearest_idx >= 0) {
- return balls[nearest_idx].color;
- } else {
- return gBackgroupColor;
- }
-}
-
-void normalize_picture(Picture pic) {
- float maxval = 0;
- for (size_t i = 0; i < pic.width * pic.height * 3; i++) {
- float val = pic.buffer[i];
- if (val < 0) val = 0;
- if (val > maxval) maxval = val;
- }
- if (maxval < 1.0) return;
- for (size_t i = 0; i < pic.width * pic.height * 3; i++) {
- pic.buffer[i] = pic.buffer[i] / maxval;
- }
-}
-
-int main() {
- init_color();
- int img_w = 1280;
- int img_h = 720;
- Picture pic = new_picture(img_w, img_h);
- for (int x = 0; x < img_w; x++) {
- for (int y = 0; y < img_h; y++) {
- Vec2i screen_pos = {x, y};
- Vec3f v = screen_proj(img_w, img_h, screen_pos);
- set_pixel(pic, screen_pos, calc_color(v));
- }
- }
- writeBMP("test.bmp", pic);
- delete_picture(pic);
- return 0;
-}
-