funfriend/src/buddy_renderer.cr

110 lines
3.3 KiB
Crystal

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