From f11b091fe0701618a89a65b4a703f8741a6a8158 Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Sun, 11 Aug 2019 14:53:15 -0500 Subject: [PATCH] Renamed lighting shader to default, shoehorned in glsl 3.30 support for Intel on Linux, removed duplicate handleGlError methods, added OpenGL and GLU to Object namespace, removed redundant includes for OpenGL and GLU, VBO and VAO now render (all be it incorrectly) --- i-mic-fps.rb | 12 +++- lib/common_methods.rb | 9 +++ lib/constants.rb | 3 + lib/objects/camera.rb | 2 - lib/objects/entity.rb | 10 ---- lib/objects/light.rb | 1 - lib/renderer/bounding_box_renderer.rb | 11 ---- lib/renderer/opengl_renderer.rb | 43 ++++++++------ lib/renderer/renderer.rb | 10 ---- lib/states/game_states/game.rb | 3 - lib/states/game_states/loading_state.rb | 2 +- lib/wavefront/material.rb | 1 - lib/wavefront/model.rb | 74 ++++++++++++++++++++----- shaders/fragment/default.glsl | 10 ++++ shaders/fragment/lighting.glsl | 7 --- shaders/vertex/default.glsl | 24 ++++++++ shaders/vertex/lighting.glsl | 9 --- 17 files changed, 142 insertions(+), 89 deletions(-) create mode 100644 shaders/fragment/default.glsl delete mode 100644 shaders/fragment/lighting.glsl create mode 100644 shaders/vertex/default.glsl delete mode 100644 shaders/vertex/lighting.glsl diff --git a/i-mic-fps.rb b/i-mic-fps.rb index 948d199..4f7dcb1 100644 --- a/i-mic-fps.rb +++ b/i-mic-fps.rb @@ -21,6 +21,12 @@ when :OPENGL_PLATFORM_MACOSX OpenGL.load_lib("libGL.dylib", "/System/Library/Frameworks/OpenGL.framework/Libraries") GLU.load_lib("libGLU.dylib", "/System/Library/Frameworks/OpenGL.framework/Libraries") when :OPENGL_PLATFORM_LINUX + # Black magic to get GLSL 3.30 support on older Intel hardware + if `glxinfo | egrep "OpenGL vendor|OpenGL renderer"`.include?("Intel") + ENV["MESA_GL_VERSION_OVERRIDE"] = "3.3" + ENV["MESA_GLSL_VERSION_OVERRIDE"] = "330" + end + gl_library_path = nil if File.exist?("/usr/lib/x86_64-linux-gnu/libGL.so") # Ubuntu (Debian) @@ -63,6 +69,9 @@ if RUBY_VERSION < "2.5.0" end include CyberarmEngine +include OpenGL +include GLU + require_relative "lib/version" require_relative "lib/constants" require_relative "lib/common_methods" @@ -111,9 +120,6 @@ require_relative "lib/wavefront/model" require_relative "lib/window" -MODEL_METER_SCALE = 1.0 # Objects exported from blender using the default or meter object scale will be close to 1 GL unit - - if ARGV.join.include?("--profile") begin require "ruby-prof" diff --git a/lib/common_methods.rb b/lib/common_methods.rb index e9538be..aafef05 100644 --- a/lib/common_methods.rb +++ b/lib/common_methods.rb @@ -42,5 +42,14 @@ class IMICFPS def fill(color = Gosu::Color::WHITE) draw_rect(0, 0, window.width, window.height, color) end + + def handleGlError + e = glGetError() + if e != GL_NO_ERROR + $stderr.puts "OpenGL error detected by handler at: #{caller[0]}" + $stderr.puts " #{gluErrorString(e)} (#{e})\n" + exit + end + end end end diff --git a/lib/constants.rb b/lib/constants.rb index 0593a0b..d1b5835 100644 --- a/lib/constants.rb +++ b/lib/constants.rb @@ -5,4 +5,7 @@ class IMICFPS Point = Struct.new(:x, :y) Color = Struct.new(:red, :green, :blue, :alpha) Face = Struct.new(:vertices, :uvs, :normals, :colors, :material, :smoothing) + + # Objects exported from blender using the default or meter object scale will be close to 1 GL unit + MODEL_METER_SCALE = 1.0 end \ No newline at end of file diff --git a/lib/objects/camera.rb b/lib/objects/camera.rb index 11e2d96..3272001 100644 --- a/lib/objects/camera.rb +++ b/lib/objects/camera.rb @@ -1,8 +1,6 @@ class IMICFPS class Camera include CommonMethods - include OpenGL - include GLU attr_accessor :field_of_view, :pitch, :yaw, :roll, :mouse_sensitivity attr_reader :entity, :position diff --git a/lib/objects/entity.rb b/lib/objects/entity.rb index 8f3fd2b..386e619 100644 --- a/lib/objects/entity.rb +++ b/lib/objects/entity.rb @@ -3,8 +3,6 @@ class IMICFPS # A game object is any renderable thing class Entity - include OpenGL - include GLU include CommonMethods attr_accessor :scale, :visible, :renderable, :backface_culling @@ -104,13 +102,5 @@ class IMICFPS def normalize_bounding_box @bound_model.model.bounding_box.normalize(self) end - - def handleGlError - e = glGetError() - if e != GL_NO_ERROR - $stderr.puts "OpenGL error in: #{gluErrorString(e)} (#{e})\n" - exit - end - end end end diff --git a/lib/objects/light.rb b/lib/objects/light.rb index 95aa299..a8b366a 100644 --- a/lib/objects/light.rb +++ b/lib/objects/light.rb @@ -1,6 +1,5 @@ class IMICFPS class Light - include OpenGL attr_reader :ambient, :diffuse, :specular, :position, :light_id attr_accessor :x, :y, :z, :intensity def initialize(x:,y:,z:, game_state:, diff --git a/lib/renderer/bounding_box_renderer.rb b/lib/renderer/bounding_box_renderer.rb index 0a26cb4..31d80c2 100644 --- a/lib/renderer/bounding_box_renderer.rb +++ b/lib/renderer/bounding_box_renderer.rb @@ -1,8 +1,5 @@ class IMICFPS class BoundingBoxRenderer - include OpenGL - include GLU - attr_reader :bounding_boxes, :vertex_count def initialize(game_state:) @game_state = game_state @@ -11,14 +8,6 @@ class IMICFPS @vertex_count = 0 end - def handleGlError - e = glGetError() - if e != GL_NO_ERROR - $stderr.puts "OpenGL error in: #{gluErrorString(e)} (#{e})\n" - exit - end - end - def create_bounding_box(object, box, color = nil, mesh_object_id) color ||= object.debug_color diff --git a/lib/renderer/opengl_renderer.rb b/lib/renderer/opengl_renderer.rb index 486c27b..f2c4b83 100644 --- a/lib/renderer/opengl_renderer.rb +++ b/lib/renderer/opengl_renderer.rb @@ -1,19 +1,6 @@ class IMICFPS class OpenGLRenderer include CommonMethods - include OpenGL - include GLU - - def initialize - end - - def handleGlError - e = glGetError() - if e != GL_NO_ERROR - $stderr.puts "OpenGL error in: #{gluErrorString(e)} (#{e})\n" - exit - end - end def draw_object(object) handleGlError @@ -28,12 +15,12 @@ class IMICFPS handleGlError - if Shader.available?("lighting") - Shader.use("lighting") do |shader| - glUniform3f(shader.attribute_location("SunLight"), 1.0, 1.0, 1.0) + if Shader.available?("default") + Shader.use("default") do |shader| + glUniform3f(shader.attribute_location("worldPosition"), object.position.x, object.position.y, object.position.z) handleGlError - draw_mesh(object.model) + draw_model(object.model) object.draw end else @@ -47,6 +34,28 @@ class IMICFPS handleGlError end + def draw_model(model) + glBindVertexArray(model.vertex_array_id) + glBindBuffer(GL_ARRAY_BUFFER, model.vertices_buffer_id) + glEnableVertexAttribArray(0) + glEnableVertexAttribArray(1) + glEnableVertexAttribArray(2) + glEnableVertexAttribArray(3) + glEnableVertexAttribArray(4) + + glDrawArrays(GL_TRIANGLES, 0, model.vertices.count) + window.number_of_vertices+=model.vertices.size + + glDisableVertexAttribArray(4) + glDisableVertexAttribArray(3) + glDisableVertexAttribArray(2) + glDisableVertexAttribArray(1) + glDisableVertexAttribArray(0) + + glBindBuffer(GL_ARRAY_BUFFER, 0) + glBindVertexArray(0) + end + def draw_mesh(model) model.objects.each_with_index do |o, i| glEnable(GL_CULL_FACE) if model.entity.backface_culling diff --git a/lib/renderer/renderer.rb b/lib/renderer/renderer.rb index 83b9c5a..2e19d0c 100644 --- a/lib/renderer/renderer.rb +++ b/lib/renderer/renderer.rb @@ -1,8 +1,6 @@ class IMICFPS class Renderer include CommonMethods - include OpenGL - include GLU attr_reader :opengl_renderer, :bounding_box_renderer @@ -28,14 +26,6 @@ class IMICFPS # @bounding_box_renderer.bounding_boxes.clear end - def handleGlError - e = glGetError() - if e != GL_NO_ERROR - $stderr.puts "OpenGL error in: #{gluErrorString(e)} (#{e})\n" - exit - end - end - def finalize # cleanup end end diff --git a/lib/states/game_states/game.rb b/lib/states/game_states/game.rb index 959817b..bea5025 100644 --- a/lib/states/game_states/game.rb +++ b/lib/states/game_states/game.rb @@ -1,8 +1,5 @@ class IMICFPS class Game < GameState - include OpenGL - include GLU - def setup @collision_manager = CollisionManager.new(game_state: self) @renderer = Renderer.new(game_state: self) diff --git a/lib/states/game_states/loading_state.rb b/lib/states/game_states/loading_state.rb index 3f3cf95..2537f05 100644 --- a/lib/states/game_states/loading_state.rb +++ b/lib/states/game_states/loading_state.rb @@ -15,7 +15,7 @@ class IMICFPS add_asset(:model, "base", "tree") add_asset(:model, "base", "biped") - add_asset(:shader, nil, "lighting") + add_asset(:shader, nil, "default") @act = false @cycled = false diff --git a/lib/wavefront/material.rb b/lib/wavefront/material.rb index c73c7e4..df7e4f1 100644 --- a/lib/wavefront/material.rb +++ b/lib/wavefront/material.rb @@ -1,7 +1,6 @@ class IMICFPS class Wavefront class Material - include OpenGL attr_accessor :name, :ambient, :diffuse, :specular attr_reader :texture_id def initialize(name) diff --git a/lib/wavefront/model.rb b/lib/wavefront/model.rb index dd97cbb..c7eb2ad 100644 --- a/lib/wavefront/model.rb +++ b/lib/wavefront/model.rb @@ -5,7 +5,6 @@ require_relative "material" class IMICFPS class Wavefront class Model - include OpenGL include CommonMethods include Parser @@ -14,8 +13,9 @@ class IMICFPS attr_accessor :scale, :entity attr_reader :position, :bounding_box, :textured_material - attr_reader :vertices_buffer + attr_reader :vertices_buffer_id attr_reader :vertices_buffer_data + attr_reader :vertices_buffer_size attr_reader :vertex_array_id attr_reader :aabb_tree @@ -45,8 +45,8 @@ 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 $debug.get(:stats) allocate_gl_objects - populate_buffers - # populate_arrays + populate_vertex_buffer + configure_vao @objects.each {|o| @vertex_count+=o.vertices.size} @objects.each_with_index do |o, i| @@ -61,7 +61,9 @@ class IMICFPS end end + start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond) build_collision_tree + puts " Building mesh collision tree took #{((Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)-start_time)/1000.0).round(2)} seconds" if $debug.get(:stats) end def allocate_gl_objects @@ -73,15 +75,17 @@ class IMICFPS @vertex_array_id = buffer.unpack('L2').first # Allocate buffers for future use - @vertices_buffer = nil + @vertices_buffer_id = nil buffer = " " * 4 glGenBuffers(1, buffer) - @vertices_buffer = buffer.unpack('L2').first + @vertices_buffer_id = buffer.unpack('L2').first end - def populate_buffers + def populate_vertex_buffer + @vertices_buffer_size = 0 @vertices_buffer_data = [] + model_has_texture = @materials.any? { |id, mat| mat.texture_id != nil } verts = [] colors = [] @@ -93,8 +97,11 @@ class IMICFPS verts << face.vertices.map { |vert| [vert.x, vert.y, vert.z] } colors << face.colors.map { |vert| [vert.x, vert.y, vert.z] } norms << face.normals.map { |vert| [vert.x, vert.y, vert.z, vert.weight] } - uvs << face.uvs.map { |vert| [vert.x, vert.y, vert.z] } if face.material.texture_id - tex_ids << face.material.texture_id if face.material.texture_id + + if model_has_texture + uvs << face.uvs.map { |vert| [vert.x, vert.y, vert.z] } + tex_ids << face.material.texture_id ? face.material.texture_id : -1 + end end verts.each_with_index do |vert, i| @@ -105,18 +112,57 @@ class IMICFPS @vertices_buffer_data << tex_ids[i] if tex_ids.size > 0 end + data_size = 0 + data_size += Fiddle::SIZEOF_FLOAT * 3 * verts.size + data_size += Fiddle::SIZEOF_FLOAT * 3 * colors.size + data_size += Fiddle::SIZEOF_FLOAT * 4 * norms.size + data_size += Fiddle::SIZEOF_FLOAT * 3 * uvs.size + data_size += Fiddle::SIZEOF_INT * 1 * tex_ids.size + + @vertices_buffer_size = data_size + data = @vertices_buffer_data.flatten.pack("f*") - glBindBuffer(GL_ARRAY_BUFFER, @vertices_buffer) - glBufferData(GL_ARRAY_BUFFER, Fiddle::SIZEOF_FLOAT * @vertices_buffer_data.size, data, GL_STATIC_DRAW) + glBindBuffer(GL_ARRAY_BUFFER, @vertices_buffer_id) + glBufferData(GL_ARRAY_BUFFER, @vertices_buffer_size, data, GL_STATIC_DRAW) glBindBuffer(GL_ARRAY_BUFFER, 0) end - def populate_arrays + def configure_vao + glBindBuffer(GL_ARRAY_BUFFER, @vertices_buffer_id) glBindVertexArray(@vertex_array_id) - glBindBuffer(GL_ARRAY_BUFFER, @vertices_buffer) - glBindVertexArray(0) + + glEnableVertexAttribArray(0) + glEnableVertexAttribArray(1) + glEnableVertexAttribArray(2) + glEnableVertexAttribArray(3) + glEnableVertexAttribArray(4) + + # index, size, type, normalized, stride, pointer + # vertices (positions) + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, Fiddle::SIZEOF_FLOAT * 3, nil) + handleGlError + # colors + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, Fiddle::SIZEOF_FLOAT * (3 + 3), nil) + handleGlError + # normals + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, Fiddle::SIZEOF_FLOAT * (4 + 3 + 3), nil) + handleGlError + # uvs + glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, Fiddle::SIZEOF_FLOAT * (3 + 4 + 3 + 3), nil) + handleGlError + # texture ids + glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, Fiddle::SIZEOF_FLOAT + (Fiddle::SIZEOF_FLOAT * (3 + 4 + 3 + 3)), nil) + handleGlError + + glDisableVertexAttribArray(4) + glDisableVertexAttribArray(3) + glDisableVertexAttribArray(2) + glDisableVertexAttribArray(1) + glDisableVertexAttribArray(0) + glBindBuffer(GL_ARRAY_BUFFER, 0) + glBindVertexArray(0) end def build_collision_tree diff --git a/shaders/fragment/default.glsl b/shaders/fragment/default.glsl new file mode 100644 index 0000000..f6627bc --- /dev/null +++ b/shaders/fragment/default.glsl @@ -0,0 +1,10 @@ +# version 330 + +in vec3 outColor; +in vec4 outNormal; +in vec3 outUV; +in float outTextureID; + +void main() { + gl_FragColor = vec4(outColor, 1.0); +} \ No newline at end of file diff --git a/shaders/fragment/lighting.glsl b/shaders/fragment/lighting.glsl deleted file mode 100644 index e8569e0..0000000 --- a/shaders/fragment/lighting.glsl +++ /dev/null @@ -1,7 +0,0 @@ -# version 150 - -out vec4 frag_colour; - -void main() { - frag_colour = vec4(0.5, 0.0, 0.5, 1.0); -} \ No newline at end of file diff --git a/shaders/vertex/default.glsl b/shaders/vertex/default.glsl new file mode 100644 index 0000000..d81d831 --- /dev/null +++ b/shaders/vertex/default.glsl @@ -0,0 +1,24 @@ +# version 330 + +layout(location = 0) in vec3 inPosition; +layout(location = 1) in vec3 inColor; +layout(location = 2) in vec4 inNormal; +layout(location = 3) in vec3 inUV; +layout(location = 4) in float inTextureID; + +out vec3 outColor; +out vec4 outNormal; +out vec3 outUV; +out float outTextureID; + +uniform vec3 worldPosition; + +void main() { + // projection * view * model * + outColor = inColor; + outNormal= inNormal; + outUV = inUV; + outTextureID = inTextureID; + + gl_Position = vec4(worldPosition + inPosition, 1.0); +} \ No newline at end of file diff --git a/shaders/vertex/lighting.glsl b/shaders/vertex/lighting.glsl deleted file mode 100644 index 2af6e81..0000000 --- a/shaders/vertex/lighting.glsl +++ /dev/null @@ -1,9 +0,0 @@ -# version 330 - -layout(location = 0) in vec3 vert; -uniform vec3 position; - -void main() { - // projection * view * model * - gl_Position = vec4(vert+position, 1.0); -} \ No newline at end of file