Wasm works great for now!

This commit is contained in:
Your Name 2026-02-06 10:49:44 +01:00
parent 36ee91abb1
commit 2d05d5c96a
20 changed files with 11729423 additions and 62 deletions

View File

@ -32,7 +32,15 @@ NAME := $(NAME).html
CC := emcc
AR := emar
CFLAGS += -v
LDFLAGS += -s USE_GLFW=3 -s ASYNCIFY --shell-file raylib/src/shell.html -DPLATFORM_WEB -s INITIAL_MEMORY=2147483648
LDFLAGS += -s USE_GLFW=3 \
-s ASYNCIFY \
-s ASSERTIONS=1 \
-s SAFE_HEAP=1 \
--preload-file scenes \
--preload-file assets \
--shell-file raylib/src/shell.html \
-DPLATFORM_WEB \
-s INITIAL_MEMORY=2147483648
endif
VNC_SCRIPT := ./script/run_vnc.sh

View File

@ -11,6 +11,7 @@
/* ************************************************************************** */
#include "./ft_printf.h"
#include <stdio.h>
int ft_fprintf(int fd, const char *format, ...)
{
@ -34,5 +35,9 @@ int ft_fprintf(int fd, const char *format, ...)
format++;
}
va_end(args);
if (fd == 1)
fflush(stdout);
else if (fd == 2)
fflush(stderr);
return (count);
}

View File

@ -11,6 +11,7 @@
/* ************************************************************************** */
#include "ft_printf.h"
#include <stdio.h>
int handle_arg(va_list args, char format, int *count, int fd)
{
@ -59,5 +60,6 @@ int ft_printf(const char *format, ...)
format++;
}
va_end(args);
fflush(stdout);
return (count);
}

BIN
miniRT

Binary file not shown.

11729201
miniRT.data Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -13,6 +13,10 @@
#ifndef MINIRT_H
# define MINIRT_H
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include <stdint.h>
#include <sys/types.h>
# include <unistd.h>
@ -23,10 +27,18 @@
# include "libft/libft.h"
# include "memory/memory.h"
# include <stdbool.h>
# ifndef __EMSCRIPTEN__
# include <pthread.h>
# endif // !__EMSCRIPTEN__
# include <dirent.h>
# include "./raylib/src/raylib.h"
# include <string.h>
# include <time.h>
# ifdef __EMSCRIPTEN__
# define SCENE_START_RESOLUTION_X 16
# define SCENE_START_RESOLUTION_Y 9
# endif // __EMSCRIPTEN__
# ifndef WI
# define WI 1920
@ -41,6 +53,15 @@
# define ASPECT_RATIO 1.77777778
# ifndef __EMSCRIPTEN__
# define SCENE_MAX_RESOLUTION_X 1
# define SCENE_MAX_RESOLUTION_Y 1
# else
# define SCENE_MAX_RESOLUTION_X 16
# define SCENE_MAX_RESOLUTION_Y 9
# endif
# ifndef __EMSCRIPTEN__
# ifdef VALGRIND
# define SCENE_START_RESOLUTION_X 16
# define SCENE_START_RESOLUTION_Y 9
@ -48,16 +69,31 @@
# define SCENE_START_RESOLUTION_X 1
# define SCENE_START_RESOLUTION_Y 1
# endif
# endif // !__EMSCRIPTEN
//
#ifndef __EMSCRIPTEN__
# define RESOLUTION_SCALE_X 16
# define RESOLUTION_SCALE_Y 9
# define SCENE_START_RESOLUTION_CAP 4
#else
# define RESOLUTION_SCALE_X SCENE_MAX_RESOLUTION_X * 2
# define RESOLUTION_SCALE_Y SCENE_MAX_RESOLUTION_Y * 2
#endif // !__EMSCRIPTEN__
# define SCENE_START_RESOLUTION_CAP 4
# define CHECKER_GRID_SIZE 16
#ifndef __EMSCRIPTEN__
# define THREAD_COUNT 30
# define THREAD_HEIGHT HI / THREAD_COUNT
#else
# define THREAD_COUNT 1
# define THREAD_HEIGHT HI / THREAD_COUNT
#endif // !__EMSCRIPTEN__
# define MAX_DEPTH 6
# define DROPOFF_DISTANCE 6
# define MAX_LIGHTS 4
@ -438,13 +474,15 @@ typedef struct s_scene
t_body *body_focus;
t_pixel *pixel;
t_body *body;
pthread_mutex_t mutex;
bool reload;
t_texture *texture;
t_texture sky;
uint texture_count;
t_bump_map *bump_map;
uint bump_map_count;
#ifndef __EMSCRIPTEN__
pthread_mutex_t mutex;
#endif
} t_scene;
typedef struct s_data
@ -458,13 +496,16 @@ typedef struct s_data
t_container explorer;
void *param;
void (*func_ptr)(void *, void *);
#ifndef __EMSCRIPTEN__
struct s_thread *threads;
int thread_count;
pthread_barrier_t barrier;
pthread_rwlock_t rwlock;
bool go;
#endif
} t_data;
#ifndef __EMSCRIPTEN__
typedef struct s_thread
{
int id;
@ -478,6 +519,7 @@ typedef struct s_thread
uint startx;
uint starty;
} t_thread;
#endif // !__EMSCRIPTEN__
/* ft_atod.c */
void item_double_inc(void *value, void *null);
@ -636,8 +678,6 @@ t_vector reflect_vector(t_vector incoming, t_vector axis);
void calc_hit_point_vectors(t_hit_point *hit, t_vector ray, t_vector n);
/* Camera */
void define_camera_rays(t_pixel *pixel, t_camera *camera, \
t_scene *scene);
void set_world_matrix(t_camera *camera);
/*camera->right in this function is used as cam normal projection onto the
xz plane to save one less t_vector type */
@ -791,6 +831,7 @@ void ppm_pixels_read(t_buffer *buffer, int fd, t_texture *texture);
int ppm_read_number(int fd, bool *eof);
void ppm_image_read(const char *path, t_texture *texture);
#ifndef __EMSCRIPTEN__
/* Threads */
void data_init_threads(t_data *data);
void threads_init(t_thread thread[], t_data *data);
@ -799,6 +840,11 @@ void thread_define_camera_rays( t_thread *thread, \
t_pixel *pixel, \
t_scene *scene, \
t_camera *camera);
#else
void define_camera_rays(t_pixel *pixel, t_camera *camera, t_scene *scene);
#endif // !__EMSCRIPTEN__
/* Read buffer */
void buffer_move_next_whitespace(t_buffer *buffer);

