class Funfriend::BuddyRenderer getter buddy : Buddy getter buddy_shader : Program getter bg_shader : Program getter vertex_array : VertexArray getter vertex_buffer : Buffer getter textures : TextureMan::TextureBasket getter bg_texture : Texture? def initialize(@buddy : Buddy) @buddy_shader, @bg_shader = init_shaders @vertex_array, @vertex_buffer = init_buffers @textures = buddy.textures @bg_texture = buddy.bg_texture end def funfriend_size funfriend_size = ConfigMan.config["window"]["funfriend_size"].as(Int32) {width: funfriend_size, height: funfriend_size} end def init_buffers vertices = { # ------ positions ------- texture coordinates 1.0f32, 1.0f32, 0.0f32, 1.0f32, 1.0f32, # top right 1.0f32, -1.0f32, 0.0f32, 1.0f32, 0.0f32, # bottom right -1.0f32, -1.0f32, 0.0f32, 0.0f32, 0.0f32, # bottom left -1.0f32, 1.0f32, 0.0f32, 0.0f32, 1.0f32 # top left } # Indices used for indexed draw calls. Each is used as an index into the four vertices. indices = { 0, 1, 3, # first triangle 1, 2, 3 # second triangle } vertex_buffer = Buffer.new element_buffer = Buffer.new vertex_array = VertexArray.new vertex_array.bind do vertex_buffer.bind(Buffer::Target::Array) do |buffer, target| target.buffer_data(vertices, Buffer::UsageHint::StaticDraw) vertex_array.define_attributes do |va| va.attribute(3, DataType::Float, false) va.attribute(2, DataType::Float, false) end end # bind the element buffer to GL_ELEMENT_ARRAY_BUFFER element_buffer.bind(Buffer::Target::ElementArray) # Send index data to the GPU. Buffer::Target::ElementArray.buffer_data(indices, Buffer::UsageHint::StaticDraw) end # unbind the element buffer. element_buffer.unbind return {vertex_array, vertex_buffer} end def init_shaders {GL.shader("funfriend.frag", "nop.vert"), GL.shader("nop.frag", "nop.vert")} end def render(dt : Float64, window_width : Int32, window_height : Int32) LibGL.clear_color(0.0, 0.0, 0.0, 0.0) LibGL.clear(Buffer::Bit::Color) textures.update(dt) frame = textures.texture width, height = frame[:width], frame[:height] LibGL.enable(LibGL::BLEND) LibGL.blend_func(LibGL::SRC_ALPHA, LibGL::ONE_MINUS_SRC_ALPHA) if bg_texture bg_texture.not_nil!.bind(Texture::Target::Texture2D) do bg_shader.use do |shader| shader.set_uniform("texture1", 0) vertex_array.bind do LibGL.draw_elements(LibGL::TRIANGLES, 6, DataType::UnsignedInt, Pointer(Void).new(0)) end end end end frame[:tex].bind(Texture::Target::Texture2D) do buddy_shader.use do |shader| shader.set_uniform("texture1", 0) shader.set_uniform("funfriendSize", funfriend_size[:width].to_f32, funfriend_size[:height].to_f32) shader.set_uniform("resolution", window_width.to_f32, window_height.to_f32) shader.set_uniform("time", CrystGLFW.time.to_f32) vertex_array.bind do LibGL.draw_elements(LibGL::TRIANGLES, 6, DataType::UnsignedInt, Pointer(Void).new(0)) end end end end def clean_up {vertex_array, vertex_buffer}.each { |v| v.delete } end end