deltatime handling

This commit is contained in:
Alexander Bass 2024-04-23 01:08:47 -04:00
parent a3a74765c9
commit 92aa9071fe
5 changed files with 107 additions and 54 deletions

2
.clangd Normal file
View file

@ -0,0 +1,2 @@
CompileFlags:
Add: [-std=c17, -D_POSIX_C_SOURCE=199309L]

View file

@ -6,10 +6,11 @@ SRC_DIRS := ./src ./includes
RESOURCE_DIRS := ./resources
CC := gcc
ld := g++
ld := gcc
BASEFLAGS = -g -Wall -Wextra -Wconversion -Wduplicated-branches -Wduplicated-cond -Wlogical-op -Wnull-dereference -Wdouble-promotion -Wshadow -Wformat=2
LDFLAGS = -lm
BASEFLAGS = -std=c17 -g -O3 -D_POSIX_C_SOURCE=199309L -Wall -Wextra -Wconversion -Wduplicated-branches -Wduplicated-cond -Wlogical-op -Wnull-dereference -Wdouble-promotion -Wshadow -Wformat=2
CFLAGS = $(BASEFLAGS) -Wjump-misses-init
# Find all the C and C++ files we want to compile
# Note the single quotes around the * expressions. The shell will incorrectly expand these otherwise, but we want to send the * directly to the find command.

View file