View File

@ -44,6 +44,7 @@ void mouse_click_right(int x, int y, t_data *data, t_mouse *mouse)
id_group = id_group_get(data->pixel[y * WI + x].id);
data->scene.body_focus = NULL;
mouse->right_is_pressed = true;
if (id_group >= ID_GROUP_SPHERE && id_group <= ID_GROUP_CONE)
{
body = body_get_by_id(data->pixel[y * WI + x].id, &data->scene);
@ -82,6 +83,8 @@ int mouse_press(int x, int y, t_data *data)
{
uint id_group;
if (x < 0 || x >= WI || y < 0 || y >= HI)
return (0);
id_group = id_group_get(data->scene.pixel[y * WI + x].id);
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
mouse_click_left(x, y, &data->scene, &data->mouse);
@ -112,7 +115,7 @@ int mouse_release(int x, int y, t_data *data)
if (!IsMouseButtonDown(MOUSE_BUTTON_LEFT))
{
data->mouse.left_is_pressed = false;
data->scene.resolution_x = 1, data->scene.resolution_y = 1;
data->scene.resolution_x = SCENE_MAX_RESOLUTION_X, data->scene.resolution_y = SCENE_MAX_RESOLUTION_Y;
if (data->mouse.grabbed)
{
(void)x;

View File

@ -11,6 +11,7 @@
/* ************************************************************************** */
#include "../minirt.h"
#include <stdio.h>
t_data data;
@ -24,12 +25,15 @@ void data_destroy_func(void *data_ptr)
t_data *data;
data = data_ptr;
#ifndef __EMSCRIPTEN__
data->go = false;
pthread_rwlock_unlock(&data->rwlock);
while (data->thread_count--)
pthread_join(data->threads[data->thread_count].thread, NULL);
pthread_barrier_destroy(&data->barrier);
pthread_rwlock_destroy(&data->rwlock);
#endif /* ifndef __EMSCRIPTEN__ */
UnloadTexture(data->texture);
CloseWindow();
}
@ -101,6 +105,7 @@ char* validate_file_extension(int argc, char **argv)
if (argc == 2 && ft_strlen(argv[1]) > 3 && ft_memcmp(&argv[1][ft_strlen(argv[1]) - 3], ".rt\0", 4) == 0)
return argv[1];
ft_fprintf(STDERR_FILENO, "Invalid Argument to Program!\nExiting...\n");
fflush(stderr);
exit(EXIT_FAILURE);
}
@ -224,28 +229,68 @@ void main_loop() {
}
}
rendering_loop(&data);
data.scene.resolution_x = 1;
data.scene.resolution_y = 1;
if (keys[0]) {
data.scene.resolution_x = SCENE_MAX_RESOLUTION_X;
data.scene.resolution_y = SCENE_MAX_RESOLUTION_Y;
}
}
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
int main(int argc, char **argv)
{
char *path;
#ifndef __EMSCRIPTEN__
t_thread thread[THREAD_COUNT];
#endif /* ifndef __EMSCRIPTEN__ */
#ifdef __EMSCRIPTEN__
EM_ASM(
console.log(FS.readdir('/'));
console.log(FS.readdir('/scenes'));
console.log("Starting Program");
);
#endif
if (argc == 1)
path = "scenes/multilight.rt";
else
path = validate_file_extension(argc, argv);
#ifdef __EMSCRIPTEN__
EM_ASM(
console.log("Before Init Data");
);
#endif
initialize_data(&data, path);
#ifdef __EMSCRIPTEN__
EM_ASM(
console.log("After Init Data");
);
#endif
lst_memory(&data, data_destroy_func, ADD);
#ifdef __EMSCRIPTEN__
EM_ASM(
console.log("Initialized Data");
);
#endif
#ifndef __EMSCRIPTEN__
threads_init(thread, &data);
#endif
rendering_loop(&data);
#ifndef __EMSCRIPTEN__
data.threads = thread;
#endif
#ifdef __EMSCRIPTEN__
EM_ASM(
console.log("Starting main loop");
);
#endif
#ifdef __EMSCRIPTEN__
emscripten_set_main_loop(main_loop, 0, 1);

View File

@ -92,5 +92,8 @@ uint color_brightness(uint original, float brightness)
float color_distance(uint r1, uint g1, uint b1, uint r2, uint g2, uint b2)
{
return sqrt(pow(r2 - r1, 2) + pow(g2 - g1, 2) + pow(b2 - b1, 2));
int dr = (int)r2 - (int)r1;
int dg = (int)g2 - (int)g1;
int db = (int)b2 - (int)b1;
return sqrt(dr * dr + dg * dg + db * db);
}

View File

@ -15,7 +15,8 @@
float dropoff_factor(float distance)
{
return (1 / pow((distance + DROPOFF_DISTANCE) / DROPOFF_DISTANCE, 2));
float d = (distance + DROPOFF_DISTANCE) / DROPOFF_DISTANCE;
return (1 / (d * d));
}
void trace_lights(t_scene *sc, t_pixel *px, t_hit_point hit)

View File

@ -88,10 +88,14 @@ void ray_check_bodys(t_pixel *pixel, t_vector ray, t_scene *scene)
uint rendering_loop(t_data *data)
{
#ifndef __EMSCRIPTEN__
pthread_rwlock_unlock(&data->rwlock);
pthread_barrier_wait(&data->barrier);
pthread_rwlock_wrlock(&data->rwlock);
pthread_barrier_wait(&data->barrier);
#else
define_camera_rays(data->pixel, &data->scene.camera, &data->scene);
#endif /* ifndef __EMSCRITPEN */
if (data->func_ptr)
data->func_ptr(data, data->param);

View File

@ -10,6 +10,8 @@
/* */
/* ************************************************************************** */
#ifndef __EMSCRIPTEN__
# include "../../minirt.h"
void data_init_threads(t_data *data)
@ -72,3 +74,4 @@ void *thread_rendering_loop(void *thread_ptr)
pthread_rwlock_unlock(thread->rwlock);
return (NULL);
}
#endif

View File

@ -90,19 +90,24 @@ void anti_aliasing_loop(t_scene *scene, uint x, uint y, t_pixel *pixel)
average_color(&pixel[y * WI + x], color, scene->anti_aliasing);
}
#ifndef __EMSCRIPTEN__
void thread_define_camera_rays(t_thread *thread, t_pixel *pixel, \
t_scene *scene, t_camera *camera)
{
uint x;
uint y;
uint max_y;
y = thread->starty;
set_world_matrix(camera);
while (y < thread->starty + THREAD_HEIGHT)
max_y = thread->starty + THREAD_HEIGHT;
if (max_y > HI)
max_y = HI;
while (y + scene->resolution_y <= max_y)
{
x = 0;
while (x < WI)
while (x + scene->resolution_x <= WI)
{
anti_aliasing_loop(scene, x, y, pixel);
x += scene->resolution_x;
@ -110,3 +115,26 @@ void thread_define_camera_rays(t_thread *thread, t_pixel *pixel, \
y += scene->resolution_y;
}
}
#else
void define_camera_rays(t_pixel *pixel, t_camera *camera, t_scene *scene)
{
uint x;
uint y;
y = 0;
set_world_matrix(camera);
while (y + scene->resolution_y <= HI)
{
x = 0;
while (x + scene->resolution_x <= WI)
{
anti_aliasing_loop(scene, x, y, pixel);
x += scene->resolution_x;
}
y += scene->resolution_y;
}
}
#endif /* ifndef __EMSCRIPTEN__ */

View File

@ -15,12 +15,12 @@
void cone_equation_coefficients(t_cone *cn, t_vector ray, \
t_vector cam_delta)
{
cn->coeffs.x = dot_product(ray, ray) - cn->tan_a2p1 * \
pow(dot_product(ray, cn->normal), 2);
double dot = dot_product(ray, cn->normal);
cn->coeffs.x = dot_product(ray, ray) - cn->tan_a2p1 * dot * dot;
cn->coeffs.y = 2 * (dot_product(cam_delta, ray) - cn->tan_a2p1 * \
dot_product(cam_delta, cn->normal) * dot_product(ray, cn->normal));
cn->coeffs.z = dot_product(cam_delta, cam_delta) - cn->tan_a2p1 * \
pow(dot_product(cam_delta, cn->normal), 2);
dot = dot_product(cam_delta, cn->normal);
cn->coeffs.z = dot_product(cam_delta, cam_delta) - cn->tan_a2p1 * dot * dot;
}
void solve_cone_equation(t_cone *cn, t_vector ray, t_vector cam_delta)
@ -31,7 +31,7 @@ void solve_cone_equation(t_cone *cn, t_vector ray, t_vector cam_delta)
cone_equation_coefficients(cn, ray, cam_delta);
cn->t[0] = -1;
cn->t[1] = -1;
discriminant = pow(cn->coeffs.y, 2) - 4 * cn->coeffs.x * cn->coeffs.z;
discriminant = cn->coeffs.y* cn->coeffs.y - 4 * cn->coeffs.x * cn->coeffs.z;
if (discriminant < 0)
return ;
discriminant = sqrt(discriminant);

View File

@ -30,7 +30,7 @@ void cyl_equation_coefficients(t_cylinder *cy, \
cy->coeffs.y = 2 * (dot_product(cam_delta, ray) - \
dot_product(cam_delta, cy->normal) * dot_product(ray, cy->normal));
cy->coeffs.z = ray_distance_from_point_squared(cy->normal, cam_delta) - \
pow(cy->radius, 2);
cy->radius * cy->radius;
}
double solve_cyl_equation(t_cylinder *cy, t_vector ray, \
@ -42,7 +42,7 @@ double solve_cyl_equation(t_cylinder *cy, t_vector ray, \
double t2;
cyl_equation_coefficients(cy, ray, cam_delta);
discriminant = pow(cy->coeffs.y, 2) - 4 * cy->coeffs.x * cy->coeffs.z;
discriminant = cy->coeffs.y * cy->coeffs.y - 4 * cy->coeffs.x * cy->coeffs.z;
if (discriminant < 0)
return (-1);
discriminant = sqrt(discriminant);

View File

@ -30,7 +30,7 @@ double disk_hit_distance(t_disk disk, t_vector ray, t_vector cam, int *invert
{
p = add_vector(cam, scale_vector(ray, dist));
delta = vector_subtract(p, disk.point);
if (dot_product(delta, delta) <= pow(disk.radius, 2))
if (dot_product(delta, delta) <= disk.radius * disk.radius)
return (dist);
}
return (-1);

View File

@ -118,6 +118,12 @@ void scene_create_loop(t_scene *scene, t_line line, int fd)
}
if (scene->camera_was_parsed == false || scene->ambient_was_parsed == false)
{
#ifdef __EMSCRIPTEN__
EM_ASM(
console.log("[MiniRT] Missing Ambient light or Camera!\n");
);
#endif /* ifndef __EMSCRIPTEN__ */
ft_fprintf(STDERR_FILENO, "[MiniRT] Missing Ambient " \
"light or Camera!\n");
lst_memory(NULL, NULL, FAIL);
@ -129,6 +135,12 @@ void scene_create(const char *filepath, t_scene *scene)
int fd;
t_line line;
#ifdef __EMSCRIPTEN__
EM_ASM(
console.log("Starting scene_create");
);
#endif /* ifndef __EMSCRIPTEN__ */
ft_bzero(scene, sizeof(*scene));
ft_bzero(&line, sizeof(line));
scene->texture = ft_calloc(MAPS_MAX, sizeof(t_texture));

View File

@ -74,7 +74,7 @@ double sphere_hit_distance(t_vector ray, t_vector dlt_centr, \
projection = dot_product(dlt_centr, ray);
if (ray_dist == sphere.radius)
return (smaller_non_negative(-1, projection));
in_section = sqrt(pow(sphere.radius, 2) - pow(ray_dist, 2));
in_section = sqrt(sphere.radius * sphere.radius - ray_dist * ray_dist);
t1 = projection + in_section;
t0 = projection - in_section;
t0 -= SHADOW_BIAS;