class CyberarmEngine::GBuffer

Attributes

screen_vbo[R]
uvs[R]
vertices[R]

Public Class Methods

new(width:, height:) click to toggle source
# File lib/cyberarm_engine/opengl/renderer/g_buffer.rb, line 5
def initialize(width:, height:)
  @width = width
  @height = height

  @framebuffer = nil
  @buffers = %i[position diffuse normal texcoord]
  @textures = {}
  @screen_vbo = nil
  @ready = false

  @vertices = [
    -1.0, -1.0, 0,
    1.0,  -1.0, 0,
    -1.0,  1.0, 0,

    -1.0,  1.0, 0,
    1.0, -1.0, 0,
    1.0, 1.0, 0
  ].freeze

  @uvs = [
    0, 0,
    1, 0,
    0, 1,

    0, 1,
    1, 0,
    1, 1
  ].freeze

  create_framebuffer
  create_screen_vbo
end

Public Instance Methods

bind_for_reading() click to toggle source
# File lib/cyberarm_engine/opengl/renderer/g_buffer.rb, line 134
def bind_for_reading
  glBindFramebuffer(GL_READ_FRAMEBUFFER, @framebuffer)
end
bind_for_writing() click to toggle source
# File lib/cyberarm_engine/opengl/renderer/g_buffer.rb, line 130
def bind_for_writing
  glBindFramebuffer(GL_DRAW_FRAMEBUFFER, @framebuffer)
end
clean_up() click to toggle source
# File lib/cyberarm_engine/opengl/renderer/g_buffer.rb, line 154
def clean_up
  glDeleteFramebuffers(1, [@framebuffer].pack("L"))

  glDeleteTextures(@textures.values.size, @textures.values.pack("L*"))

  glDeleteBuffers(2, [@positions_buffer_id, @uvs_buffer_id].pack("L*"))
  glDeleteVertexArrays(1, [@screen_vbo].pack("L"))
  gl_error?
end
create_framebuffer() click to toggle source
# File lib/cyberarm_engine/opengl/renderer/g_buffer.rb, line 39
def create_framebuffer
  buffer = " " * 4
  glGenFramebuffers(1, buffer)
  @framebuffer = buffer.unpack1("L2")

  glBindFramebuffer(GL_DRAW_FRAMEBUFFER, @framebuffer)

  create_textures

  status = glCheckFramebufferStatus(GL_FRAMEBUFFER)

  if status != GL_FRAMEBUFFER_COMPLETE
    message = ""

    message = case status
              when GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
                "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"
              when GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
                "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"
              when GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER
                "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"
              when GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER
                "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER"
              when GL_FRAMEBUFFER_UNSUPPORTED
                "GL_FRAMEBUFFER_UNSUPPORTED"
              else
                "Unknown error!"
              end
    puts "Incomplete framebuffer: #{status}\nError: #{message}"
  else
    @ready = true
  end

  glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0)
end
create_screen_vbo() click to toggle source
# File lib/cyberarm_engine/opengl/renderer/g_buffer.rb, line 102
def create_screen_vbo
  buffer = " " * 4
  glGenVertexArrays(1, buffer)
  @screen_vbo = buffer.unpack1("L2")

  buffer = " " * 4
  glGenBuffers(1, buffer)
  @positions_buffer_id = buffer.unpack1("L2")

  buffer = " " * 4
  glGenBuffers(1, buffer)
  @uvs_buffer_id = buffer.unpack1("L2")

  glBindVertexArray(@screen_vbo)
  glBindBuffer(GL_ARRAY_BUFFER, @positions_buffer_id)
  glBufferData(GL_ARRAY_BUFFER, @vertices.size * Fiddle::SIZEOF_FLOAT, @vertices.pack("f*"), GL_STATIC_DRAW)
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nil)

  glBindBuffer(GL_ARRAY_BUFFER, @uvs_buffer_id)
  glBufferData(GL_ARRAY_BUFFER, @uvs.size * Fiddle::SIZEOF_FLOAT, @uvs.pack("f*"), GL_STATIC_DRAW)
  glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, nil)

  glEnableVertexAttribArray(0)
  glEnableVertexAttribArray(1)

  glBindVertexArray(0)
end
create_textures() click to toggle source
# File lib/cyberarm_engine/opengl/renderer/g_buffer.rb, line 75
def create_textures
  @buffers.size.times do |i|
    buffer = " " * 4
    glGenTextures(1, buffer)
    texture_id = buffer.unpack1("L2")
    @textures[@buffers[i]] = texture_id

    glBindTexture(GL_TEXTURE_2D, texture_id)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, @width, @height, 0, GL_RGBA, GL_FLOAT, nil)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, texture_id, 0)
  end

  buffer = " " * 4
  glGenTextures(1, buffer)
  texture_id = buffer.unpack1("L2")
  @textures[:depth] = texture_id

  glBindTexture(GL_TEXTURE_2D, texture_id)
  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, @width, @height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nil)
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture_id, 0)

  draw_buffers = [GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3]
  glDrawBuffers(draw_buffers.size, draw_buffers.pack("I*"))
end
set_read_buffer(buffer) click to toggle source
# File lib/cyberarm_engine/opengl/renderer/g_buffer.rb, line 138
def set_read_buffer(buffer)
  glReadBuffer(GL_COLOR_ATTACHMENT0 + @textures.keys.index(buffer))
end
set_read_buffer_depth() click to toggle source
# File lib/cyberarm_engine/opengl/renderer/g_buffer.rb, line 142
def set_read_buffer_depth
  glReadBuffer(GL_DEPTH_ATTACHMENT)
end
texture(type) click to toggle source
# File lib/cyberarm_engine/opengl/renderer/g_buffer.rb, line 150
def texture(type)
  @textures[type]
end
unbind_framebuffer() click to toggle source
# File lib/cyberarm_engine/opengl/renderer/g_buffer.rb, line 146
def unbind_framebuffer
  glBindFramebuffer(GL_FRAMEBUFFER, 0)
end