add loading textures from sdl surfaces
This commit is contained in:
parent
104d941ab7
commit
635d742363
15
src/main.ml
15
src/main.ml
|
@ -8,16 +8,21 @@ include (val Ohlog.logs "Main")
|
||||||
|
|
||||||
let main () =
|
let main () =
|
||||||
debug (fun m -> m "initializing");
|
debug (fun m -> m "initializing");
|
||||||
let window = Window.make ~title:"GEOMETRA" in
|
let wnd = Window.make ~title:"GEOMETRA" in
|
||||||
info (fun m -> m "window initialized");
|
info (fun m -> m "window initialized");
|
||||||
let ren = Renderer.make ~window in
|
let ren = Renderer.make ~wnd in
|
||||||
info (fun m -> m "renderer initialized");
|
info (fun m -> m "renderer initialized");
|
||||||
|
|
||||||
|
let cat = Asset.load_texture "catthumbsup.png" in
|
||||||
|
info (fun m -> m "%dx%d" (Texture.width cat) (Texture.height cat));
|
||||||
|
debug (fun m -> m "loaded assets");
|
||||||
|
|
||||||
let tg = TG.make () in
|
let tg = TG.make () in
|
||||||
let sg = SG.make () in
|
let sg = SG.make () in
|
||||||
|
|
||||||
let scene = Scene.load "main" ~tg ~sg in
|
let scene = Scene.load "main" ~tg ~sg in
|
||||||
let root = Scene.get scene "root" in
|
let root = Scene.get scene "root" in
|
||||||
|
debug (fun m -> m "loaded scene");
|
||||||
|
|
||||||
let render time =
|
let render time =
|
||||||
begin
|
begin
|
||||||
|
@ -45,16 +50,16 @@ let main () =
|
||||||
Gc.minor ();
|
Gc.minor ();
|
||||||
end
|
end
|
||||||
in
|
in
|
||||||
Window.event_loop window ~render;
|
Window.event_loop wnd ~render;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
info (fun m -> m "quitting");
|
info (fun m -> m "quitting");
|
||||||
Window.destroy window;
|
Window.destroy wnd;
|
||||||
Renderer.destroy ren;
|
Renderer.destroy ren;
|
||||||
end
|
end
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
Ohlog.init () ~min_level:DEBUG;
|
Ohlog.init () ~min_level:TRACE;
|
||||||
|
|
||||||
try main () with
|
try main () with
|
||||||
| Sdl.Error msg -> error (fun m -> m "SDL error: %s" msg)
|
| Sdl.Error msg -> error (fun m -> m "SDL error: %s" msg)
|
||||||
|
|
|
@ -3,14 +3,13 @@ include (val Ohlog.sublogs logger "asset")
|
||||||
|
|
||||||
exception Error of string * string
|
exception Error of string * string
|
||||||
|
|
||||||
|
let absolute_path path =
|
||||||
|
Unix.realpath (Printf.sprintf "assets/%s" path)
|
||||||
|
|
||||||
let load_file path =
|
let load_file path =
|
||||||
trace (fun m -> m "open text file %S" path);
|
trace (fun m -> m "open text file %S" path);
|
||||||
let abspath =
|
|
||||||
Unix.realpath
|
|
||||||
(Printf.sprintf "assets/%s" path)
|
|
||||||
in
|
|
||||||
let fd =
|
let fd =
|
||||||
try Unix.openfile abspath [O_RDONLY] 0
|
try Unix.openfile (absolute_path path) [O_RDONLY] 0
|
||||||
with Unix.Unix_error (ENOENT, _, _) ->
|
with Unix.Unix_error (ENOENT, _, _) ->
|
||||||
raise (Error (path, "not found"))
|
raise (Error (path, "not found"))
|
||||||
in
|
in
|
||||||
|
|
|
@ -6,5 +6,6 @@
|
||||||
|
|
||||||
ohlog
|
ohlog
|
||||||
tsdl
|
tsdl
|
||||||
|
tsdl-image
|
||||||
tgls.tgl4
|
tgls.tgl4
|
||||||
sexplib))
|
sexplib))
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
open! Import
|
open! Import
|
||||||
include (val Ohlog.sublogs logger "Ren")
|
include (val Ohlog.sublogs logger "Ren")
|
||||||
|
|
||||||
|
type ivec2 = int * int
|
||||||
|
|
||||||
|
|
||||||
(* Buffer *)
|
(* Buffer *)
|
||||||
|
|
||||||
|
@ -129,7 +131,7 @@ let uniform {spo} name =
|
||||||
type 'a set_fn = 'a uniform -> 'a -> unit
|
type 'a set_fn = 'a uniform -> 'a -> unit
|
||||||
|
|
||||||
let set_int : int set_fn = fun (U l) x -> Gl.uniform1i l x
|
let set_int : int set_fn = fun (U l) x -> Gl.uniform1i l x
|
||||||
let set_ivec2 : (int*int) set_fn = fun (U l) (x, y) -> Gl.uniform2i l x y
|
let set_ivec2 : ivec2 set_fn = fun (U l) (x, y) -> Gl.uniform2i l x y
|
||||||
let set_color : color set_fn = fun (U l) c -> Gl.uniform4f l c.r c.g c.b c.a
|
let set_color : color set_fn = fun (U l) c -> Gl.uniform4f l c.r c.g c.b c.a
|
||||||
let set_aabb : aabb set_fn = fun (U l) b -> Gl.uniform4f l b.x0 b.y0 b.x1 b.y1
|
let set_aabb : aabb set_fn = fun (U l) b -> Gl.uniform4f l b.x0 b.y0 b.x1 b.y1
|
||||||
|
|
||||||
|
@ -190,6 +192,31 @@ let draw_geometry ?(instances = 1) { vao; draw_mode; indices } =
|
||||||
Gl.draw_elements_instanced draw_mode n type_ offset instances
|
Gl.draw_elements_instanced draw_mode n type_ offset instances
|
||||||
|
|
||||||
|
|
||||||
|
(* Texture *)
|
||||||
|
|
||||||
|
type texture = {
|
||||||
|
tid : int;
|
||||||
|
tsize : ivec2;
|
||||||
|
}
|
||||||
|
|
||||||
|
type pixel_array = (float, Bigarray.float32_elt, Bigarray.c_layout) Array1.t
|
||||||
|
|
||||||
|
let make_texture ~size ~format (pixels : pixel_array) =
|
||||||
|
Gl.gen_textures 1 Gl._i32;
|
||||||
|
let tid = Int32.to_int Gl._i32.{0} in
|
||||||
|
let width, height = size in
|
||||||
|
Gl.bind_texture Gl.texture_2d tid;
|
||||||
|
(* TODO: configurable *)
|
||||||
|
Gl.tex_parameteri Gl.texture_2d Gl.texture_wrap_s Gl.clamp_to_edge;
|
||||||
|
Gl.tex_parameteri Gl.texture_2d Gl.texture_wrap_t Gl.clamp_to_edge;
|
||||||
|
Gl.tex_parameteri Gl.texture_2d Gl.texture_min_filter Gl.linear_mipmap_linear;
|
||||||
|
Gl.tex_parameteri Gl.texture_2d Gl.texture_mag_filter Gl.linear;
|
||||||
|
Gl.tex_image2d Gl.texture_2d 0 format width height 0 format Gl.float (`Data pixels);
|
||||||
|
Gl.generate_mipmap Gl.texture_2d;
|
||||||
|
Gl.bind_texture Gl.texture_2d 0;
|
||||||
|
{ tid; tsize = size }
|
||||||
|
|
||||||
|
|
||||||
(* Renderer *)
|
(* Renderer *)
|
||||||
|
|
||||||
type t = {
|
type t = {
|
||||||
|
@ -232,10 +259,10 @@ let unit_square_with_norm =
|
||||||
[| 0.; 1.; -1.; 1. |];
|
[| 0.; 1.; -1.; 1. |];
|
||||||
]
|
]
|
||||||
|
|
||||||
let make ~(window : Sdl.window) : t =
|
let make ~(wnd : Sdl.window) : t =
|
||||||
debug (fun m -> m "initializing");
|
debug (fun m -> m "initializing");
|
||||||
let gl_ctx = Sdl.gl_create_context_exn window in
|
let gl_ctx = Sdl.gl_create_context_exn wnd in
|
||||||
Sdl.gl_make_current_exn window gl_ctx;
|
Sdl.gl_make_current_exn wnd gl_ctx;
|
||||||
Sdl.gl_set_swap_interval_exn 1;
|
Sdl.gl_set_swap_interval_exn 1;
|
||||||
|
|
||||||
Gl.enable Gl.blend;
|
Gl.enable Gl.blend;
|
||||||
|
@ -259,7 +286,7 @@ let make ~(window : Sdl.window) : t =
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
window;
|
window = wnd;
|
||||||
gl_ctx;
|
gl_ctx;
|
||||||
polygon;
|
polygon;
|
||||||
rect;
|
rect;
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
module Window = Window
|
module Window = Window
|
||||||
module Asset = Asset
|
|
||||||
module Renderer = Renderer
|
module Renderer = Renderer
|
||||||
|
module Texture = Texture
|
||||||
|
module Asset = struct
|
||||||
|
include Asset
|
||||||
|
include Texture.Asset
|
||||||
|
end
|
||||||
module Sdl = Sdl
|
module Sdl = Sdl
|
||||||
module Gl = Gl
|
module Gl = Gl
|
||||||
|
|
|
@ -14,17 +14,24 @@ module Window : sig
|
||||||
val event_loop : t -> render:(float -> unit) -> unit
|
val event_loop : t -> render:(float -> unit) -> unit
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module Texture : sig
|
||||||
|
type t
|
||||||
|
val width : t -> int
|
||||||
|
val height : t -> int
|
||||||
|
end
|
||||||
|
|
||||||
module Renderer : sig
|
module Renderer : sig
|
||||||
open Adam
|
open Adam
|
||||||
|
|
||||||
type t
|
type t
|
||||||
val make : window:Window.t -> t
|
val make : wnd:Window.t -> t
|
||||||
val destroy : t -> unit
|
val destroy : t -> unit
|
||||||
|
|
||||||
val pre_draw : t -> unit
|
val pre_draw : t -> unit
|
||||||
val post_draw : t -> unit
|
val post_draw : t -> unit
|
||||||
val clear : t -> color -> unit
|
val clear : t -> color -> unit
|
||||||
val draw_rect : t -> tf:mat2a -> bb:aabb -> fill:color -> unit
|
val draw_rect : t -> tf:mat2a -> bb:aabb -> fill:color -> unit
|
||||||
|
(* val draw_texture : t -> tf:mat2a -> bb:aabb -> tex:Texture.t -> unit *)
|
||||||
end
|
end
|
||||||
|
|
||||||
module Asset : sig
|
module Asset : sig
|
||||||
|
@ -34,4 +41,5 @@ module Asset : sig
|
||||||
|
|
||||||
val load_file : string -> string
|
val load_file : string -> string
|
||||||
val load_sexp_conv : string -> (Sexp.t -> 'a) -> 'a
|
val load_sexp_conv : string -> (Sexp.t -> 'a) -> 'a
|
||||||
|
val load_texture : string -> Texture.t
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
open! Import
|
open! Import
|
||||||
include Tsdl.Sdl
|
include Tsdl.Sdl
|
||||||
|
include Tsdl_image
|
||||||
|
|
||||||
exception Error of string
|
exception Error of string
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
open Import
|
||||||
|
open Renderer
|
||||||
|
|
||||||
|
type t = texture
|
||||||
|
|
||||||
|
let width t = fst t.tsize
|
||||||
|
let height t = snd t.tsize
|
||||||
|
|
||||||
|
let conv_alpha_premultiply ~size ~pitch ~stride src ofs_r ofs_g ofs_b ofs_a =
|
||||||
|
trace (fun m -> m "premultiply alpha: %d,%d,%d,%d,%d,%d,%d,%d"
|
||||||
|
(fst size) (snd size) pitch stride ofs_r ofs_g ofs_b ofs_a);
|
||||||
|
let width, height = size in
|
||||||
|
let dst = Array1.create Float32 C_layout (width * height * 4) in
|
||||||
|
for y = 0 to height - 1 do
|
||||||
|
for x = 0 to width - 1 do
|
||||||
|
let idx = y * pitch + x * stride in
|
||||||
|
let sr = src.{idx + ofs_r} in
|
||||||
|
let sg = src.{idx + ofs_g} in
|
||||||
|
let sb = src.{idx + ofs_b} in
|
||||||
|
let sa = src.{idx + ofs_a} in
|
||||||
|
let i = (y * width + x) * 4 in
|
||||||
|
dst.{i + 0} <- Float.of_int (sr * sa) /. 65025.;
|
||||||
|
dst.{i + 1} <- Float.of_int (sg * sa) /. 65025.;
|
||||||
|
dst.{i + 2} <- Float.of_int (sb * sa) /. 65025.;
|
||||||
|
dst.{i + 3} <- Float.of_int sa /. 255.;
|
||||||
|
done
|
||||||
|
done;
|
||||||
|
make_texture dst ~size ~format:Gl.rgba
|
||||||
|
|
||||||
|
let conv_noalpha ~size ~pitch ~stride src ofs_r ofs_g ofs_b =
|
||||||
|
trace (fun m -> m "no alpha: %d,%d,%d,%d,%d,%d,%d"
|
||||||
|
(fst size) (snd size) pitch stride ofs_r ofs_g ofs_b);
|
||||||
|
let width, height = size in
|
||||||
|
let dst = Array1.create Float32 C_layout (width * height * 3) in
|
||||||
|
for y = 0 to height - 1 do
|
||||||
|
for x = 0 to width - 1 do
|
||||||
|
let idx = (y * pitch) + (x * stride) in
|
||||||
|
let sr = src.{idx + ofs_r} in
|
||||||
|
let sg = src.{idx + ofs_g} in
|
||||||
|
let sb = src.{idx + ofs_b} in
|
||||||
|
let i = (y * width + x) * 3 in
|
||||||
|
dst.{i + 0} <- Float.of_int sr /. 255.;
|
||||||
|
dst.{i + 1} <- Float.of_int sg /. 255.;
|
||||||
|
dst.{i + 2} <- Float.of_int sb /. 255.;
|
||||||
|
done
|
||||||
|
done;
|
||||||
|
make_texture dst ~size ~format:Gl.rgb
|
||||||
|
|
||||||
|
let pp_pixfmt ppf x = Format.pp_print_string ppf (Sdl.get_pixel_format_name x)
|
||||||
|
|
||||||
|
let of_surface srf =
|
||||||
|
let pixfmt = Sdl.get_surface_format_enum srf in
|
||||||
|
let size = Sdl.get_surface_size srf in
|
||||||
|
let pitch = Sdl.get_surface_pitch srf in
|
||||||
|
let data = Sdl.get_surface_pixels srf Int8_unsigned in
|
||||||
|
trace (fun m -> m "converting texture from %a" pp_pixfmt pixfmt);
|
||||||
|
if Sdl.Pixel.eq pixfmt Sdl.Pixel.format_abgr8888 then
|
||||||
|
conv_alpha_premultiply data ~size ~pitch ~stride:4 0 1 2 3
|
||||||
|
else if Sdl.Pixel.eq pixfmt Sdl.Pixel.format_rgb24 then
|
||||||
|
conv_noalpha data ~size ~pitch ~stride:3 0 1 2
|
||||||
|
else
|
||||||
|
Format.kasprintf failwith "unsupported pixel format %a" pp_pixfmt pixfmt
|
||||||
|
|
||||||
|
let of_surface_free srf =
|
||||||
|
try
|
||||||
|
let tex = of_surface srf in
|
||||||
|
Sdl.free_surface srf; tex
|
||||||
|
with e ->
|
||||||
|
Sdl.free_surface srf; raise e
|
||||||
|
|
||||||
|
module Asset = struct
|
||||||
|
open Asset
|
||||||
|
|
||||||
|
let load_texture path =
|
||||||
|
trace (fun m -> m "open image %S" path);
|
||||||
|
try
|
||||||
|
match Sdl.Image.load (absolute_path path) with
|
||||||
|
| Ok srf ->
|
||||||
|
of_surface_free srf
|
||||||
|
| Error (`Msg msg) ->
|
||||||
|
failwith msg
|
||||||
|
with
|
||||||
|
Failure msg -> raise (Error (path, msg))
|
||||||
|
end
|
Loading…
Reference in New Issue