From 0d1d7ff6bc747e3d65ebb6fa4ad5c6292a10b6b0 Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Sun, 22 Mar 2020 17:22:10 -0500 Subject: [PATCH] Fixed modern opengl renderer not renderering model textures, framebuffer can be used without crashing, model uv coordinates are now in buffer, minor rendering optimization --- lib/model.rb | 20 ++++---- lib/renderer/g_buffer.rb | 16 +++++++ lib/renderer/opengl_renderer.rb | 82 ++++++++++++++++++++------------- lib/renderer/renderer.rb | 13 +----- shaders/fragment/default.glsl | 19 ++++++-- 5 files changed, 95 insertions(+), 55 deletions(-) diff --git a/lib/model.rb b/lib/model.rb index a346590..e4d22bf 100644 --- a/lib/model.rb +++ b/lib/model.rb @@ -44,6 +44,15 @@ class IMICFPS puts "#{@file_path.split('/').last} took #{((Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)-start_time)/1000.0).round(2)} seconds to parse" if window.config.get(:debug_options, :stats) + @has_texture = false + + @materials.each do |key, material| + if material.texture_id + @has_texture = true + @textured_material = key + end + end + if Shader.available?("default") allocate_gl_objects populate_vertex_buffer @@ -55,13 +64,6 @@ class IMICFPS puts " Model::Object Name: #{o.name}, Vertices: #{o.vertices.size}" if window.config.get(:debug_options, :stats) end window.number_of_vertices+=@vertex_count - @has_texture = false - @materials.each do |key, material| - if material.texture_id - @has_texture = true - @textured_material = key - end - end start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond) # build_collision_tree @@ -160,8 +162,8 @@ class IMICFPS glBindBuffer(GL_ARRAY_BUFFER, @uvs_buffer_id) glBufferData(GL_ARRAY_BUFFER, uvs.flatten.size * Fiddle::SIZEOF_FLOAT, uvs.flatten.pack("f*"), GL_STATIC_DRAW) - glBindBuffer(GL_ARRAY_BUFFER, @textures_buffer_id) - glBufferData(GL_ARRAY_BUFFER, tex_ids.flatten.size * Fiddle::SIZEOF_FLOAT, tex_ids.flatten.pack("f*"), GL_STATIC_DRAW) + # glBindBuffer(GL_ARRAY_BUFFER, @textures_buffer_id) + # glBufferData(GL_ARRAY_BUFFER, tex_ids.flatten.size * Fiddle::SIZEOF_FLOAT, tex_ids.flatten.pack("f*"), GL_STATIC_DRAW) end glBindBuffer(GL_ARRAY_BUFFER, 0) diff --git a/lib/renderer/g_buffer.rb b/lib/renderer/g_buffer.rb index 75047ed..3cee155 100644 --- a/lib/renderer/g_buffer.rb +++ b/lib/renderer/g_buffer.rb @@ -72,6 +72,22 @@ class IMICFPS glDrawBuffers(draw_buffers.size, draw_buffers.pack("I*")) end + def bind_for_writing + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, @framebuffer) + end + + def bind_for_reading + glBindFramebuffer(GL_READ_FRAMEBUFFER, @framebuffer) + end + + def set_read_buffer(buffer) + glReadBuffer(GL_COLOR_ATTACHMENT0 + @textures.keys.index(buffer)) + end + + def unbind_framebuffer + glBindFramebuffer(GL_FRAMEBUFFER, 0) + end + def clean_up glDeleteFramebuffers(@framebuffer) diff --git a/lib/renderer/opengl_renderer.rb b/lib/renderer/opengl_renderer.rb index 138b5f6..473d42d 100644 --- a/lib/renderer/opengl_renderer.rb +++ b/lib/renderer/opengl_renderer.rb @@ -8,31 +8,43 @@ class IMICFPS @g_buffer = GBuffer.new end - def draw_object(camera, lights, object) + def render(camera, lights, entities) if Shader.available?("default") + # @g_buffer.bind_for_writing + gl_error? + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) + Shader.use("default") do |shader| - shader.uniform_transform("projection", camera.projection_matrix) - shader.uniform_transform("view", camera.view_matrix) - shader.uniform_transform("model", object.model_matrix) - shader.uniform_boolean("hasTexture", object.model.has_texture?) - shader.uniform_vec3("cameraPosition", camera.position) + entities.each do |entity| + next unless entity.visible && entity.renderable - # TODO: Upload and use lights - lights.each_with_index do |light, i| - shader.uniform_float("lights[#{i}.end", -1.0); - shader.uniform_float("lights[#{i}.type", light.type); - shader.uniform_vec3("lights[#{i}].position", light.position) - shader.uniform_vec3("lights[#{i}].ambient", light.ambient) - shader.uniform_vec3("lights[#{i}].diffuse", light.diffuse) - shader.uniform_vec3("lights[#{i}].specular", light.specular) + shader.uniform_transform("projection", camera.projection_matrix) + shader.uniform_transform("view", camera.view_matrix) + shader.uniform_transform("model", entity.model_matrix) + shader.uniform_boolean("hasTexture", entity.model.has_texture?) + shader.uniform_vec3("cameraPosition", camera.position) + + # TODO: Upload and use lights + lights.each_with_index do |light, i| + shader.uniform_float("lights[#{i}.end", -1.0); + shader.uniform_float("lights[#{i}.type", light.type); + shader.uniform_vec3("lights[#{i}].position", light.position) + shader.uniform_vec3("lights[#{i}].ambient", light.ambient) + shader.uniform_vec3("lights[#{i}].diffuse", light.diffuse) + shader.uniform_vec3("lights[#{i}].specular", light.specular) + end + + shader.uniform_float("totalLights", lights.size) + + gl_error? + draw_model(entity.model, shader) + entity.draw end - - shader.uniform_float("totalLights", lights.size) - - gl_error? - draw_model(object.model) - object.draw end + + # @g_buffer.unbind_framebuffer + gl_error? else puts "Shader 'default' failed to compile, using immediate mode for rendering..." unless @@immediate_mode_warning @@immediate_mode_warning = true @@ -42,29 +54,35 @@ class IMICFPS camera.draw glEnable(GL_NORMALIZE) - glPushMatrix + entities.each do |entity| + next unless entity.visible && entity.renderable - glTranslatef(object.position.x, object.position.y, object.position.z) - glScalef(object.scale.x, object.scale.y, object.scale.z) - glRotatef(object.orientation.x, 1.0, 0, 0) - glRotatef(object.orientation.y, 0, 1.0, 0) - glRotatef(object.orientation.z, 0, 0, 1.0) + glPushMatrix - gl_error? - draw_mesh(object.model) - object.draw - glPopMatrix + glTranslatef(entity.position.x, entity.position.y, entity.position.z) + glScalef(entity.scale.x, entity.scale.y, entity.scale.z) + glRotatef(entity.orientation.x, 1.0, 0, 0) + glRotatef(entity.orientation.y, 0, 1.0, 0) + glRotatef(entity.orientation.z, 0, 0, 1.0) + + gl_error? + draw_mesh(entity.model) + entity.draw + glPopMatrix + end end gl_error? end - def draw_model(model) + def draw_model(model, shader) glBindVertexArray(model.vertex_array_id) glEnableVertexAttribArray(0) glEnableVertexAttribArray(1) glEnableVertexAttribArray(2) if model.has_texture? + glBindTexture(GL_TEXTURE_2D, model.materials[model.textured_material].texture_id) + glEnableVertexAttribArray(3) glEnableVertexAttribArray(4) end @@ -86,6 +104,8 @@ class IMICFPS if model.has_texture? glDisableVertexAttribArray(4) glDisableVertexAttribArray(3) + + glBindTexture(GL_TEXTURE_2D, 0) end glDisableVertexAttribArray(2) glDisableVertexAttribArray(1) diff --git a/lib/renderer/renderer.rb b/lib/renderer/renderer.rb index 3e5806e..89e19bc 100644 --- a/lib/renderer/renderer.rb +++ b/lib/renderer/renderer.rb @@ -13,18 +13,7 @@ class IMICFPS glViewport(0, 0, window.width, window.height) glEnable(GL_DEPTH_TEST) - entities.each do |object| - if object.visible && object.renderable - # Render bounding boxes before transformation is applied - # @bounding_box_renderer.create_bounding_box(object, object.model.bounding_box, object.debug_color, object.object_id) if window.config.get(:debug_options, :boundingboxes) - - @opengl_renderer.draw_object(camera, lights, object) - end - end - - # @bounding_box_renderer.draw_bounding_boxes if window.config.get(:debug_options, :boundingboxes) - # window.number_of_vertices+=@bounding_box_renderer.vertex_count if window.config.get(:debug_options, :boundingboxes) - # @bounding_box_renderer.bounding_boxes.clear + @opengl_renderer.render(camera, lights, entities) end def finalize # cleanup diff --git a/shaders/fragment/default.glsl b/shaders/fragment/default.glsl index 2e14c32..117dd49 100644 --- a/shaders/fragment/default.glsl +++ b/shaders/fragment/default.glsl @@ -7,6 +7,7 @@ in vec3 outColor; in vec4 outNormal; in vec3 outUV; in float outTextureID; +in float outHasTexture; in Light outLights[MAX_LIGHTS]; in float outTotalLights; in vec3 outFragPos; @@ -14,6 +15,8 @@ in vec3 outCameraPos; in vec3 outInverseNormal; in float outDisableLighting; +uniform sampler2D diffuse_texture; + // optimizing compilers are annoying at this stage of my understanding of GLSL vec4 lokiVar; @@ -78,10 +81,20 @@ void main() { lokiVar = normalize(lokiVar); vec3 result; - if (outDisableLighting == 1.0) { - result = outColor + 0.25; + + if (outHasTexture == 0) { + if (outDisableLighting == 1.0) { + result = outColor + 0.25; + } else { + result = calculateLighting() * outColor; + } + } else { - result = calculateLighting() * outColor; + if (outDisableLighting == 1.0) { + result = texture(diffuse_texture, outUV.xy).xyz + 0.25; + } else { + result = calculateLighting() * texture(diffuse_texture, outUV.xy).xyz; + } } gl_FragColor = vec4(result, 1.0);