class Funfriend::FunfriendRenderer FPS = 10.0 getter shader_program : Program getter vertex_array : VertexArray getter vertex_buffer : Buffer getter textures : Hash(String, TextureMan::TextureBasket) property catmoding : Bool def initialize @catmoding = false @shader_program = init_shaders @vertex_array, @vertex_buffer = init_buffers @textures = init_textures end def funfriend_size funfriend_size = ConfigMan.config["window"]["funfriend_size"].as(Int32) {width: funfriend_size, height: funfriend_size} end def init_textures return { "normal" => TextureMan::TextureBasket.new( (0..39).map { |i| TextureMan.load_texture("assets/funfriend/funfriend_#{i.to_s.rjust(2, '0')}.png") }, FPS ), "cat" => TextureMan::TextureBasket.new( (0..39).map { |i| TextureMan.load_texture("assets/funfriend/catfriend_#{i.to_s.rjust(2, '0')}.png") }, FPS ) } 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 vertex_shader_source = FileStorage.get("nop.vert").gets_to_end fragment_shader_source = FileStorage.get("funfriend.frag").gets_to_end vertex_shader = VertexShader.create(vertex_shader_source) fragment_shader = FragmentShader.create(fragment_shader_source) shaders = {vertex_shader, fragment_shader} return Program.create(shaders) 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.each_value &.update(dt) texture_basket = textures[catmoding ? "cat" : "normal"] frame = texture_basket.texture width, height = frame[:width], frame[:height] Texture::Unit.activate(0) frame[:tex].bind(Texture::Target::Texture2D) do shader_program.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