Move rendering logic into camera module
This commit is contained in:
58
demo.c
58
demo.c
@@ -1,27 +1,16 @@
|
|||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "ff.h"
|
#include "ff.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "ray.h"
|
|
||||||
#include "vec3.h"
|
|
||||||
|
|
||||||
#include <float.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define W 800
|
#define W 800
|
||||||
#define H 600
|
#define H 600
|
||||||
|
|
||||||
#define FOCAL_LEN 1.0
|
#define FOCAL_LEN 1.0
|
||||||
#define VIEWPORT_H 2.0
|
#define VIEWPORT_H 2.0
|
||||||
|
|
||||||
#define NELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
|
#define NELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||||
|
|
||||||
static const vec3_t lightblue = { 0.4, 0.6, 1.0 };
|
|
||||||
static const vec3_t white = { 1.0, 1.0, 1.0 };
|
|
||||||
static const vec3_t red = { 1.0, 0.1, 0.2 };
|
|
||||||
|
|
||||||
static const vec3_t camera_pos = { 0.0, 0.0, 0.0 };
|
static const vec3_t camera_pos = { 0.0, 0.0, 0.0 };
|
||||||
|
|
||||||
static const obj_t scene[] = {
|
static const obj_t scene[] = {
|
||||||
@@ -32,54 +21,11 @@ static const obj_t scene[] = {
|
|||||||
|
|
||||||
static pix_t pixbuf[W * H];
|
static pix_t pixbuf[W * H];
|
||||||
|
|
||||||
static vec3_t raycol(ray_t ray)
|
|
||||||
{
|
|
||||||
bool got_hit = false;
|
|
||||||
hit_t hit = { .t = DBL_MAX };
|
|
||||||
for (unsigned i = 0; i < NELEMS(scene); ++i) {
|
|
||||||
if (scene[i].intersect(scene[i].params, ray, &hit, 0.0, hit.t))
|
|
||||||
got_hit = true;
|
|
||||||
}
|
|
||||||
if (got_hit)
|
|
||||||
return vec3_scale(vec3_add(hit.normal, white), 0.5);
|
|
||||||
|
|
||||||
const double a = (ray.dir.y + 1.0) / 2.0;
|
|
||||||
return vec3_add(vec3_scale(lightblue, a), vec3_scale(white, 1 - a));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setpix(vec3_t col, pix_t *out)
|
|
||||||
{
|
|
||||||
out->r = UINT16_MAX * col.x;
|
|
||||||
out->g = UINT16_MAX * col.y;
|
|
||||||
out->b = UINT16_MAX * col.z;
|
|
||||||
out->a = UINT16_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
img_t img = { .w = W, .h = H, .pix = pixbuf };
|
img_t img = { .pix = pixbuf };
|
||||||
camera_t camera = camera_init(camera_pos, FOCAL_LEN, VIEWPORT_H, W, H);
|
camera_t camera = camera_init(camera_pos, FOCAL_LEN, VIEWPORT_H, W, H);
|
||||||
|
camera_render(&camera, scene, NELEMS(scene), &img);
|
||||||
for (unsigned y = 0; y < H; ++y) {
|
|
||||||
fprintf(stderr, "\r[%3d/%3d]", y, H);
|
|
||||||
fflush(stderr);
|
|
||||||
|
|
||||||
const vec3_t row
|
|
||||||
= vec3_add(camera.pix_origin, vec3_scale(camera.y_step, y));
|
|
||||||
for (unsigned x = 0; x < W; ++x) {
|
|
||||||
const vec3_t pix = vec3_add(row, vec3_scale(camera.x_step, x));
|
|
||||||
const ray_t ray = {
|
|
||||||
.orig = camera.pos,
|
|
||||||
.dir = vec3_unit(pix),
|
|
||||||
};
|
|
||||||
const vec3_t col = raycol(ray);
|
|
||||||
setpix(col, img.pix + (W * y + x));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "\r[%3d/%3d]\n", H, H);
|
|
||||||
|
|
||||||
ff_write(STDOUT_FILENO, img);
|
ff_write(STDOUT_FILENO, img);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#ifndef CAMERA_H
|
#ifndef CAMERA_H
|
||||||
#define CAMERA_H
|
#define CAMERA_H
|
||||||
|
|
||||||
|
#include "img.h"
|
||||||
|
#include "obj.h"
|
||||||
#include "vec3.h"
|
#include "vec3.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -8,10 +10,15 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
vec3_t pos;
|
vec3_t pos;
|
||||||
vec3_t pix_origin, x_step, y_step;
|
vec3_t pix_origin, x_step, y_step;
|
||||||
|
uint32_t img_width, img_height;
|
||||||
} camera_t;
|
} camera_t;
|
||||||
|
|
||||||
camera_t camera_init(
|
camera_t camera_init(
|
||||||
vec3_t pos, double focal_len, double viewport_height, uint32_t img_width,
|
vec3_t pos, double focal_len, double viewport_height, uint32_t img_width,
|
||||||
uint32_t img_height);
|
uint32_t img_height);
|
||||||
|
|
||||||
|
void camera_render(
|
||||||
|
const camera_t *camera, const obj_t *scene, unsigned scene_count,
|
||||||
|
img_t *img_out);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
60
src/camera.c
60
src/camera.c
@@ -1,5 +1,36 @@
|
|||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
|
|
||||||
|
#include "ray.h"
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static const vec3_t lightblue = { 0.4, 0.6, 1.0 };
|
||||||
|
static const vec3_t white = { 1.0, 1.0, 1.0 };
|
||||||
|
|
||||||
|
static vec3_t trace(ray_t ray, const obj_t *scene, unsigned scene_count)
|
||||||
|
{
|
||||||
|
bool got_hit = false;
|
||||||
|
hit_t hit = { .t = DBL_MAX };
|
||||||
|
for (unsigned i = 0; i < scene_count; ++i) {
|
||||||
|
if (scene[i].intersect(scene[i].params, ray, &hit, 0.0, hit.t))
|
||||||
|
got_hit = true;
|
||||||
|
}
|
||||||
|
if (got_hit)
|
||||||
|
return vec3_scale(vec3_add(hit.normal, white), 0.5);
|
||||||
|
|
||||||
|
const double a = (ray.dir.y + 1.0) / 2.0;
|
||||||
|
return vec3_add(vec3_scale(lightblue, a), vec3_scale(white, 1 - a));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setpix(vec3_t col, pix_t *out)
|
||||||
|
{
|
||||||
|
out->r = UINT16_MAX * col.x;
|
||||||
|
out->g = UINT16_MAX * col.y;
|
||||||
|
out->b = UINT16_MAX * col.z;
|
||||||
|
out->a = UINT16_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
camera_t camera_init(
|
camera_t camera_init(
|
||||||
vec3_t pos, double focal_len, double viewport_height, uint32_t img_width,
|
vec3_t pos, double focal_len, double viewport_height, uint32_t img_width,
|
||||||
uint32_t img_height)
|
uint32_t img_height)
|
||||||
@@ -22,5 +53,34 @@ camera_t camera_init(
|
|||||||
.pix_origin = pix_origin,
|
.pix_origin = pix_origin,
|
||||||
.x_step = x_step,
|
.x_step = x_step,
|
||||||
.y_step = y_step,
|
.y_step = y_step,
|
||||||
|
.img_width = img_width,
|
||||||
|
.img_height = img_height,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void camera_render(
|
||||||
|
const camera_t *camera, const obj_t *scene, unsigned scene_count,
|
||||||
|
img_t *img_out)
|
||||||
|
{
|
||||||
|
const uint32_t w = img_out->w = camera->img_width;
|
||||||
|
const uint32_t h = img_out->h = camera->img_height;
|
||||||
|
|
||||||
|
for (unsigned y = 0; y < h; ++y) {
|
||||||
|
fprintf(stderr, "\r[%3d/%3d]", y, h);
|
||||||
|
fflush(stderr);
|
||||||
|
|
||||||
|
const vec3_t row
|
||||||
|
= vec3_add(camera->pix_origin, vec3_scale(camera->y_step, y));
|
||||||
|
for (unsigned x = 0; x < w; ++x) {
|
||||||
|
const vec3_t pix = vec3_add(row, vec3_scale(camera->x_step, x));
|
||||||
|
const ray_t ray = {
|
||||||
|
.orig = camera->pos,
|
||||||
|
.dir = vec3_unit(pix),
|
||||||
|
};
|
||||||
|
const vec3_t col = trace(ray, scene, scene_count);
|
||||||
|
setpix(col, img_out->pix + (w * y + x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "\r[%3d/%3d]\n", h, h);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user