From 35d6061198b7915ca8239c6f561f19d21b85ae63 Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Sun, 22 Mar 2020 14:56:22 -0500 Subject: [PATCH] Setup GBuffer for future deferred rendering --- i-mic-fps.rb | 1 + lib/renderer/g_buffer.rb | 83 +++++++++++++++++++++++++++++++++ lib/renderer/opengl_renderer.rb | 8 ++-- 3 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 lib/renderer/g_buffer.rb diff --git a/i-mic-fps.rb b/i-mic-fps.rb index 4532397..9d7a13f 100644 --- a/i-mic-fps.rb +++ b/i-mic-fps.rb @@ -40,6 +40,7 @@ require_relative "lib/managers/collision_manager" require_relative "lib/managers/physics_manager" require_relative "lib/renderer/renderer" +require_relative "lib/renderer/g_buffer" require_relative "lib/renderer/opengl_renderer" require_relative "lib/renderer/bounding_box_renderer" diff --git a/lib/renderer/g_buffer.rb b/lib/renderer/g_buffer.rb new file mode 100644 index 0000000..75047ed --- /dev/null +++ b/lib/renderer/g_buffer.rb @@ -0,0 +1,83 @@ +class IMICFPS + class GBuffer + include CommonMethods + + def initialize + @framebuffer = nil + @buffers = [:position, :diffuse, :normal, :texcoord] + @textures = {} + @ready = false + + create_framebuffer + end + + def create_framebuffer + buffer = ' ' * 8 + glGenFramebuffers(1, buffer) + @framebuffer = buffer.unpack('L2').first + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, @framebuffer) + + create_textures + + status = glCheckFramebufferStatus(GL_FRAMEBUFFER) + + if status != GL_FRAMEBUFFER_COMPLETE + message = "" + + case status + when GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT + message = "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT" + when GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT + message = "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT" + when GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER + message = "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER" + when GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER + message = "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER" + when GL_FRAMEBUFFER_UNSUPPORTED + message = "GL_FRAMEBUFFER_UNSUPPORTED" + else + message = "Unknown error!" + end + puts "Incomplete framebuffer: #{status}\nError: #{message}" + else + @ready = true + end + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0) + end + + def create_textures + @buffers.size.times do |i| + buffer = ' ' * 8 + glGenTextures(1, buffer) + texture_id = buffer.unpack('L2').first + @textures[@buffers[i]] = texture_id + + glBindTexture(GL_TEXTURE_2D, texture_id) + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, window.width, window.height, 0, GL_RGB, GL_FLOAT, nil) + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, texture_id, 0) + end + + buffer = ' ' * 8 + glGenTextures(1, buffer) + texture_id = buffer.unpack('L2').first + @textures[:depth] = texture_id + + glBindTexture(GL_TEXTURE_2D, texture_id) + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, window.width, window.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 + + def clean_up + glDeleteFramebuffers(@framebuffer) + + @textures.values.each do |id| + glDeleteTextures(id) + end + end + end +end \ No newline at end of file diff --git a/lib/renderer/opengl_renderer.rb b/lib/renderer/opengl_renderer.rb index c3f63da..138b5f6 100644 --- a/lib/renderer/opengl_renderer.rb +++ b/lib/renderer/opengl_renderer.rb @@ -2,8 +2,10 @@ class IMICFPS class OpenGLRenderer include CommonMethods + @@immediate_mode_warning = false + def initialize - @immediate_mode_warning = false + @g_buffer = GBuffer.new end def draw_object(camera, lights, object) @@ -32,8 +34,8 @@ class IMICFPS object.draw end else - puts "Shader 'default' failed to compile, using immediate mode for rendering..." unless @immediate_mode_warning - @immediate_mode_warning = true + puts "Shader 'default' failed to compile, using immediate mode for rendering..." unless @@immediate_mode_warning + @@immediate_mode_warning = true gl_error? lights.each(&:draw)