Added ray casting to significantly improve frame rate
This commit is contained in:
parent
2585ec0556
commit
c70cd64e29
BIN
display.cmi
BIN
display.cmi
Binary file not shown.
BIN
display.cmo
BIN
display.cmo
Binary file not shown.
Binary file not shown.
238
display.ml
238
display.ml
|
@ -5,9 +5,27 @@ Random.self_init () ;;
|
|||
let __width__ = 1500
|
||||
and __height__ = 1000 ;;
|
||||
|
||||
type tile = Free | Wall | Crate | Exit | Craxit | Camera ;;
|
||||
|
||||
let width = 15
|
||||
and height = 15
|
||||
and depth = 15 ;;
|
||||
(* dimensions *)
|
||||
|
||||
let render_distance = 7 ;;
|
||||
let chunk_dist = 2 ;;
|
||||
|
||||
let chunk_size = 4 ;;
|
||||
let chunk_size_f = float_of_int chunk_size ;;
|
||||
|
||||
(* -------------------------------------------------------------------------------------------------------- *)
|
||||
(* -------------------------------------------------------------------------------------------------------- *)
|
||||
(* -------------------------------------------------------------------------------------------------------- *)
|
||||
(* -------------------------------------------------------------------------------------------------------- *)
|
||||
|
||||
(*
|
||||
|
||||
ocamlfind ocamlc -linkpkg -package unix -linkpkg -package graphics -thread -package threads -linkpkg display.ml
|
||||
ocamlfind ocamlopt -linkpkg -package unix -linkpkg -package graphics -thread -package threads -linkpkg display.ml
|
||||
|
||||
*)
|
||||
|
||||
|
@ -111,7 +129,7 @@ let parse_texture filename =
|
|||
tex
|
||||
| exn -> close_in ptr ; raise exn ;;
|
||||
|
||||
let stone = parse_texture "texture404.txt" ;;
|
||||
let stone = parse_texture "output.txt" ;;
|
||||
|
||||
(* ------------------------------------------------------------- *)
|
||||
(* ------------------------------------------------------------- *)
|
||||
|
@ -249,6 +267,14 @@ let adjust_to_camera (shape : pt_3d array) =
|
|||
(*debug_1 res2 ;*)
|
||||
res2 ;;
|
||||
|
||||
let adjust_pt (pt : pt_3d) =
|
||||
let tpt = {x = pt.x +. camera_xyz.x ; y = pt.y +. camera_xyz.y ; z = pt.z -. camera_xyz.z} in
|
||||
{
|
||||
x = tpt.x *. Float.cos ((float_of_int !camera_angle_y) *. 3.14159255358 /. 180.) +. tpt.z *. Float.sin ((float_of_int !camera_angle_y) *. 3.14159255358 /. 180.);
|
||||
y = tpt.y;
|
||||
z = tpt.z *. Float.cos ((float_of_int !camera_angle_y) *. 3.14159255358 /. 180.) -. tpt.x *. Float.sin ((float_of_int !camera_angle_y) *. 3.14159255358 /. 180.)
|
||||
} ;;
|
||||
|
||||
let sq x = x *. x ;;
|
||||
|
||||
let dist_from_camera (p : pt_3d) =
|
||||
|
@ -282,34 +308,150 @@ let convex_pt (p1 : int * int) (p2 : int * int) theta maxtheta =
|
|||
and mid_y = int_of_float ((1. -. ratio) *. (float_of_int (snd p1)) +. ratio *. (float_of_int (snd p2))) in
|
||||
(mid_x, mid_y) ;;
|
||||
|
||||
let convex_3d (p1 : pt_3d) (p2 : pt_3d) theta maxtheta =
|
||||
let ratio = (float_of_int theta) /. (float_of_int maxtheta) in
|
||||
{
|
||||
x = (1. -. ratio) *. p1.x +. ratio *. p2.x;
|
||||
y = (1. -. ratio) *. p1.y +. ratio *. p2.y;
|
||||
z = (1. -. ratio) *. p1.z +. ratio *. p2.z
|
||||
} ;;
|
||||
|
||||
|
||||
|
||||
(*
|
||||
----\\ WARNING : THIS BIT YIELDS A SEGMENTATION FAULT //-----
|
||||
|
||||
exception Out_of_bounds ;;
|
||||
let get_single_pt pt =
|
||||
try
|
||||
Graphics.point_color (fst pt) (snd pt)
|
||||
with
|
||||
| Graphics.Graphic_failure _ -> raise Out_of_bounds ;;
|
||||
|
||||
let is_hidden (rect : (int * int) array) =
|
||||
try
|
||||
let midpt = ((fst rect.(0) + fst rect.(1) + fst rect.(2) + fst rect.(3))/4, (snd rect.(0) + snd rect.(1) + snd rect.(2) + snd rect.(3))/4) in
|
||||
let color_BL = get_single_pt rect.(0)
|
||||
and color_BR = get_single_pt rect.(1)
|
||||
and color_TL = get_single_pt rect.(2)
|
||||
and color_TR = get_single_pt rect.(3)
|
||||
and color_C = get_single_pt midpt in
|
||||
(color_BL = 0) || (color_BR = 0) || (color_TL = 0) || (color_TR = 0) || (color_C = 0)
|
||||
with
|
||||
| Out_of_bounds -> false ;;
|
||||
*)
|
||||
|
||||
let ctc_one x =
|
||||
if x >= 0 then
|
||||
x / chunk_size
|
||||
else
|
||||
x / chunk_size -1 ;;
|
||||
|
||||
let ctcf_one x =
|
||||
if x >= 0. then
|
||||
int_of_float (x /. chunk_size_f)
|
||||
else
|
||||
int_of_float (x /. chunk_size_f) -1 ;;
|
||||
|
||||
let coords_to_chunk x y z =
|
||||
(ctc_one x, ctc_one y, ctc_one z) ;;
|
||||
|
||||
let coords_to_chunk_f x y z =
|
||||
(ctcf_one x, ctcf_one y, ctcf_one z) ;;
|
||||
|
||||
(* -------------------------------------------------------------------------------------- *)
|
||||
|
||||
let is_in_cube (pt : pt_3d) (cube : pt_3d array) =
|
||||
(* cube and pt are relative to the camera *)
|
||||
(*Printf.printf " comparing with cube : (%f, %f, %f)" cube.(0).x cube.(0).y cube.(0).z;
|
||||
Stdlib.print_endline " ";*)
|
||||
(cube.(0).x <= pt.x) &&
|
||||
(cube.(0).y <= pt.y) &&
|
||||
(cube.(0).z <= pt.z) &&
|
||||
(cube.(6).x >= pt.x) &&
|
||||
(cube.(6).y >= pt.y) &&
|
||||
(cube.(6).z >= pt.z) ;;
|
||||
|
||||
let seg_len (p1 : pt_3d) (p2 : pt_3d) =
|
||||
Float.sqrt ((sq (p1.x -. p2.x)) +. (sq (p1.y -. p2.y)) +. (sq (p1.z -. p2.z))) ;;
|
||||
|
||||
exception ReturnBool of bool ;;
|
||||
let is_visible (pt0 : pt_3d) (hash : (int * int * int, coloredCube dynamic) Hashtbl.t) =
|
||||
try
|
||||
let pt = pt0 in
|
||||
(*Printf.printf " current pt : (%f, %f, %f)\n" pt.x pt.y pt.z;
|
||||
Printf.printf " camera pt : (%f, %f, %f)\n" (-. camera_xyz.x) (-. camera_xyz.y) camera_xyz.z;*)
|
||||
|
||||
let segment_length = dist_from_camera pt in
|
||||
let n_iter = int_of_float (segment_length /. 1.7) in
|
||||
|
||||
(*Printf.printf " distance : %f\n" segment_length;
|
||||
Printf.printf " n_iter : %d" n_iter;
|
||||
Stdlib.print_endline " ";*)
|
||||
|
||||
for i = 1 to n_iter -1 do
|
||||
let cur_pt = convex_3d pt {x = -. camera_xyz.x ; y = -. camera_xyz.y ; z = camera_xyz.z} i n_iter in
|
||||
let (ch_x, ch_y, ch_z) = coords_to_chunk_f cur_pt.x cur_pt.y cur_pt.z in
|
||||
|
||||
(*Printf.printf " regarding pt : (%f, %f, %f) in chunk (%d, %d, %d)" cur_pt.x cur_pt.y cur_pt.z ch_x ch_y ch_z;
|
||||
Stdlib.print_endline " ";*)
|
||||
|
||||
let cubes = Hashtbl.find hash (ch_x, ch_y, ch_z) in
|
||||
for c = 0 to cubes.len -1 do
|
||||
if is_in_cube cur_pt cubes.tab.(c).cube then
|
||||
raise (ReturnBool false)
|
||||
done
|
||||
done;
|
||||
(*Stdlib.print_endline " No collision detected";*)
|
||||
true
|
||||
with
|
||||
| Not_found -> (*Stdlib.print_endline " EMPTY"; *)true
|
||||
| ReturnBool b -> (*Printf.printf " Aborted to %b" b ; Stdlib.print_endline " "; *)b ;;
|
||||
|
||||
let is_visible_cube (cube : pt_3d array) (hash : (int * int * int, coloredCube dynamic) Hashtbl.t) =
|
||||
(*Printf.printf "cube (%f, %f, %f)" cube.(0).x cube.(0).y cube.(0).z;
|
||||
Printf.printf "[of length %d]" (Array.length cube);
|
||||
Stdlib.print_endline " ";*)
|
||||
let res = ref false in
|
||||
for i = 0 to Array.length cube -1 do
|
||||
res := !res || (is_visible cube.(i) hash)
|
||||
done;
|
||||
(*Printf.printf "yielding %b" !res;
|
||||
Stdlib.print_endline " "; *)
|
||||
!res ;;
|
||||
|
||||
let draw_texture (rect : (int * int) array) (text : texture) light =
|
||||
(*set_color white;
|
||||
fill_poly rect ;;*)
|
||||
for i = 0 to text.width -1 do
|
||||
for j = 0 to text.height -1 do
|
||||
let face_R = int_of_float ((float_of_int text.arr_red.(i).(j)) *. light)
|
||||
and face_G = int_of_float ((float_of_int text.arr_green.(i).(j)) *. light)
|
||||
and face_B = int_of_float ((float_of_int text.arr_blue.(i).(j)) *. light) in
|
||||
set_color (rgb face_R face_G face_B);
|
||||
if true then begin
|
||||
let face_R = int_of_float ((float_of_int text.arr_red.(i).(j)) *. light)
|
||||
and face_G = int_of_float ((float_of_int text.arr_green.(i).(j)) *. light)
|
||||
and face_B = int_of_float ((float_of_int text.arr_blue.(i).(j)) *. light) in
|
||||
set_color (rgb face_R face_G face_B);
|
||||
|
||||
let pt_a = convex_pt rect.(0) rect.(1) i text.width
|
||||
and pt_b = convex_pt rect.(0) rect.(1) (i+1) text.width
|
||||
let pt_a = convex_pt rect.(0) rect.(1) i text.width
|
||||
and pt_b = convex_pt rect.(0) rect.(1) (i+1) text.width
|
||||
|
||||
and pt_e = convex_pt rect.(3) rect.(2) (i+1) text.width
|
||||
and pt_f = convex_pt rect.(3) rect.(2) i text.width in
|
||||
and pt_e = convex_pt rect.(3) rect.(2) (i+1) text.width
|
||||
and pt_f = convex_pt rect.(3) rect.(2) i text.width in
|
||||
|
||||
let bot_left = convex_pt pt_a pt_f j text.height
|
||||
and bot_right = convex_pt pt_b pt_e j text.height
|
||||
and top_left = convex_pt pt_a pt_f (j+1) text.height
|
||||
and top_right = convex_pt pt_b pt_e (j+1) text.height in
|
||||
fill_poly [|bot_left; bot_right; top_right; top_left|]
|
||||
let bot_left = convex_pt pt_a pt_f j text.height
|
||||
and bot_right = convex_pt pt_b pt_e j text.height
|
||||
and top_left = convex_pt pt_a pt_f (j+1) text.height
|
||||
and top_right = convex_pt pt_b pt_e (j+1) text.height in
|
||||
fill_poly [|bot_left; bot_right; top_right; top_left|]
|
||||
end
|
||||
done
|
||||
done ;;
|
||||
|
||||
let draw_cube_p (cube : pt_3d array) screen_wd screen_ht fov r g b =
|
||||
let draw_cube_p (cube : pt_3d array) (hash : (int * int * int, coloredCube dynamic) Hashtbl.t) 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
|
||||
if draw_cube then begin
|
||||
if draw_cube && (is_visible_cube cube hash) then begin
|
||||
(*Printf.printf "drawing cube (%f, %f, %f)" cube.(0).x cube.(0).y cube.(0).z ;
|
||||
Stdlib.print_endline " ";*)
|
||||
let proj = project adjusted screen_wd screen_ht fov in
|
||||
|
||||
let graphed = to_graphics proj screen_wd screen_ht in
|
||||
|
@ -358,16 +500,16 @@ let draw_cube_p (cube : pt_3d array) screen_wd screen_ht fov r g b =
|
|||
swap order i !idmax;
|
||||
swap draw_faces i !idmax;
|
||||
done;
|
||||
set_line_width 5;
|
||||
set_line_width 2;
|
||||
for i = 0 to 5 do
|
||||
if draw_faces.(i) then begin
|
||||
let light = max (0.) (1. -. (distances.(i)) /. 12.5) in
|
||||
let face_R = int_of_float ((float_of_int r) *. light)
|
||||
(*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);
|
||||
(*draw_texture order.(i) stone light ;*)
|
||||
fill_poly order.(i);*)
|
||||
draw_texture order.(i) stone light ;
|
||||
set_color black;
|
||||
draw_poly_line order.(i);
|
||||
end
|
||||
|
@ -403,7 +545,7 @@ let cube_dist (c : pt_3d array) =
|
|||
}
|
||||
in dist_from_camera mid_pt ;;
|
||||
|
||||
let draw_multiples_cubes_colored (cubes : pt_3d array dynamic) rs gs bs screen_wd screen_ht fov render_dist =
|
||||
let draw_multiples_cubes_colored (cubes : pt_3d array dynamic) rs gs bs hash screen_wd screen_ht fov render_dist =
|
||||
let n = cubes.len in
|
||||
|
||||
let distances = Array.make n 0. in
|
||||
|
@ -426,11 +568,11 @@ let draw_multiples_cubes_colored (cubes : pt_3d array dynamic) rs gs bs screen_w
|
|||
done;
|
||||
for i = 0 to n-1 do
|
||||
if distances.(i) <= (float_of_int render_dist) then begin
|
||||
draw_cube_p cubes.tab.(i) screen_wd screen_ht fov rs.tab.(i) gs.tab.(i) bs.tab.(i)
|
||||
draw_cube_p cubes.tab.(i) hash screen_wd screen_ht fov rs.tab.(i) gs.tab.(i) bs.tab.(i)
|
||||
end
|
||||
done ;;
|
||||
|
||||
let draw_multiples_cubes_colored_hash (dyna : coloredCube dynamic) screen_wd screen_ht fov =
|
||||
let draw_multiples_cubes_colored_hash (dyna : coloredCube dynamic) (hash : (int * int * int, coloredCube dynamic) Hashtbl.t) screen_wd screen_ht fov =
|
||||
let n = dyna.len in
|
||||
|
||||
(*Printf.printf ">> %d <<" n;
|
||||
|
@ -457,7 +599,7 @@ let draw_multiples_cubes_colored_hash (dyna : coloredCube dynamic) screen_wd scr
|
|||
for i = 0 to n-1 do
|
||||
(*Printf.printf "drawing (%f, %f, %f)" (dyna.tab.(i).cube.(0).x) (dyna.tab.(i).cube.(0).y) (dyna.tab.(i).cube.(0).z);
|
||||
Stdlib.print_endline " ";*)
|
||||
draw_cube_p (dyna.tab.(i).cube) screen_wd screen_ht fov (dyna.tab.(i).red) (dyna.tab.(i).green) (dyna.tab.(i).blue)
|
||||
draw_cube_p (dyna.tab.(i).cube) hash screen_wd screen_ht fov (dyna.tab.(i).red) (dyna.tab.(i).green) (dyna.tab.(i).blue)
|
||||
done ;;
|
||||
|
||||
let create_cube x0' y0' z0' sz' =
|
||||
|
@ -519,24 +661,6 @@ let get1char () =
|
|||
(* -------------------------------------------------------------------------------------------------------- *)
|
||||
(* -------------------------------------------------------------------------------------------------------- *)
|
||||
|
||||
type tile = Free | Wall | Crate | Exit | Craxit | Camera ;;
|
||||
|
||||
let width = 15
|
||||
and height = 15
|
||||
and depth = 15 ;;
|
||||
(* dimensions *)
|
||||
|
||||
let render_distance = 7 ;;
|
||||
let chunk_dist = 2 ;;
|
||||
|
||||
let chunk_size = 4 ;;
|
||||
let chunk_size_f = float_of_int chunk_size ;;
|
||||
|
||||
(* -------------------------------------------------------------------------------------------------------- *)
|
||||
(* -------------------------------------------------------------------------------------------------------- *)
|
||||
(* -------------------------------------------------------------------------------------------------------- *)
|
||||
(* -------------------------------------------------------------------------------------------------------- *)
|
||||
|
||||
let laby = Array.make width [|[||]|] ;;
|
||||
for i = 0 to width -1 do
|
||||
laby.(i) <- Array.make_matrix height depth Wall
|
||||
|
@ -544,24 +668,6 @@ done ;;
|
|||
|
||||
let n_walls = ref (width*height*depth) ;;
|
||||
|
||||
let ctc_one x =
|
||||
if x >= 0 then
|
||||
x / chunk_size
|
||||
else
|
||||
x / chunk_size -1 ;;
|
||||
|
||||
let ctcf_one x =
|
||||
if x >= 0. then
|
||||
int_of_float (x /. chunk_size_f)
|
||||
else
|
||||
int_of_float (x /. chunk_size_f) -1 ;;
|
||||
|
||||
let coords_to_chunk x y z =
|
||||
(ctc_one x, ctc_one y, ctc_one z) ;;
|
||||
|
||||
let coords_to_chunk_f x y z =
|
||||
(ctcf_one x, ctcf_one y, ctcf_one z) ;;
|
||||
|
||||
let is_collision_cube (cam_coords : pt_3d) (cube : pt_3d array) =
|
||||
cube.(0).x <= (-. cam_coords.x) &&
|
||||
cube.(0).y <= (-. cam_coords.y) &&
|
||||
|
@ -775,7 +881,7 @@ let cheesify (laby : tile array array array) =
|
|||
done
|
||||
done
|
||||
done;;
|
||||
|
||||
(*
|
||||
(* z q s d for movement, p to go up, m to go down, a to rotate left, e to rotate right *)
|
||||
let rec move_cam (cubes : pt_3d array array) b c =(* Printf.printf "[%b]" b; Stdlib.print_endline " " ; *)match c with
|
||||
| 'z' ->
|
||||
|
@ -821,7 +927,7 @@ let play laby =
|
|||
fill_poly [|(0, 0); (1500, 0); (1500, 1000); (0, 1000); (0, 0)|];
|
||||
set_color white;
|
||||
|
||||
draw_multiples_cubes_colored cs rs gs bs __width__ __height__ fov render_distance ;
|
||||
draw_multiples_cubes_colored cs rs gs bs hash __width__ __height__ fov render_distance ;
|
||||
|
||||
auto_synchronize true;
|
||||
|
||||
|
@ -830,7 +936,7 @@ let play laby =
|
|||
|
||||
let usr_input = get1char () in
|
||||
move_cam cs.tab true usr_input
|
||||
done ;;
|
||||
done ;;*)
|
||||
|
||||
let rec move_cam_hash (cubes : coloredCube dynamic) b c =(* Printf.printf "[%b]" b; Stdlib.print_endline " " ; *)match c with
|
||||
| 'z' ->
|
||||
|
@ -936,7 +1042,7 @@ let rec move_cam_hash_2 hash cx cy cz b c =(* Printf.printf "[%b]" b; Stdlib.pri
|
|||
|
||||
let manage_unexisting_chunk hash ch_x ch_y ch_z screen_wd screen_ht fov =
|
||||
try
|
||||
draw_multiples_cubes_colored_hash (Hashtbl.find hash (ch_x, ch_y, ch_z)) screen_wd screen_ht fov
|
||||
draw_multiples_cubes_colored_hash (Hashtbl.find hash (ch_x, ch_y, ch_z)) hash screen_wd screen_ht fov
|
||||
with
|
||||
| Not_found -> () ;;
|
||||
|
||||
|
@ -952,6 +1058,7 @@ let render_chunks hash camx camy camz ch_distance screen_wd screen_ht fov =
|
|||
done
|
||||
done;
|
||||
let sort_fct elt1 elt2 =
|
||||
(*- (snd (snd elt2)) + (snd (snd elt1))*)
|
||||
(snd (snd elt2)) - (snd (snd elt1))
|
||||
in
|
||||
|
||||
|
@ -987,7 +1094,6 @@ let play_dos laby =
|
|||
|
||||
let (ch_x, ch_y, ch_z) = coords_to_chunk_f (-. camera_xyz.x) (-. camera_xyz.y) camera_xyz.z in
|
||||
|
||||
(*draw_multiples_cubes_colored_hash (Hashtbl.find hash (ch_x, ch_y, ch_z)) __width__ __height__ fov ;*)
|
||||
render_chunks hash ch_x ch_y ch_z chunk_dist __width__ __height__ fov ;
|
||||
|
||||
auto_synchronize true;
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
2 2
|
||||
250,0,250 0,0,0
|
||||
0,0,0 250,0,250
|
||||
250,0,250 2,2,2
|
||||
2,2,2 250,0,250
|
||||
|
|
Loading…
Reference in New Issue