Fixing aspect ratio

This commit is contained in:
Your Name 2026-02-08 22:30:21 +01:00
parent 48a0606734
commit 056c7d1f5f
24 changed files with 154 additions and 112 deletions

View File

@ -32,6 +32,8 @@ WEB_OUTPUT_JS := $(WEB_OUTPUT).js
WEB_OUTPUT_WASM := $(WEB_OUTPUT).wasm
WEB_OUTPUT_DATA := $(WEB_OUTPUT).data
OBJDIR_BASE := obj
ifeq ($(PLATFORM), PLATFORM_WEB)
LIBRAYLIB := libraylib.web.a
NAME := $(NAME).html
@ -47,8 +49,13 @@ LDFLAGS += -s USE_GLFW=3 \
--shell-file raylib/src/shell.html \
-DPLATFORM_WEB \
-s INITIAL_MEMORY=2147483648
OBJDIR := $(OBJDIR_BASE)/web
else
CFLAGS += -DROOT_DIRECTORY=\"$(PWD)\"
OBJDIR := $(OBJDIR_BASE)/native
endif
VNC_SCRIPT := ./script/run_vnc.sh
@ -82,8 +89,6 @@ SRCUTIL := $(addprefix $(UTILDIR)/, $(addsuffix .c,\
LIBS := libft/libft.a memory/memory.a raylib/src/$(LIBRAYLIB)
MAP := mapgen
OBJDIR := obj
OBJ := $(SRC:%.c=$(OBJDIR)/%.o)
OBJRENDER := $(SRCRENDER:%.c=$(OBJDIR)/%.o)
OBJSCENE := $(SRCSCENE:%.c=$(OBJDIR)/%.o)
@ -134,7 +139,7 @@ vnc: all
$(VNC_SCRIPT)
clean:
rm -rf $(OBJDIR)
rm -rf $(OBJDIR_BASE)
make clean -C libft
make clean -C memory
make clean -C libft/printf

BIN
miniRT Executable file

Binary file not shown.

View File

@ -40,14 +40,6 @@
# define SCENE_START_RESOLUTION_Y 9
# endif // __EMSCRIPTEN__
# ifndef WI
# define WI 1920
# endif
# ifndef HI
# define HI 1080
# endif
# define MAX_BODY_INIT 16
# define READ_BUFFER_SIZE 1000
@ -57,14 +49,6 @@
# define ROOT_DIRECTORY "/"
# endif
# 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
@ -76,11 +60,11 @@
# endif // !__EMSCRIPTEN
//
#ifndef __EMSCRIPTEN__
# define RESOLUTION_SCALE_X 16
# define RESOLUTION_SCALE_Y 9
# define RESOLUTION_SCALE_X ratio_x
# define RESOLUTION_SCALE_Y ratio_y
#else
# define RESOLUTION_SCALE_X SCENE_MAX_RESOLUTION_X * 2
# define RESOLUTION_SCALE_Y SCENE_MAX_RESOLUTION_Y * 2
# define RESOLUTION_SCALE_X ratio_x * 2
# define RESOLUTION_SCALE_Y ratio_y * 2
#endif // !__EMSCRIPTEN__
# define SCENE_START_RESOLUTION_CAP 4
@ -89,12 +73,10 @@
#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__
@ -390,7 +372,7 @@ typedef struct s_cone
# endif
# define ASSETS_PATH ROOT_DIRECTORY"/assets"
# define SCENES_PATH ROOT_DIRECTORY"/scenes"
# define SCENES_PATH ASSETS_PATH"/scenes"
typedef struct s_texture
{
@ -463,6 +445,8 @@ typedef struct s_camera
typedef struct s_scene
{
uint w;
uint h;
uint current_body_max;
uint body_cursor;
uint resolution_x;
@ -530,6 +514,12 @@ typedef struct s_thread
} t_thread;
#endif // !__EMSCRIPTEN__
extern t_data data;
extern uint ratio_x;
extern uint ratio_y;
extern uint max_res_x;
extern uint max_res_y;
/* ft_atod.c */
void item_double_inc(void *value, void *null);
void item_double_dec(void *value, void *null);
@ -812,9 +802,9 @@ void item_bool_toggle(void *null, void *value);
/* Mouse */
int mouse_press(int x, int y, t_data *data);
int mouse_release(int x, int y, t_data *data);
int mouse_move(int x, int y, t_data *data);
int mouse_press(uint x, uint y, t_data *data);
int mouse_release(uint x, uint y, t_data *data);
int mouse_move(uint x, uint y, t_data *data);
void mouse_grab(t_mouse *mouse, t_body *body);
/* Parsing */

View File

@ -95,10 +95,10 @@ t_container container_create(const char *title, t_rect *attr, uint format)
container.attr = *attr;
else
{
container.attr.width = WI / 3;
container.attr.width = data.scene.w / 3;
container.attr.x = 0;
container.attr.height = HI - CONTAINER_PADDING * 2;
container.attr.y = HI / 2 - container.attr.height / 2;
container.attr.height = data.scene.h - CONTAINER_PADDING * 2;
container.attr.y = data.scene.h / 2 - container.attr.height / 2;
}
container.format = format;
container.id = id_set(ID_GROUP_MENU_MAIN, container_id_count);

View File

@ -50,20 +50,20 @@ static void glyph_draw( t_pixel *pixel, \
size_t j;
i = 0;
if (x + 1 < WI)
if (x + 1 < data.scene.w)
{
while (i / 2 < GLYPH_ROW)
{
j = 0;
while (j / 2 < GLYPH_COL)
{
if (x + j + 1 < WI && y + i + 1 < HI \
if (x + j + 1 < data.scene.w && y + i + 1 < data.scene.w \
&& glyph[i / 2][j / 2] == '1')
{
*pixel[(y + i) * WI + (x + j)].color = RAYWHITE;
*pixel[(y + i + 1) * WI + (x + j)].color = RAYWHITE;
*pixel[(y + i) * WI + (x + j + 1)].color = RAYWHITE;
*pixel[(y + i + 1) * WI + (x + j + 1)].color = RAYWHITE;
*pixel[(y + i) * data.scene.w + (x + j)].color = RAYWHITE;
*pixel[(y + i + 1) * data.scene.w + (x + j)].color = RAYWHITE;
*pixel[(y + i) * data.scene.w + (x + j + 1)].color = RAYWHITE;
*pixel[(y + i + 1) * data.scene.w + (x + j + 1)].color = RAYWHITE;
}
j += 2;
}

View File

@ -41,11 +41,11 @@ void help_menu_draw(void *data_ptr, void *pixel)
t_rect background;
t_data *data;
uint x = WI / 4;
uint y = HI / 4;
data = data_ptr;
background = (t_rect){x, y, .width = WI / 2, .height = HI / 2, };
uint x = data->scene.w / 4;
uint y = data->scene.h / 4;
background = (t_rect){x, y, .width = data->scene.w / 2, .height = data->scene.h / 2, };
(void)pixel;
rt_draw_rect_blend(background, data->pixel, 0, HELP_MENU_BG);
glyph_print(x + 2, y + 2, \

View File

@ -70,8 +70,8 @@ void mouse_move_body(Vector2 mouse_delta, int id_group, t_mouse *mouse)
void decrease_resolution(t_scene *scene)
{
if (scene->resolution_x == SCENE_MAX_RESOLUTION_X
&& scene->resolution_y == SCENE_MAX_RESOLUTION_Y)
if (scene->resolution_x == max_res_x
&& scene->resolution_y == max_res_y)
{
scene->anti_aliasing = false;
scene->resolution_x = RESOLUTION_SCALE_X;
@ -102,7 +102,7 @@ void mouse_left_move(int x, t_mouse *mouse, t_scene *scene)
}
}
int mouse_move(int x, int y, t_data *data)
int mouse_move(uint x, uint y, t_data *data)
{
if (data->mouse.left_is_pressed)
{

View File

@ -22,16 +22,16 @@ void mouse_click_left(int x, int y, t_scene *scene, t_mouse *mouse)
mouse->left_is_pressed = true;
mouse->data->scene.body_focus = NULL;
mouse->data->should_rerender = true;
id_group = id_group_get(scene->pixel[y * WI + x].id);
id_group = id_group_get(scene->pixel[y * data.scene.w + x].id);
mouse->data->func_ptr = NULL;
if (id_group == ID_GROUP_ITEM && mouse->data->current_menu)
{
container_item_get_by_id(mouse->data->current_menu, \
scene->pixel[y * WI + x].id, x, y);
scene->pixel[y * data.scene.w + x].id, x, y);
}
else if (id_group > 0 && id_group < ID_GROUP_ITEM)
{
body = body_get_by_id(scene->pixel[y * WI + x].id, scene);
body = body_get_by_id(scene->pixel[y * data.scene.w + x].id, scene);
scene->body_focus = NULL;
mouse_grab(mouse, body);
} else {
@ -44,13 +44,13 @@ void mouse_click_right(int x, int y, t_data *data, t_mouse *mouse)
uint id_group;
t_body *body;
id_group = id_group_get(data->pixel[y * WI + x].id);
id_group = id_group_get(data->pixel[y * data->scene.w + x].id);
data->scene.body_focus = NULL;
mouse->right_is_pressed = true;
data->should_rerender = 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);
body = body_get_by_id(data->pixel[y * data->scene.w + x].id, &data->scene);
data->scene.body_focus = body;
if (id_group == ID_GROUP_PLANE)
plane_menu_map(&data->menu[ID_GROUP_PLANE], body, &body->color);
@ -81,13 +81,13 @@ void menu_scroll_items(t_container *param, uint scaler)
}
}
int mouse_press(int x, int y, t_data *data)
int mouse_press(uint x, uint y, t_data *data)
{
uint id_group;
if (x < 0 || x >= WI || y < 0 || y >= HI)
if (x > INT_MAX || x >= data->scene.w || y > INT_MAX || y >= data->scene.h)
return (0);
id_group = id_group_get(data->scene.pixel[y * WI + x].id);
id_group = id_group_get(data->scene.pixel[y * data->scene.w + x].id);
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && !data->mouse.left_is_pressed)
mouse_click_left(x, y, &data->scene, &data->mouse);
else if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT) && !data->mouse.right_is_pressed)
@ -114,12 +114,12 @@ int mouse_press(int x, int y, t_data *data)
return (0);
}
int mouse_release(int x, int y, t_data *data)
int mouse_release(uint x, uint y, t_data *data)
{
if (data->mouse.left_is_pressed && !IsMouseButtonDown(MOUSE_BUTTON_LEFT))
{
data->mouse.left_is_pressed = false;
data->scene.resolution_x = SCENE_MAX_RESOLUTION_X, data->scene.resolution_y = SCENE_MAX_RESOLUTION_Y;
data->scene.resolution_x = max_res_x, data->scene.resolution_y = max_res_y;
if (data->mouse.grabbed)
{
(void)x;

View File

@ -13,10 +13,22 @@
#include "../minirt.h"
#include <stdio.h>
t_data data;
t_data data = { 0 };
uint ratio_x = 0;
uint ratio_y = 0;
uint max_res_x = 1;
uint max_res_y = 1;
void create_display() {
InitWindow(WI, HI, "miniRT in Raylib!!");
InitWindow(800, 600, "miniRT");
int monitor = GetCurrentMonitor();
int w = GetMonitorWidth(monitor);
int h = GetMonitorHeight(monitor);
SetWindowSize(w, h);
data.scene.w = w;
data.scene.h = h;
SetTargetFPS(60);
}
@ -86,7 +98,6 @@ t_container *menus_create(t_data *data)
void initialize_data(t_data *data, char *path)
{
ft_bzero(data, sizeof(*data));
scene_create(path, &data->scene);
create_display();
data->pixel = pixel_plane_create();
@ -94,7 +105,7 @@ void initialize_data(t_data *data, char *path)
data->mouse.data = data;
data->scene.pixel = data->pixel;
data->menu = menus_create(data);
Image img = GenImageColor(WI, HI, BLACK);
Image img = GenImageColor(data->scene.w, data->scene.h, BLACK);
data->pixel_colors = img.data;
data->texture = LoadTextureFromImage(img);
data->should_rerender = true;
@ -217,7 +228,6 @@ bool key_was_pressed = false;
void main_loop() {
int keys[3] = { 0 };
Vector2 mouse_pos = GetMousePosition();
if (data.mouse.left_is_pressed || data.mouse.right_is_pressed)
{
@ -234,45 +244,69 @@ void main_loop() {
{
key_was_pressed = true;
data.should_rerender = true;
data.scene.resolution_x = RESOLUTION_SCALE_X;
data.scene.resolution_y = RESOLUTION_SCALE_Y;
#ifdef __EMSCRIPTEN__
data.scene.resolution_x = ratio_x * 2;
data.scene.resolution_y = ratio_y * 2;
#else
data.scene.resolution_x = ratio_x;
data.scene.resolution_y = ratio_y;
#endif /* ifdef __EMSCRIPTEN__ */
key_press(keys[i], &data);
}
}
rendering_loop(&data);
if (keys[0] && keys[0] != KEY_EQUAL) {
data.scene.resolution_x = SCENE_MAX_RESOLUTION_X;
data.scene.resolution_y = SCENE_MAX_RESOLUTION_Y;
}
if (key_was_pressed) key_was_pressed = false;
else {
data.scene.resolution_x = max_res_x;
data.scene.resolution_y = max_res_y;
if (key_was_pressed) {
key_was_pressed = false;
} else {
data.should_rerender = false;
data.func_ptr = NULL;
}
}
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
int main(int argc, char **argv)
{
char *path;
#ifndef __EMSCRIPTEN__
t_thread thread[THREAD_COUNT];
#endif /* ifndef __EMSCRIPTEN__ */
if (argc == 1)
if (argc == 1) {
path = SCENES_PATH"/multilight.rt";
}
else
path = validate_file_extension(argc, argv);
initialize_data(&data, path);
lst_memory(&data, data_destroy_func, ADD);
int divisor = gcd(data.scene.w, data.scene.h);
ratio_x = data.scene.w / divisor;
ratio_y = data.scene.h / divisor;
#ifndef __EMSCRIPTEN__
threads_init(thread, &data);
data.threads = thread;
#endif
#ifdef __EMSCRIPTEN__
max_res_y = ratio_y;
max_res_x = ratio_x;
emscripten_set_main_loop(main_loop, 0, 1);
#else
while(!WindowShouldClose()) {

View File

@ -18,13 +18,13 @@ void rt_draw_rect(t_rect rect, t_pixel *pixel, uint id, uint color)
uint y;
y = 0;
while (y < rect.height && rect.y + y < HI)
while (y < rect.height && rect.y + y < data.scene.h)
{
x = 0;
while (x < rect.width && rect.x + x < WI)
while (x < rect.width && rect.x + x < data.scene.w)
{
*pixel[(rect.y + y) * WI + (rect.x + x)].color = uint_to_color(color);
pixel[(rect.y + y) * WI + (rect.x + x)].id = id;
*pixel[(rect.y + y) * data.scene.w + (rect.x + x)].color = uint_to_color(color);
pixel[(rect.y + y) * data.scene.w + (rect.x + x)].id = id;
x++;
}
y++;
@ -37,15 +37,15 @@ void rt_draw_rect_blend(t_rect rect, t_pixel *pixel, uint id, uint color)
uint y;
y = 0;
while (y < rect.height && rect.y + y < HI)
while (y < rect.height && rect.y + y < data.scene.h)
{
x = 0;
while (x < rect.width && rect.x + x < WI)
while (x < rect.width && rect.x + x < data.scene.w)
{
*pixel[(rect.y + y) * WI + (rect.x + x)].color = \
*pixel[(rect.y + y) * data.scene.w + (rect.x + x)].color = \
uint_to_color(color_blend(*(int *)pixel[(rect.y + y) \
* WI + (rect.x + x)].color, color));
pixel[(rect.y + y) * WI + (rect.x + x)].id = id;
* data.scene.w + (rect.x + x)].color, color));
pixel[(rect.y + y) * data.scene.w + (rect.x + x)].id = id;
x++;
}
y++;

View File

@ -18,12 +18,12 @@ void pixels_image_syncronize(Color *image, t_pixel *pixel)
uint y;
y = 0;
while (y < HI)
while (y < data.scene.h)
{
x = 0;
while (x < WI)
while (x < data.scene.w)
{
pixel[y * WI + x].color = &image[y * WI + x];
pixel[y * data.scene.w + x].color = &image[y * data.scene.w + x];
x++;
}
y++;

View File

@ -35,9 +35,9 @@ void pixels_clear(t_pixel *pixel, uint wi, uint hi)
x = 0;
while (x < wi)
{
pixel[y * WI + x].id = 0;
*pixel[y * WI + x].color = uint_to_color(0x0);
pixel[y * WI + x].dist = -1;
pixel[y * data.scene.w + x].id = 0;
*pixel[y * data.scene.w + x].color = uint_to_color(0x0);
pixel[y * data.scene.w + x].dist = -1;
x++;
}
y++;
@ -48,9 +48,9 @@ t_pixel *pixel_plane_create(void)
{
t_pixel *pixels;
pixels = ft_calloc(HI * WI, sizeof(*pixels));
pixels = ft_calloc(data.scene.h * data.scene.w, sizeof(*pixels));
lst_memory(pixels, free, ADD);
set_pixel_distances(pixels, WI * HI, -1);
set_pixel_distances(pixels, data.scene.w * data.scene.h, -1);
return (pixels);
}
@ -67,9 +67,9 @@ void pixel_fill(t_pixel *pixel, t_scene *scene)
j = 0;
while (j < scene->resolution_x)
{
*pixel[i * WI + j].color = *pixel_new.color;
pixel[i * WI + j].id = pixel_new.id;
pixel[i * WI + j].dist = pixel_new.dist;
*pixel[i * data.scene.w + j].color = *pixel_new.color;
pixel[i * data.scene.w + j].id = pixel_new.id;
pixel[i * data.scene.w + j].dist = pixel_new.dist;
j++;
}
i++;

View File

@ -109,6 +109,10 @@ uint rendering_loop(t_data *data)
BeginDrawing();
DrawTexture(data->texture, 0, 0, RAYWHITE);
#ifdef __EMSCRIPTEN__
Vector2 pos = GetMousePosition();
DrawCircleV(pos, (float)data->scene.w / 100, RED);
#endif
EndDrawing();
return (0);
}

View File

@ -40,10 +40,10 @@ void threads_init(t_thread thread[], t_data *data)
i = 0;
while (i < THREAD_COUNT)
{
thread[i].width = WI;
thread[i].width = data->scene.w;
thread[i].data = data;
thread[i].id = i;
thread[i].starty = i * THREAD_HEIGHT;
thread[i].starty = i * data->scene.h / THREAD_COUNT;
thread[i].pixel = data->pixel;
thread[i].scene = &data->scene;
thread[i].rwlock = &data->rwlock;

View File

@ -46,8 +46,8 @@ t_vector set_ray(float x, float y, t_scene *scene, t_camera *camera)
{
t_vector ray;
ray.x = ((2 * x / WI - 1) * camera->fov_f * ASPECT_RATIO);
ray.y = ((1 - 2 * y / HI) * camera->fov_f);
ray.x = ((2 * x / data.scene.w - 1) * camera->fov_f * ASPECT_RATIO);
ray.y = ((1 - 2 * y / data.scene.h) * camera->fov_f);
ray.z = 1;
ray_to_world(&ray, camera);
scene->depth = 0;

View File

@ -57,8 +57,8 @@ bool requires_supersampling(uint x, uint y, t_pixel *pixel, bool aa_on)
if (x == 0 && y == 0) //top left pixel in thread
return true;
color = *(uint *)pixel->color;
color_above = (y != 0) ? *(uint *)pixel[(y - 1) * WI + x].color : color;
color_left = (x != 0) ? *(uint *)pixel[y * WI + (x - 1)].color : color;
color_above = (y != 0) ? *(uint *)pixel[(y - 1) * data.scene.w + x].color : color;
color_left = (x != 0) ? *(uint *)pixel[y * data.scene.w + (x - 1)].color : color;
if (!color_above || !color_left)
return true;
@ -82,12 +82,12 @@ void anti_aliasing_loop(t_scene *scene, uint x, uint y, t_pixel *pixel)
while (i < scene->anti_aliasing + 1)
{
ray = set_ray(aa_x(x, i), aa_y(y, i), scene, &scene->camera);
pixels_clear(&pixel[y * WI + x], scene->resolution_x, \
pixels_clear(&pixel[y * data.scene.w + x], scene->resolution_x, \
scene->resolution_y);
ray_check_bodys(&pixel[y * WI + x], ray, scene);
color[i++] = color_to_uint(*pixel[y * WI + x].color);
ray_check_bodys(&pixel[y * data.scene.w + x], ray, scene);
color[i++] = color_to_uint(*pixel[y * data.scene.w + x].color);
}
average_color(&pixel[y * WI + x], color, scene->anti_aliasing);
average_color(&pixel[y * data.scene.w + x], color, scene->anti_aliasing);
}
#ifndef __EMSCRIPTEN__
@ -98,18 +98,24 @@ void thread_define_camera_rays(t_thread *thread, t_pixel *pixel, \
uint x;
uint y;
uint max_y;
uint thread_height = scene->h / THREAD_COUNT;
uint w = thread->data->scene.w;
uint h = thread->data->scene.h;
y = thread->starty;
set_world_matrix(camera);
max_y = thread->starty + THREAD_HEIGHT;
if (max_y > HI)
max_y = HI;
while (y + scene->resolution_y <= max_y)
max_y = thread->starty + thread_height;
if (max_y > h)
max_y = h;
while (y < max_y)
{
x = 0;
while (x + scene->resolution_x <= WI)
while (x < w)
{
anti_aliasing_loop(scene, x, y, pixel);
uint safe_x = (x + scene->resolution_x > w) ? w - scene->resolution_x : x;
uint safe_y = (y + scene->resolution_y > h) ? h - scene->resolution_y : y;
anti_aliasing_loop(scene, safe_x, safe_y, pixel);
x += scene->resolution_x;
}
y += scene->resolution_y;
@ -120,15 +126,15 @@ void thread_define_camera_rays(t_thread *thread, t_pixel *pixel, \
void define_camera_rays(t_pixel *pixel, t_camera *camera, t_scene *scene)
{
uint x;
uint y;
int x;
int y;
y = 0;
set_world_matrix(camera);
while (y + scene->resolution_y <= HI)
while (y + scene->resolution_y <= scene->h)
{
x = 0;
while (x + scene->resolution_x <= WI)
while (x + scene->resolution_x <= scene->w)
{
anti_aliasing_loop(scene, x, y, pixel);
x += scene->resolution_x;

View File

@ -141,7 +141,10 @@ EM_ASM(
);
#endif /* ifndef __EMSCRIPTEN__ */
ft_bzero(scene, sizeof(*scene));
int monitor = GetCurrentMonitor();
scene->w = GetMonitorWidth(monitor);
scene->h = GetMonitorHeight(monitor);
printf("monitor: %d:%s %u x %u\n", monitor, GetMonitorName(monitor), scene->w, scene->h);
ft_bzero(&line, sizeof(line));
scene->texture = ft_calloc(MAPS_MAX, sizeof(t_texture));
lst_memory(scene->texture, free, ADD);