working to have chunk-based display

This commit is contained in:
Alexandre 2024-07-01 13:15:40 +02:00
parent d24f925b0a
commit 7c90754be9
4 changed files with 277 additions and 134 deletions

BIN
a.out

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,14 +1,42 @@
open Graphics ;; open Graphics ;;
open Tsdl ;;
Random.self_init () ;; Random.self_init () ;;
let __width__ = 1500
and __height__ = 1000 ;;
(* (*
ocamlfind ocamlc -linkpkg -package unix -linkpkg -package graphics -linkpkg -package tsdl -thread -package threads -linkpkg display.ml ocamlfind ocamlc -linkpkg -package unix -linkpkg -package graphics -thread -package threads -linkpkg display.ml
*) *)
(* ------------------------------------------------------------- *)
(* ------------------------------------------------------------- *)
type 'a dynamic = {mutable tab : 'a array ; mutable len : int ; mutable memlen : int} ;;
let dyn_create i =
{tab = Array.make 10 i ; len = 0 ; memlen = 10} ;;
let dyn_append arr elt =
let fct x =
if x < arr.len then
arr.tab.(x)
else
arr.tab.(0)
in
if arr.len = arr.memlen then begin
let newarr = Array.init (2 * arr.memlen) fct in
arr.memlen <- 2 * arr.memlen;
arr.tab <- newarr
end;
arr.tab.(arr.len) <- elt;
arr.len <- arr.len + 1 ;;
(* ------------------------------------------------------------- *)
(* ------------------------------------------------------------- *)
let matrix_mult m1 m2 = let matrix_mult m1 m2 =
let n = Array.length m1 let n = Array.length m1
and p = Array.length m1.(0) and p = Array.length m1.(0)
@ -155,6 +183,92 @@ let are_faces_behind (cube : pt_3d array) =
res.(5) <- (should_be_drawn_gr cube.(3)) || (should_be_drawn_gr cube.(0)) || (should_be_drawn_gr cube.(4)) || (should_be_drawn_gr cube.(7)); res.(5) <- (should_be_drawn_gr cube.(3)) || (should_be_drawn_gr cube.(0)) || (should_be_drawn_gr cube.(4)) || (should_be_drawn_gr cube.(7));
(res, res.(0) || res.(1) || res.(2) || res.(3) || res.(4) || res.(5)) ;; (res, res.(0) || res.(1) || res.(2) || res.(3) || res.(4) || res.(5)) ;;
let are_faces_behind_rev (cube : pt_3d array) =
let res = Array.make 6 false in
res.(0) <-
((should_be_drawn_gr cube.(0)) || (should_be_drawn_gr cube.(2))) &&
((should_be_drawn_gr cube.(1)) || (should_be_drawn_gr cube.(3))) &&
((should_be_drawn_gr cube.(0)) || (should_be_drawn_gr cube.(1))) &&
((should_be_drawn_gr cube.(1)) || (should_be_drawn_gr cube.(2))) &&
((should_be_drawn_gr cube.(2)) || (should_be_drawn_gr cube.(3))) &&
((should_be_drawn_gr cube.(3)) || (should_be_drawn_gr cube.(0))) ;
res.(1) <-
((should_be_drawn_gr cube.(4)) || (should_be_drawn_gr cube.(6))) &&
((should_be_drawn_gr cube.(5)) || (should_be_drawn_gr cube.(7))) &&
((should_be_drawn_gr cube.(4)) || (should_be_drawn_gr cube.(5))) &&
((should_be_drawn_gr cube.(5)) || (should_be_drawn_gr cube.(6))) &&
((should_be_drawn_gr cube.(6)) || (should_be_drawn_gr cube.(7))) &&
((should_be_drawn_gr cube.(7)) || (should_be_drawn_gr cube.(4))) ;
res.(2) <-
((should_be_drawn_gr cube.(0)) || (should_be_drawn_gr cube.(5))) &&
((should_be_drawn_gr cube.(1)) || (should_be_drawn_gr cube.(4))) &&
((should_be_drawn_gr cube.(0)) || (should_be_drawn_gr cube.(1))) &&
((should_be_drawn_gr cube.(1)) || (should_be_drawn_gr cube.(5))) &&
((should_be_drawn_gr cube.(5)) || (should_be_drawn_gr cube.(4))) &&
((should_be_drawn_gr cube.(4)) || (should_be_drawn_gr cube.(0))) ;
res.(3) <-
((should_be_drawn_gr cube.(1)) || (should_be_drawn_gr cube.(6))) &&
((should_be_drawn_gr cube.(2)) || (should_be_drawn_gr cube.(5))) &&
((should_be_drawn_gr cube.(1)) || (should_be_drawn_gr cube.(2))) &&
((should_be_drawn_gr cube.(2)) || (should_be_drawn_gr cube.(6))) &&
((should_be_drawn_gr cube.(6)) || (should_be_drawn_gr cube.(5))) &&
((should_be_drawn_gr cube.(5)) || (should_be_drawn_gr cube.(1))) ;
res.(4) <-
((should_be_drawn_gr cube.(2)) || (should_be_drawn_gr cube.(7))) &&
((should_be_drawn_gr cube.(3)) || (should_be_drawn_gr cube.(6))) &&
((should_be_drawn_gr cube.(2)) || (should_be_drawn_gr cube.(3))) &&
((should_be_drawn_gr cube.(3)) || (should_be_drawn_gr cube.(7))) &&
((should_be_drawn_gr cube.(7)) || (should_be_drawn_gr cube.(6))) &&
((should_be_drawn_gr cube.(6)) || (should_be_drawn_gr cube.(2))) ;
res.(5) <-
((should_be_drawn_gr cube.(3)) || (should_be_drawn_gr cube.(4))) &&
((should_be_drawn_gr cube.(0)) || (should_be_drawn_gr cube.(7))) &&
((should_be_drawn_gr cube.(3)) || (should_be_drawn_gr cube.(0))) &&
((should_be_drawn_gr cube.(0)) || (should_be_drawn_gr cube.(4))) &&
((should_be_drawn_gr cube.(4)) || (should_be_drawn_gr cube.(7))) &&
((should_be_drawn_gr cube.(7)) || (should_be_drawn_gr cube.(3))) ;
(res, res.(0) || res.(1) || res.(2) || res.(3) || res.(4) || res.(5)) ;;
let are_edges_behind (cube : pt_3d array) =
let res = Array.make 6 [||] in
res.(0) <- [|
(should_be_drawn_gr cube.(0)) && (should_be_drawn_gr cube.(1));
(should_be_drawn_gr cube.(1)) && (should_be_drawn_gr cube.(2));
(should_be_drawn_gr cube.(2)) && (should_be_drawn_gr cube.(3));
(should_be_drawn_gr cube.(3)) && (should_be_drawn_gr cube.(0))
|];
res.(1) <- [|
(should_be_drawn_gr cube.(4)) && (should_be_drawn_gr cube.(5));
(should_be_drawn_gr cube.(5)) && (should_be_drawn_gr cube.(6));
(should_be_drawn_gr cube.(6)) && (should_be_drawn_gr cube.(7));
(should_be_drawn_gr cube.(7)) && (should_be_drawn_gr cube.(4))
|];
res.(2) <- [|
(should_be_drawn_gr cube.(0)) && (should_be_drawn_gr cube.(1));
(should_be_drawn_gr cube.(1)) && (should_be_drawn_gr cube.(5));
(should_be_drawn_gr cube.(5)) && (should_be_drawn_gr cube.(4));
(should_be_drawn_gr cube.(4)) && (should_be_drawn_gr cube.(0))
|];
res.(3) <- [|
(should_be_drawn_gr cube.(1)) && (should_be_drawn_gr cube.(2));
(should_be_drawn_gr cube.(2)) && (should_be_drawn_gr cube.(6));
(should_be_drawn_gr cube.(6)) && (should_be_drawn_gr cube.(5));
(should_be_drawn_gr cube.(5)) && (should_be_drawn_gr cube.(1))
|];
res.(4) <- [|
(should_be_drawn_gr cube.(2)) && (should_be_drawn_gr cube.(3));
(should_be_drawn_gr cube.(3)) && (should_be_drawn_gr cube.(7));
(should_be_drawn_gr cube.(7)) && (should_be_drawn_gr cube.(6));
(should_be_drawn_gr cube.(6)) && (should_be_drawn_gr cube.(2))
|];
res.(5) <- [|
(should_be_drawn_gr cube.(3)) && (should_be_drawn_gr cube.(0));
(should_be_drawn_gr cube.(0)) && (should_be_drawn_gr cube.(4));
(should_be_drawn_gr cube.(4)) && (should_be_drawn_gr cube.(7));
(should_be_drawn_gr cube.(7)) && (should_be_drawn_gr cube.(3))
|];
res ;;
let draw_cube_p (cube : pt_3d array) screen_wd screen_ht fov r g b = let draw_cube_p (cube : pt_3d array) screen_wd screen_ht fov r g b =
let adjusted = adjust_to_camera cube in let adjusted = adjust_to_camera cube in
let (draw_faces, draw_cube) = are_faces_behind adjusted in let (draw_faces, draw_cube) = are_faces_behind adjusted in
@ -222,6 +336,138 @@ let draw_cube_p (cube : pt_3d array) screen_wd screen_ht fov r g b =
done done
end ;; end ;;
let draw_cube_p_rev (cube : pt_3d array) screen_wd screen_ht fov r g b =
let adjusted = adjust_to_camera cube in
let (draw_faces, draw_cube) = are_faces_behind_rev adjusted in
if draw_cube then begin
let proj = project adjusted screen_wd screen_ht fov in
let graphed = to_graphics proj screen_wd screen_ht in
set_color (rgb 192 192 192);
let distances = [|
max (farthest_pt cube.(0) cube.(1)) (farthest_pt cube.(2) cube.(3));
max (farthest_pt cube.(4) cube.(5)) (farthest_pt cube.(6) cube.(7));
max (farthest_pt cube.(0) cube.(1)) (farthest_pt cube.(5) cube.(4));
max (farthest_pt cube.(1) cube.(2)) (farthest_pt cube.(6) cube.(5));
max (farthest_pt cube.(2) cube.(3)) (farthest_pt cube.(7) cube.(6));
max (farthest_pt cube.(3) cube.(0)) (farthest_pt cube.(4) cube.(7));
|] in
let order = [|
[|graphed.(0); graphed.(1); graphed.(2); graphed.(3); graphed.(0)|];
[|graphed.(4); graphed.(5); graphed.(6); graphed.(7); graphed.(4)|];
[|graphed.(0); graphed.(1); graphed.(5); graphed.(4); graphed.(0)|];
[|graphed.(1); graphed.(2); graphed.(6); graphed.(5); graphed.(1)|];
[|graphed.(2); graphed.(3); graphed.(7); graphed.(6); graphed.(2)|];
[|graphed.(3); graphed.(0); graphed.(4); graphed.(7); graphed.(3)|];
|] in
(* Note : edge orders must be as following :
7--------6
/| /|
/ | / |
4--------5 |
| | | |
| 3-----|--2
| / | /
|/ |/
0--------1
*)
for i = 0 to 5 do
let cur_max = ref distances.(i) in
let idmax = ref i in
for j = i to 5 do
if distances.(j) > !cur_max then begin
cur_max := distances.(j);
idmax := j
end
done;
swap distances i !idmax;
swap order i !idmax;
swap draw_faces i !idmax;
done;
set_line_width 5;
for i = 0 to 5 do
if draw_faces.(i) then begin
let light = max (0.) (1. -. (distances.(i)) /. 7.5) in
let face_R = int_of_float ((float_of_int r) *. light)
and face_G = int_of_float ((float_of_int g) *. light)
and face_B = int_of_float ((float_of_int b) *. light) in
set_color (rgb face_R face_G face_B);
fill_poly order.(i);
set_color black;
draw_poly_line order.(i);
end
done
end ;;
let draw_cube_hollow_p (cube : pt_3d array) screen_wd screen_ht fov r g b=
let adjusted = adjust_to_camera cube in
let (draw_faces, draw_cube) = are_faces_behind adjusted in
let draw_edges = are_edges_behind adjusted in
if draw_cube then begin
let proj = project adjusted screen_wd screen_ht fov in
let graphed = to_graphics proj screen_wd screen_ht in
set_color (rgb 192 192 192);
let distances = [|
max (farthest_pt cube.(0) cube.(1)) (farthest_pt cube.(2) cube.(3));
max (farthest_pt cube.(4) cube.(5)) (farthest_pt cube.(6) cube.(7));
max (farthest_pt cube.(0) cube.(1)) (farthest_pt cube.(5) cube.(4));
max (farthest_pt cube.(1) cube.(2)) (farthest_pt cube.(6) cube.(5));
max (farthest_pt cube.(2) cube.(3)) (farthest_pt cube.(7) cube.(6));
max (farthest_pt cube.(3) cube.(0)) (farthest_pt cube.(4) cube.(7));
|] in
let order = [|
[|graphed.(0); graphed.(1); graphed.(2); graphed.(3); graphed.(0)|];
[|graphed.(4); graphed.(5); graphed.(6); graphed.(7); graphed.(4)|];
[|graphed.(0); graphed.(1); graphed.(5); graphed.(4); graphed.(0)|];
[|graphed.(1); graphed.(2); graphed.(6); graphed.(5); graphed.(1)|];
[|graphed.(2); graphed.(3); graphed.(7); graphed.(6); graphed.(2)|];
[|graphed.(3); graphed.(0); graphed.(4); graphed.(7); graphed.(3)|];
|] in
(* Note : edge orders must be as following :
7--------6
/| /|
/ | / |
4--------5 |
| | | |
| 3-----|--2
| / | /
|/ |/
0--------1
*)
for i = 0 to 5 do
let cur_max = ref distances.(i) in
let idmax = ref i in
for j = i to 5 do
if distances.(j) > !cur_max then begin
cur_max := distances.(j);
idmax := j
end
done;
swap distances i !idmax;
swap order i !idmax;
swap draw_faces i !idmax;
swap draw_edges i !idmax
done;
set_line_width 5;
set_color (rgb r g b);
for i = 0 to 5 do
for j = 0 to 3 do
if draw_edges.(i).(j) then begin
draw_poly_line [|order.(i).(j) ; order.(i).((j+1) mod 4)|];
end
done
done
end ;;
let sum_x (poly : pt_3d array) = let sum_x (poly : pt_3d array) =
let res = ref 0. in let res = ref 0. in
for i = 0 to (Array.length poly -1) do for i = 0 to (Array.length poly -1) do
@ -251,46 +497,15 @@ let cube_dist (c : pt_3d array) =
} }
in dist_from_camera mid_pt ;; in dist_from_camera mid_pt ;;
let draw_multiples_cubes (cubes : pt_3d array array) screen_wd screen_ht fov = let draw_multiples_cubes_colored (cubes : pt_3d array dynamic) rs gs bs screen_wd screen_ht fov render_dist =
let n = Array.length cubes in let n = cubes.len in
let new_arr = Array.make n cubes.(0) in
let distances = Array.make n 0. in let distances = Array.make n 0. in
for i = 0 to n-1 do for i = 0 to n-1 do
new_arr.(i) <- cubes.(i); distances.(i) <- cube_dist cubes.tab.(i);
distances.(i) <- cube_dist cubes.(i)
done ; done ;
for i = 0 to n-1 do
let cur_max = ref distances.(i) in
let idmax = ref i in
for j = i to n-1 do
if distances.(j) > !cur_max then begin
cur_max := distances.(j);
idmax := j
end
done;
swap distances i !idmax;
swap new_arr i !idmax;
done;
for i = 0 to n-1 do
draw_cube_p new_arr.(i) screen_wd screen_ht fov 192 192 192
done ;;
let draw_multiples_cubes_colored (cubes : pt_3d array array) maxlen rs gs bs screen_wd screen_ht fov render_dist =
let n = maxlen in
let new_arr = Array.make n cubes.(0)
and distances = Array.make n 0.
and reds = Array.make n 0
and greens = Array.make n 0
and blues = Array.make n 0 in
for i = 0 to n-1 do
new_arr.(i) <- cubes.(i);
distances.(i) <- cube_dist cubes.(i);
reds.(i) <- rs.(i);
greens.(i) <- gs.(i);
blues.(i) <- bs.(i)
done ;
for i = 0 to n-1 do for i = 0 to n-1 do
let cur_max = ref distances.(i) in let cur_max = ref distances.(i) in
let idmax = ref i in let idmax = ref i in
@ -301,16 +516,12 @@ let draw_multiples_cubes_colored (cubes : pt_3d array array) maxlen rs gs bs scr
end end
done; done;
swap distances i !idmax; swap distances i !idmax;
swap new_arr i !idmax; swap cubes.tab i !idmax;
swap reds i !idmax;
swap greens i !idmax;
swap blues i !idmax;
done; done;
for i = 0 to n-1 do for i = 0 to n-1 do
(*Printf.printf "drawing cube (%f, %f, %f) with distance %f" new_arr.(i).(0).x new_arr.(i).(0).y new_arr.(i).(0).z distances.(i); if distances.(i) <= (float_of_int render_dist) then begin
Stdlib.print_endline "...";*) draw_cube_p cubes.tab.(i) screen_wd screen_ht fov rs.tab.(i) gs.tab.(i) bs.tab.(i)
if distances.(i) <= (float_of_int render_dist) then end
draw_cube_p new_arr.(i) screen_wd screen_ht fov reds.(i) greens.(i) blues.(i)
done ;; done ;;
let create_cube x0' y0' z0' sz' = let create_cube x0' y0' z0' sz' =
@ -330,69 +541,8 @@ let create_cube x0' y0' z0' sz' =
|] |]
in res ;; in res ;;
let cube = [|
{x = -1.; y = 1.; z = 1.};
{x = -2.; y = 1.; z = 1.};
{x = -2.; y = 2.; z = 1.};
{x = -1.; y = 2.; z = 1.};
{x = -1.; y = 1.; z = 2.};
{x = -2.; y = 1.; z = 2.};
{x = -2.; y = 2.; z = 2.};
{x = -1.; y = 2.; z = 2.}
|] ;;
let cube2 = [|
{x = 1.; y = 1.; z = 1.};
{x = 2.; y = 1.; z = 1.};
{x = 2.; y = 2.; z = 1.};
{x = 1.; y = 2.; z = 1.};
{x = 1.; y = 1.; z = 2.};
{x = 2.; y = 1.; z = 2.};
{x = 2.; y = 2.; z = 2.};
{x = 1.; y = 2.; z = 2.}
|] ;;
let cube3 = [|
{x = 1.; y = 1.; z = 2.};
{x = 2.; y = 1.; z = 2.};
{x = 2.; y = 2.; z = 2.};
{x = 1.; y = 2.; z = 2.};
{x = 1.; y = 1.; z = 3.};
{x = 2.; y = 1.; z = 3.};
{x = 2.; y = 2.; z = 3.};
{x = 1.; y = 2.; z = 3.}
|] ;;
let cube4 = [|
{x = 1.; y = 0.; z = 2.};
{x = 2.; y = 0.; z = 2.};
{x = 2.; y = -1.; z = 2.};
{x = 1.; y = -1. ; z = 2.};
{x = 1.; y = 0.; z = 3.};
{x = 2.; y = 0.; z = 3.};
{x = 2.; y = -1.; z = 3.};
{x = 1.; y = -1.; z = 3.}
|] ;;
let fov = 90 ;; let fov = 90 ;;
let hehe () =
open_graph " 1500x1000" ;
set_window_title "3D" ;
camera_xyz.z <- 0.8;
for i = 0 to 488 do
open_graph " 1500x1000" ;
draw_multiples_cubes [|cube ; cube4 ; cube2 ; cube3|] 1500 1000 fov ;
camera_xyz.z <- camera_xyz.z -. 0.1;
Stdlib.print_endline "-";
Stdlib.print_endline "-";
Unix.sleepf 0.15
done;
Unix.sleepf 1.0;
close_graph () ;;
(* (*
7--------6 7--------6
/| /| /| /|
@ -470,40 +620,46 @@ let is_collision_cube (cam_coords : pt_3d) (cube : pt_3d array) =
let is_collision (cam_coords : pt_3d) (cubes : pt_3d array array) = let is_collision (cam_coords : pt_3d) (cubes : pt_3d array array) =
let res = ref false in let res = ref false in
let n = !n_walls in let n = !n_walls in
let distances = Array.make n 0. in
for i = 0 to n-1 do for i = 0 to n-1 do
if not !res then distances.(i) <- cube_dist cubes.(i);
done ;
for i = 0 to n-1 do
if not !res && distances.(i) < 2. then
res := is_collision_cube cam_coords cubes.(i) res := is_collision_cube cam_coords cubes.(i)
done; done;
!res ;; !res ;;
let convert_laby laby = let convert_laby laby =
let width = Array.length laby let width = Array.length laby
and height = Array.length laby.(0) and height = Array.length laby.(0)
and depth = Array.length laby.(0).(0) in and depth = Array.length laby.(0).(0) in
let cubes = Array.make (width*height*depth) [||] let cubes = dyn_create (create_cube 0 0 0 0)
and reds = Array.make (width*height*depth) 0 and reds = dyn_create 0
and greens = Array.make (width*height*depth) 0 and greens = dyn_create 0
and blues = Array.make (width*height*depth) 0 in and blues = dyn_create 0 in
let index = ref 0 in
for w = 0 to width-1 do for w = 0 to width-1 do
for h = 0 to height-1 do for h = 0 to height-1 do
for d = 0 to depth-1 do for d = 0 to depth-1 do
if laby.(w).(h).(d) <> Free then begin if laby.(w).(h).(d) <> Free then begin
(*Printf.printf "added (%d, %d, %d)" w h d; (*Printf.printf "added (%d, %d, %d)" w h d;
Stdlib.print_endline " ";*) Stdlib.print_endline " ";*)
cubes.(!index) <- create_cube w h d 1; dyn_append cubes (create_cube w h d 1);
reds.(!index) <- 212; dyn_append reds 212;
greens.(!index) <- 212; dyn_append greens 212;
blues.(!index) <- 212; dyn_append blues 212;
incr index
end end
done done
done done
done; done;
(cubes, reds, greens, blues) ;; (cubes, reds, greens, blues) ;;
let cheesify laby = let cheesify (laby : tile array array array) =
let width = Array.length laby let width = Array.length laby
and height = Array.length laby.(0) and height = Array.length laby.(0)
and depth = Array.length laby.(0).(0) in and depth = Array.length laby.(0).(0) in
@ -577,7 +733,7 @@ let play laby =
fill_poly [|(0, 0); (1500, 0); (1500, 1000); (0, 1000); (0, 0)|]; fill_poly [|(0, 0); (1500, 0); (1500, 1000); (0, 1000); (0, 0)|];
set_color white; set_color white;
draw_multiples_cubes_colored cs !n_walls rs gs bs 1500 1000 fov render_distance ; draw_multiples_cubes_colored cs rs gs bs __width__ __height__ fov render_distance ;
auto_synchronize true; auto_synchronize true;
@ -585,20 +741,7 @@ let play laby =
Stdlib.print_endline " "; Stdlib.print_endline " ";
let usr_input = get1char () in let usr_input = get1char () in
move_cam cs true usr_input move_cam cs.tab true usr_input
done ;;
let test1 laby =
cheesify laby ;
let (cs, rs, gs, bs) = convert_laby laby in
camera_xyz.z <- -. (1.5) ;
camera_xyz.x <- -. (float_of_int width) /. 2. ;
camera_xyz.y <- -. (float_of_int height) /. 2. ;
while true do
open_graph " 1500x1000";
draw_multiples_cubes_colored cs !n_walls rs gs bs 1500 1000 fov render_distance ;
camera_xyz.z <- camera_xyz.z +. 1.;
Unix.sleepf 1.25
done ;; done ;;
play laby ;; play laby ;;