From 2855edbb81f64ffadb93576e0800066f71880746 Mon Sep 17 00:00:00 2001 From: tali Date: Fri, 19 Jan 2024 16:22:10 -0500 Subject: [PATCH] add basic texture rendering (no clips, no instances) --- assets/shaders/sprite.frag | 12 ++++++++ assets/shaders/sprite.vert | 25 ++++++++++++++++ src/main.ml | 4 +++ src/s2/renderer.ml | 58 ++++++++++++++++++++++++++++++-------- src/s2/s2.mli | 2 +- 5 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 assets/shaders/sprite.frag create mode 100644 assets/shaders/sprite.vert diff --git a/assets/shaders/sprite.frag b/assets/shaders/sprite.frag new file mode 100644 index 0000000..5bea912 --- /dev/null +++ b/assets/shaders/sprite.frag @@ -0,0 +1,12 @@ +#version 150 core + +uniform sampler2D Texture; +uniform vec4 Tint; + +in vec2 TextureCoord; + +out vec4 FragColor; + +void main() { + FragColor = texture2D(Texture, TextureCoord) * Tint; +} diff --git a/assets/shaders/sprite.vert b/assets/shaders/sprite.vert new file mode 100644 index 0000000..9b413ca --- /dev/null +++ b/assets/shaders/sprite.vert @@ -0,0 +1,25 @@ +#version 150 core + +uniform ivec2 Viewport; +uniform mat3 Transform; +uniform vec4 BoundingBox; + +in vec2 Vert; + +/* TODO: instances */ +// in vec4 Rect; +// in vec4 Clip; + +out vec2 TextureCoord; + +void main() { + vec2 vert = mix(BoundingBox.xy, BoundingBox.zw, Vert); + vec3 pos = Transform * vec3(vert, 1.0); + + // TextureCoord = mix(Clip.st, Clip.pq, Vert) / textureSize(T, 0); + TextureCoord = Vert; + + gl_Position.xy = pos.xy * vec2(2.0, -2.0) / Viewport + vec2(-1.0, 1.0); + gl_Position.z = 0.0; + gl_Position.w = 1.0; +} diff --git a/src/main.ml b/src/main.ml index 40010c3..675a8dd 100644 --- a/src/main.ml +++ b/src/main.ml @@ -45,6 +45,10 @@ let main () = TG.update tg; SG.render sg ~ren; + Renderer.draw_texture ren cat + ~tf + ~bb:(aabb 0.0 0.0 (200.0) (200.0)); + Renderer.post_draw ren; Gc.minor (); diff --git a/src/s2/renderer.ml b/src/s2/renderer.ml index 88926e9..e3014ce 100644 --- a/src/s2/renderer.ml +++ b/src/s2/renderer.ml @@ -216,6 +216,13 @@ let make_texture ~size ~format (pixels : pixel_array) = Gl.bind_texture Gl.texture_2d 0; { tid; tsize = size } +let set_tex : texture set_fn = + fun (U l) { tid; _ } -> + (* TODO: in order to allow multiple textures, there should something like a LRU cache of + which texture unit each is bound to. *) + Gl.bind_texture Gl.texture_2d tid; + Gl.uniform1i l 0 + (* Renderer *) @@ -224,7 +231,11 @@ type t = { gl_ctx : Sdl.gl_context; polygon : shader; - rect : geometry; + polygon_rect : geometry; + + sprite : shader; + sprite_rect : geometry; + (* sprite_instances : vertex_buffer; *) } let unit_square = @@ -269,12 +280,8 @@ let make ~(wnd : Sdl.window) : t = Gl.blend_func Gl.one Gl.one_minus_src_alpha; Gl.check_error "setup"; - let polygon = - load_shader - ~name:"polygon" - in - - let rect = + let polygon = load_shader ~name:"polygon" in + let polygon_rect = make_geometry [ make_static_vertex_buffer unit_square_with_norm [ attr polygon "Vert" `float 2; @@ -285,11 +292,25 @@ let make ~(wnd : Sdl.window) : t = ~index:(`count 4) in + let sprite = load_shader ~name:"sprite" in + let sprite_rect = + make_geometry [ + make_static_vertex_buffer unit_square [ + attr polygon "Vert" `float 2; + ] + (* sprite_instances *) + ] + ~draw_mode:Gl.triangle_strip + ~index:(`count 4) + in + { window = wnd; gl_ctx; polygon; - rect; + polygon_rect; + sprite; + sprite_rect; } let destroy t = @@ -299,7 +320,8 @@ let pre_draw t = let viewport = Sdl.get_window_size t.window in begin Sdl.gl_make_current_exn t.window t.gl_ctx; - set_ivec2 (uniform t.polygon "Viewport") viewport; + use t.polygon; set_ivec2 (uniform t.polygon "Viewport") viewport; + use t.sprite; set_ivec2 (uniform t.sprite "Viewport") viewport; end let post_draw t = @@ -313,7 +335,7 @@ let clear _t (bg : color) = Gl.clear Gl.color_buffer_bit; end -let draw_rect t ~(tf : mat2a) ~(bb : aabb) ~(fill : color) = +let draw_rect t ~tf ~bb ~fill = let sh = t.polygon in begin (* TODO: cache/store uniform locations in some way *) @@ -322,5 +344,19 @@ let draw_rect t ~(tf : mat2a) ~(bb : aabb) ~(fill : color) = set_aabb (uniform sh "BoundingBox") bb; set_int (uniform sh "Border") 0; set_color (uniform sh "Fill") fill; - draw_geometry t.rect; + draw_geometry t.polygon_rect; + end + +let _white = Color.white () + +let draw_texture t ~tf ~bb ?(tint = _white) tex = + let sh = t.sprite in + begin + (* TODO: cache/store uniform locations in some way *) + use sh; + set_mat2a (uniform sh "Transform") tf; + set_aabb (uniform sh "BoundingBox") bb; + set_tex (uniform sh "Texture") tex; + set_color (uniform sh "Tint") tint; + draw_geometry t.sprite_rect; end diff --git a/src/s2/s2.mli b/src/s2/s2.mli index 38ed3e4..4a6d145 100644 --- a/src/s2/s2.mli +++ b/src/s2/s2.mli @@ -31,7 +31,7 @@ module Renderer : sig val post_draw : t -> unit val clear : t -> 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 *) + val draw_texture : t -> tf:mat2a -> bb:aabb -> ?tint:color -> Texture.t -> unit end module Asset : sig