From 67b06b0001afb9246ba8f93d6e3c7ce8f0f97164 Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Mon, 30 Jul 2018 12:52:35 -0500 Subject: [PATCH] Bounding boxes are now drawn using Vertex arrays --- Gemfile.lock | 4 +- lib/objects/camera.rb | 9 +- lib/objects/game_object.rb | 213 +++++++++++++++++++++++---------- lib/objects/multi_line_text.rb | 1 - lib/objects/player.rb | 8 +- lib/objects/terrain.rb | 10 +- lib/window.rb | 28 ++++- 7 files changed, 195 insertions(+), 78 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index e3308f8..6304bf4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,8 +1,8 @@ GEM remote: https://rubygems.org/ specs: - glu (8.3.0) - glu (8.3.0-x86-mingw32) + glu (8.2.2) + glu (8.2.2-x86-mingw32) gosu (0.13.3) gosu (0.13.3-x86-mingw32) opengl-bindings (1.6.6) diff --git a/lib/objects/camera.rb b/lib/objects/camera.rb index 63de877..a34f2ed 100644 --- a/lib/objects/camera.rb +++ b/lib/objects/camera.rb @@ -74,9 +74,16 @@ class IMICFPS glRotatef(@render_pitch,1,0,0) glRotatef(@yaw,0,1,0) glTranslatef(-@x, -@y, -@z) - glMatrixMode(GL_MODELVIEW) # The modelview matrix is where object information is stored. glLoadIdentity + + if $debug && @game_object + glBegin(GL_LINES) + glColor3f(1,0,0) + glVertex3f(@x, @y, @z) + glVertex3f(@game_object.x, @game_object.y, @game_object.z) + glEnd + end end def update diff --git a/lib/objects/game_object.rb b/lib/objects/game_object.rb index 308d164..e74fc45 100644 --- a/lib/objects/game_object.rb +++ b/lib/objects/game_object.rb @@ -4,6 +4,7 @@ class IMICFPS # A game object is any renderable thing class GameObject include OpenGL + include GLU include CommonMethods attr_accessor :x, :y, :z, :scale attr_accessor :visible, :renderable, :backface_culling @@ -110,73 +111,159 @@ class IMICFPS end def render_bounding_box(box, color = @debug_color) - # TODO: Minimize number of calls in here box = normalize_bounding_box(box) + glEnableClientState(GL_VERTEX_ARRAY) + glEnableClientState(GL_COLOR_ARRAY) + glEnableClientState(GL_NORMAL_ARRAY) + + _normals = [ + 0,1,0, + 0,1,0, + 0,1,0, + 0,1,0, + 0,1,0, + 0,1,0, + + 0,-1,0, + 0,-1,0, + 0,-1,0, + 0,-1,0, + 0,-1,0, + 0,-1,0, + + 0,0,1, + 0,0,1, + 0,0,1, + 0,0,1, + 0,0,1, + 0,0,1, + + 1,0,0, + 1,0,0, + 1,0,0, + 1,0,0, + 1,0,0, + 1,0,0, + + -1,0,0, + -1,0,0, + -1,0,0, + -1,0,0, + -1,0,0, + -1,0,0, + + -1,0,0, + -1,0,0, + -1,0,0, + + -1,0,0, + -1,0,0, + -1,0,0 + ].pack("f*") + _colors = [ + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue, + color.red, color.green, color.blue + ].pack("f*") + _vertices = [ + box.min_x, box.max_y, box.max_z, + box.min_x, box.max_y, box.min_z, + box.max_x, box.max_y, box.min_z, + + box.min_x, box.max_y, box.max_z, + box.max_x, box.max_y, box.max_z, + box.max_x, box.max_y, box.min_z, + + box.max_x, box.min_y, box.min_z, + box.max_x, box.min_y, box.max_z, + box.min_x, box.min_y, box.max_z, + + box.max_x, box.min_y, box.min_z, + box.min_x, box.min_y, box.min_z, + box.min_x, box.min_y, box.max_z, + + box.min_x, box.max_y, box.max_z, + box.min_x, box.max_y, box.min_z, + box.min_x, box.min_y, box.min_z, + + box.min_x, box.min_y, box.max_z, + box.min_x, box.min_y, box.min_z, + box.min_x, box.max_y, box.max_z, + + box.max_x, box.max_y, box.max_z, + box.max_x, box.max_y, box.min_z, + box.max_x, box.min_y, box.min_z, + + box.max_x, box.min_y, box.max_z, + box.max_x, box.min_y, box.min_z, + box.max_x, box.max_y, box.max_z, + + box.min_x, box.max_y, box.max_z, + box.max_x, box.max_y, box.max_z, + box.max_x, box.min_y, box.max_z, + + box.min_x, box.max_y, box.max_z, + box.max_x, box.min_y, box.max_z, + box.min_x, box.min_y, box.max_z, + + box.max_x, box.min_y, box.min_z, + box.min_x, box.min_y, box.min_z, + box.min_x, box.max_y, box.min_z, + + box.max_x, box.min_y, box.min_z, + box.min_x, box.max_y, box.min_z, + box.max_x, box.max_y, box.min_z + ] + _vertices_size = _vertices.size + _vertices = _vertices.pack("f*") + + glVertexPointer(3, GL_FLOAT, 0, _vertices) + glColorPointer(3, GL_FLOAT, 0, _colors) + glNormalPointer(GL_FLOAT, 0, _normals) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) - glBegin(GL_TRIANGLES) - # TOP - glNormal3f(0,1,0) - glColor3f(color.red, color.green, color.blue) - glVertex3f(box.min_x, box.max_y, box.max_z) - glVertex3f(box.min_x, box.max_y, box.min_z) - glVertex3f(box.max_x, box.max_y, box.min_z) - - glVertex3f(box.min_x, box.max_y, box.max_z) - glVertex3f(box.max_x, box.max_y, box.max_z) - glVertex3f(box.max_x, box.max_y, box.min_z) - - # BOTTOM - glNormal3f(0,-1,0) - glVertex3f(box.max_x, box.min_y, box.min_z) - glVertex3f(box.max_x, box.min_y, box.max_z) - glVertex3f(box.min_x, box.min_y, box.max_z) - - glVertex3f(box.max_x, box.min_y, box.min_z) - glVertex3f(box.min_x, box.min_y, box.min_z) - glVertex3f(box.min_x, box.min_y, box.max_z) - - # RIGHT SIDE - glNormal3f(0,0,1) - glVertex3f(box.min_x, box.max_y, box.max_z) - glVertex3f(box.min_x, box.max_y, box.min_z) - glVertex3f(box.min_x, box.min_y, box.min_z) - - glVertex3f(box.min_x, box.min_y, box.max_z) - glVertex3f(box.min_x, box.min_y, box.min_z) - glVertex3f(box.min_x, box.max_y, box.max_z) - - # LEFT SIDE - glNormal3f(1,0,0) - glVertex3f(box.max_x, box.max_y, box.max_z) - glVertex3f(box.max_x, box.max_y, box.min_z) - glVertex3f(box.max_x, box.min_y, box.min_z) - - glVertex3f(box.max_x, box.min_y, box.max_z) - glVertex3f(box.max_x, box.min_y, box.min_z) - glVertex3f(box.max_x, box.max_y, box.max_z) - - # FRONT - glNormal3f(-1,0,0) - glVertex3f(box.min_x, box.max_y, box.max_z) - glVertex3f(box.max_x, box.max_y, box.max_z) - glVertex3f(box.max_x, box.min_y, box.max_z) - - glVertex3f(box.min_x, box.max_y, box.max_z) - glVertex3f(box.max_x, box.min_y, box.max_z) - glVertex3f(box.min_x, box.min_y, box.max_z) - - # BACK - glNormal3f(-1,0,0) - glVertex3f(box.max_x, box.min_y, box.min_z) - glVertex3f(box.min_x, box.min_y, box.min_z) - glVertex3f(box.min_x, box.max_y, box.min_z) - - glVertex3f(box.max_x, box.min_y, box.min_z) - glVertex3f(box.min_x, box.max_y, box.min_z) - glVertex3f(box.max_x, box.max_y, box.min_z) - glEnd + glDisable(GL_LIGHTING) + glDrawArrays(GL_TRIANGLES, 0, _vertices_size/3) + glEnable(GL_LIGHTING) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) + + glDisableClientState(GL_VERTEX_ARRAY) + glDisableClientState(GL_COLOR_ARRAY) + glDisableClientState(GL_NORMAL_ARRAY) end def handleGlError diff --git a/lib/objects/multi_line_text.rb b/lib/objects/multi_line_text.rb index e997d50..b610ab0 100644 --- a/lib/objects/multi_line_text.rb +++ b/lib/objects/multi_line_text.rb @@ -45,7 +45,6 @@ class MultiLineText def y=(int) @y = int - puts "Hi, #{int}" @texts.each_with_index {|t, i| t.y=int+(i*t.size)} end diff --git a/lib/objects/player.rb b/lib/objects/player.rb index 2355983..40a3c44 100644 --- a/lib/objects/player.rb +++ b/lib/objects/player.rb @@ -48,7 +48,7 @@ class IMICFPS glEnable(GL_BLEND) glBindTexture(GL_TEXTURE_2D, @name_texture_id) glBegin(GL_TRIANGLES) - # glColor3f(0.0,0.0,0.0) + glColor3f(1.0,1.0,1.0) # TOP LEFT glTexCoord2f(0, 0) glVertex3f(_x-_width,_y+_height,@z) @@ -81,15 +81,15 @@ class IMICFPS def draw if !@first_person_view - draw_nameplate super + draw_nameplate end end def update super - @floor = @terrain.height_at(self) + @floor = @terrain.height_at(self, 4.5) relative_speed = @speed if button_down?(Gosu::KbLeftControl) @@ -141,7 +141,7 @@ class IMICFPS end if @jumping && !@falling if button_down?(Gosu::KbSpace) - @y_velocity+=(2*5)*delta_time + @y_velocity+=(2*15)*delta_time @falling = true if @y_velocity >= 2 end end diff --git a/lib/objects/terrain.rb b/lib/objects/terrain.rb index f5bb70b..31bf1b1 100644 --- a/lib/objects/terrain.rb +++ b/lib/objects/terrain.rb @@ -22,15 +22,15 @@ class IMICFPS p model.faces.first end - def height_at(vertex) - if vert = find_nearest_vertex(vertex) + def height_at(vertex, max_distance = Float::INFINITY) + if vert = find_nearest_vertex(vertex, max_distance) return vert.y else -1 end end - def find_nearest_vertex(vertex) + def find_nearest_vertex(vertex, max_distance) nearest = nil smaller_list = [] smaller_list << @nearest_vertex_lookup.dig(vertex.x.round-1, vertex.y.round-1) @@ -41,12 +41,12 @@ class IMICFPS smaller_list.each do |vert| next if vert.nil? if nearest - if distance(vert, vertex) < distance(vert, nearest) + if distance(vert, vertex) < distance(vert, nearest) && distance(vert, vertex) <= max_distance nearest = vert end end - nearest = vert unless nearest + nearest = vert unless nearest && distance(vert, vertex) > max_distance end return nearest diff --git a/lib/window.rb b/lib/window.rb index 559ba78..623ac7d 100644 --- a/lib/window.rb +++ b/lib/window.rb @@ -31,7 +31,7 @@ class IMICFPS # Tree.new(x: 1, z: -5, terrain: @terrain) # Tree.new(x: 5, z: 5, terrain: @terrain) # TestObject.new(scale: 1) - p ObjectManager.objects.map {|o| o.name} + # p ObjectManager.objects.map {|o| o.name} # Model.new(type: :obj, file_path: "objects/tree.obj", z: -5) # Model.new(type: :obj, file_path: "objects/tree.obj", x: -2, z: -6) # Model.new(type: :obj, file_path: "objects/sponza.obj", scale: 1, y: -0.2) @@ -51,16 +51,23 @@ class IMICFPS Light.new(x: 0, y: 100, z: 0, diffuse: Color.new(1.0, 0.5, 0.1)) end - def draw + def glError? e = glGetError() if e != GL_NO_ERROR $stderr.puts "OpenGL error in: #{gluErrorString(e)} (#{e})\n" exit end + end + + def draw + glError? gl do + glError? glClearColor(0,0.2,0.5,1) # skyish blue + glError? glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # clear the screen and the depth buffer + glError? LightManager.lights.each(&:draw) @@ -82,6 +89,7 @@ class IMICFPS def update @last_frame_time = Gosu.milliseconds + begin string = <<-eos OpenGL Vendor: #{glGetString(GL_VENDOR)} OpenGL Renderer: #{glGetString(GL_RENDERER)} @@ -99,6 +107,22 @@ Last Frame: #{delta_time*1000.0}ms (#{Gosu.fps} fps) Draw Skydome: #{@draw_skydome} Debug mode: #{$debug} eos + rescue ArgumentError + string = <<-eos +Unable to call glGetString! + +Camera pitch: #{@camera.pitch.round(2)} Yaw: #{@camera.yaw.round(2)} Roll #{@camera.roll.round(2)} +Camera X:#{@camera.x.round(2)} Y:#{@camera.y.round(2)} Z:#{@camera.z.round(2)} +#{if @camera.game_object then "Actor X:#{@camera.game_object.x.round(2)} Y:#{@camera.game_object.y.round(2)} Z:#{@camera.game_object.z.round(2)}";end} +Field Of View: #{@camera.field_of_view} +Mouse Sesitivity: #{@camera.mouse_sensitivity} +Faces: #{@number_of_faces} +Last Frame: #{delta_time*1000.0}ms (#{Gosu.fps} fps) + +Draw Skydome: #{@draw_skydome} +Debug mode: #{$debug} +eos + end @text.text = string # ObjectManager.objects.each do |object|