@ -4,17 +4,16 @@
#include "donut.h"
#include "point.h"
#include "types.h"
#include "point_list.h"
#include "texture.h"
#include "types.h"
#include "vec3.h"
#include <math.h>
vec3_t sample_rgb(texture_t tex, size_t index) {
u8 red = tex.bytes[index];
u8 green = tex.bytes[index + 1];
u8 blue = tex.bytes[index + 2];
vec3_t color = vec3((f64)red, (f64)green, (f64)blue);
vec3_t color = {(f64)red, (f64)green, (f64)blue};
color = mul_vec(color, vec3(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0));
return color;
};
@ -27,16 +26,16 @@ vec3_t mix_transparency(vec3_t transparent, vec3_t solid) {
}
}
void generate_cube(point_list_t *points, texture_t bottom_tex, texture_t top_tex, texture_t side_tex, i32 face_x, i32 face_y) {
const vec3_t grass_color_scale = vec3(0.4, 1.0, 0.4);
const vec3_t grass_color_scale = {0.4, 1.0, 0.4};
const size_t image_size = 16;
const size_t point_count = 32;
const size_t point_count = 20;
const size_t world_width = 16;
for (size_t l_x = 0; l_x < point_count; l_x++) {
for (size_t l_y = 0; l_y < point_count; l_y++) {
f64 sx = (f64)l_x / (f64)point_count;
f64 sy = (f64)l_y / (f64)point_count;
size_t index = 3 * ((size_t)(sx * (f64)(image_size)) + (size_t)(sy * (f64)(image_size)) * image_size);
size_t index = 3 * ((size_t)(round(sx * (f64)(image_size))) + (size_t)(round(sy * (f64)(image_size)) * image_size));
vec3_t dirt = sample_rgb(bottom_tex, index);
vec3_t grass = sample_rgb(top_tex, index);
vec3_t side = sample_rgb(side_tex, index);

View file

@ -1,6 +1,6 @@
// Alexander Bass
// Created 4/16/24
// Modified 4/21/24
// Modified 4/23/24
#include "donut.h"
#include "point.h"
@ -15,49 +15,74 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
const i32 WIDTH = 120;
const i32 HEIGHT = 90;
const i32 DEPTH = WIDTH;
#define WIDTH 120
#define HEIGHT 90
#define DEPTH WIDTH
void draw(vec4_t *, const point_list_t *);
void update(point_list_t *);
#define SECONDS_TO_NANOSECONDS 1000000000
#define FRAMERATE 30
#define LARGEST_PIXEL_CHAR_STRING "\033[38;2;255;255;255m██"
#define LARGEST_PIXEL_CHAR_LEN sizeof(LARGEST_PIXEL_CHAR_STRING) - 1
void draw(vec4_t *, const point_list_t *, char *);
void update(point_list_t *, u64);
int main() {
texture_t dirt = load_ppm_file("dirt.ppm");
texture_t grass = load_ppm_file("grass_top.ppm");
texture_t grass_side = load_ppm_file("grass_side.ppm");
// point_list_t points = point_list(300);
point_list_t points = generate_donut(dirt, grass, grass_side);
// extend_point_list(&points, &donut_points);
// free_point_list(&donut_points);
free_texture(&dirt);
free_texture(&grass);
free_texture(&grass_side);
vec4_t *pixel_buffer = malloc((size_t)(WIDTH * HEIGHT) * sizeof(vec4_t));
for (u32 i = 0; i < (u32)(WIDTH * HEIGHT); i++) {
// pixel_buffer[i] = vec4(0.0, 0.0, 0.0, 0.0);
vec4_t *pixel_buffer = malloc(WIDTH * HEIGHT * sizeof(vec4_t));
for (u32 i = 0; i < (WIDTH * HEIGHT); i++) {
pixel_buffer[i] = vec4(0.0, 0.0, 0.0, 0.0);
};
struct timespec tim;
tim.tv_sec = 0;
tim.tv_nsec = 1000000L * 1000L / 60L;
size_t char_buffer_capacity = (HEIGHT * WIDTH * LARGEST_PIXEL_CHAR_LEN + HEIGHT);
char *screen_char_buffer = malloc(char_buffer_capacity * sizeof(char));
__SYSCALL_SLONG_TYPE frame_budget = SECONDS_TO_NANOSECONDS / FRAMERATE;
struct timespec frame_start, frame_end, sleep_time;
sleep_time.tv_sec = 0;
sleep_time.tv_nsec = frame_budget;
u64 counter = 0;
while (true) {
clock_gettime(CLOCK_MONOTONIC_RAW, &frame_start);
// Move cursor to top left
printf("\033[0;0H");
// Draw points
draw(pixel_buffer, &points);
draw(pixel_buffer, &points, screen_char_buffer);
// Rotate points
update(&points);
// Wait
nanosleep(&tim, NULL);
// Repeat
update(&points, counter);
// Compute time until next frame
clock_gettime(CLOCK_MONOTONIC_RAW, &frame_end);
__SYSCALL_SLONG_TYPE diff_ns = frame_end.tv_nsec - frame_start.tv_nsec;
__SYSCALL_SLONG_TYPE diff_s = frame_end.tv_sec - frame_start.tv_sec;
diff_ns += SECONDS_TO_NANOSECONDS * diff_s;
__SYSCALL_SLONG_TYPE excess = diff_ns > frame_budget ? 0 : frame_budget - diff_ns;
// if (excess == 0) {
// printf("\033[38;2;255;255;255mCan't keep up; Exiting. Ran for %lu frames\n", counter);
// exit(0);
// }
sleep_time.tv_nsec = excess;
counter += 1;
// Wait until next frame
nanosleep(&sleep_time, NULL);
}
free_point_list(&points);
@ -65,20 +90,32 @@ int main() {
return 0;
}
i32 w_x_to_screen(f64 w_x) {
return (i32)(round(w_x)) + WIDTH / 2;
inline size_t w_x_to_screen(f64 w_x) {
return (size_t)(round(w_x)) + WIDTH / 2;
}
i32 w_y_to_screen(f64 w_y) {
return (i32)(round(w_y)) + HEIGHT / 2;
inline size_t w_y_to_screen(f64 w_y) {
return (size_t)(round(w_y)) + HEIGHT / 2;
}
f64 w_z_to_screen(f64 w_z) {
inline f64 w_z_to_screen(f64 w_z) {
return (w_z + (f64)(DEPTH) / 2.0) / (f64)(DEPTH);
}
void draw(vec4_t *pixel_buffer, const point_list_t *points) {
for (u32 i = 0; i < (u32)(WIDTH * HEIGHT); i++) {
inline void push_string(char *to, const char *from, size_t *to_length) {
// Assumes `to` has enough room for the string in `from`
size_t i = 0;
while (from[i] != '\0') {
char c = from[i];
to[i + *to_length] = c;
i++;
}
(*to_length) += i;
}
void draw(vec4_t *pixel_buffer, const point_list_t *points, char *screen_char_buffer) {
// Reset Depth buffer
for (size_t i = 0; i < WIDTH * HEIGHT; i++) {
pixel_buffer[i].l = 0.0;
};
@ -93,12 +130,12 @@ void draw(vec4_t *pixel_buffer, const point_list_t *points) {
f64 p_y = pos.j;
f64 p_z = pos.k;
i32 s_x = w_x_to_screen(p_x);
i32 s_y = w_y_to_screen(p_y);
size_t s_x = w_x_to_screen(p_x);
size_t s_y = w_y_to_screen(p_y);
f64 s_z = w_z_to_screen(p_z);
if (0 <= s_x && s_x < WIDTH && 0 <= s_y && s_y < HEIGHT) {
size_t index = (size_t)(s_x + s_y * WIDTH);
if (s_x < WIDTH && s_y < HEIGHT) {
size_t index = (s_x + s_y * WIDTH);
vec4_t existing = pixel_buffer[index];
if (existing.l < s_z) {
pixel_buffer[index].i = color.i;
@ -109,33 +146,44 @@ void draw(vec4_t *pixel_buffer, const point_list_t *points) {
};
}
for (size_t y = 0; y < (size_t)(HEIGHT); y++) {
for (size_t x = 0; x < (size_t)(WIDTH); x++) {
size_t index = x + y * (size_t)(WIDTH);
size_t char_buffer_length = 0;
for (size_t y = 0; y < HEIGHT; y++) {
for (size_t x = 0; x < WIDTH; x++) {
size_t index = x + y * WIDTH;
vec4_t pixel = pixel_buffer[index];
f64 depth = pixel.l;
if (depth <= 0.0) {
printf(" ");
screen_char_buffer[char_buffer_length] = ' ';
screen_char_buffer[char_buffer_length + 1] = ' ';
char_buffer_length += 2;
continue;
}
assert(depth >= 0.0);
assert(depth <= 1.0);
char color_buf[64] = "";
u8 red = (u8)(round(pixel.i * depth * 255.0));
u8 green = (u8)(round(pixel.j * depth * 255.0));
u8 blue = (u8)(round(pixel.k * depth * 255.0));
printf("\033[38;2;%u;%u;%um██", red, green, blue);
snprintf(color_buf, 32, "\033[38;2;%hhu;%hhu;%hhum██", red, green, blue);
push_string(screen_char_buffer, color_buf, &char_buffer_length);
}
printf("\n");
screen_char_buffer[char_buffer_length] = '\n';
char_buffer_length++;
}
fwrite(screen_char_buffer, 1, char_buffer_length, stdout);
}
void update(point_list_t *points) {
void update(point_list_t *points, u64 frame_count) {
for (size_t i = 0; i < points->length; i++) {
vec3_t *pos = &points->list[i].pos;
rotate_i(pos, 0.02);
rotate_j(pos, -0.04);
rotate_k(pos, 0.03);
// rotate_i(pos, sin(frame_count / 32.0) / 32.0);
rotate_j(pos, 0.04);
rotate_k(pos, -0.037);
}
}

View file

@ -15,8 +15,10 @@ texture_t load_ppm(FILE *file) {
u32 width, height;
u32 color;
fscanf(file, "%d %d", &width, &height);
fscanf(file, "%d", &color);
int res1 = fscanf(file, "%d %d", &width, &height);
assert(res1 > 0);
int res2 = fscanf(file, "%d", &color);
assert(res2 > 0);
assert(width == 16 && height == 16);
assert(color == 255);
@ -25,7 +27,8 @@ texture_t load_ppm(FILE *file) {
for (size_t i = 0; i < width * height * 3; i++) {
u8 byte;
fscanf(file, "%hhd", &byte);
int res3 = fscanf(file, "%hhd", &byte);
assert(res3 > 0);
tex.bytes[i] = byte;
}