mirror of
https://github.com/cyberarm/i-mic-fps.git
synced 2025-12-15 15:42:35 +00:00
Modern 'GL now renders properly, camera works as expected, added fallback to immediate mode if shader fails to compile.
This commit is contained in:
2
Gemfile
2
Gemfile
@@ -1,5 +1,5 @@
|
||||
source "https://rubygems.org"
|
||||
gem "opengl-bindings"
|
||||
gem "opengl-bindings", require: "opengl"
|
||||
gem "cyberarm_engine"
|
||||
|
||||
group(:packaging) do
|
||||
|
||||
@@ -72,7 +72,7 @@ class IMICFPS
|
||||
# Calculates aspect ratio of the window. Gets perspective view. 45 is degree viewing angle, (0.1, 100) are ranges how deep can we draw into the screen
|
||||
gluPerspective(@field_of_view, window.width / window.height, 0.1, @max_view_distance)
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
|
||||
glRotatef(@orientation.z, 1, 0, 0)
|
||||
glRotatef(@orientation.x, 1, 0, 0)
|
||||
glRotatef(@orientation.y, 0, 1, 0)
|
||||
glTranslatef(-@position.x, -@position.y, -@position.z)
|
||||
glMatrixMode(GL_MODELVIEW) # The modelview matrix is where object information is stored.
|
||||
@@ -87,8 +87,8 @@ class IMICFPS
|
||||
@orientation.y -= delta
|
||||
@orientation.y %= 360.0
|
||||
|
||||
@orientation.z -= Float(@true_mouse.y - self.mouse_y) / (@mouse_sensitivity * @field_of_view) * 70
|
||||
@orientation.z = @orientation.z.clamp(-90.0, 90.0)
|
||||
@orientation.x -= Float(@true_mouse.y - self.mouse_y) / (@mouse_sensitivity * @field_of_view) * 70
|
||||
@orientation.x = @orientation.x.clamp(-90.0, 90.0)
|
||||
|
||||
if @entity
|
||||
@entity.orientation.y += delta
|
||||
@@ -170,27 +170,15 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def aspect_ratio
|
||||
window.width / window.height
|
||||
window.width / window.height.to_f
|
||||
end
|
||||
|
||||
def projection_matrix
|
||||
fov = 1 / Math.tan(@field_of_view / 2) # field of view
|
||||
zn = @max_view_distance - @min_view_distance # near plane
|
||||
zf = @max_view_distance + @min_view_distance # far plane
|
||||
z_num = -(2 * @max_view_distance * @min_view_distance) / zn # something
|
||||
|
||||
Transform.new(
|
||||
[
|
||||
fov / aspect_ratio, 0, 0, 0,
|
||||
0, fov, 0, 0,
|
||||
0, 0, -zf / zn, z_num,
|
||||
0, 0, -1, 0
|
||||
]
|
||||
)
|
||||
Transform.perspective(@field_of_view, aspect_ratio, @min_view_distance, @max_view_distance)
|
||||
end
|
||||
|
||||
def view_matrix
|
||||
Transform.identity# Transform.rotate_3d(@orientation) * Transform.translate_3d(@position)
|
||||
Transform.translate_3d(@position * -1) * Transform.rotate_3d(@orientation)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -119,7 +119,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def model_matrix
|
||||
Transform.rotate_3d(@orientation) * Transform.translate_3d(@position)
|
||||
Transform.rotate_3d(@orientation) * Transform.scale_3d(@scale) * Transform.translate_3d(@position)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
57
lib/model.rb
57
lib/model.rb
@@ -35,9 +35,11 @@ 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_vertex_buffer
|
||||
configure_vao
|
||||
if Shader.available?("default")
|
||||
allocate_gl_objects
|
||||
populate_vertex_buffer
|
||||
configure_vao
|
||||
end
|
||||
|
||||
@objects.each {|o| @vertex_count+=o.vertices.size}
|
||||
@objects.each_with_index do |o, i|
|
||||
@@ -119,14 +121,14 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def populate_vertex_buffer
|
||||
verts = []
|
||||
pos = []
|
||||
colors = []
|
||||
norms = []
|
||||
uvs = []
|
||||
tex_ids = []
|
||||
|
||||
@faces.each do |face|
|
||||
verts << face.vertices.map { |vert| [vert.x, vert.y, vert.z] }
|
||||
pos << 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] }
|
||||
|
||||
@@ -137,20 +139,20 @@ class IMICFPS
|
||||
end
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, @positions_buffer_id)
|
||||
glBufferData(GL_ARRAY_BUFFER, 3 * verts.size * Fiddle::SIZEOF_FLOAT, verts.flatten.pack("f*"), GL_STATIC_DRAW)
|
||||
glBufferData(GL_ARRAY_BUFFER, pos.flatten.size * Fiddle::SIZEOF_FLOAT, pos.flatten.pack("f*"), GL_STATIC_DRAW)
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, @colors_buffer_id)
|
||||
glBufferData(GL_ARRAY_BUFFER, 3 * colors.size * Fiddle::SIZEOF_FLOAT, colors.flatten.pack("f*"), GL_STATIC_DRAW)
|
||||
glBufferData(GL_ARRAY_BUFFER, colors.flatten.size * Fiddle::SIZEOF_FLOAT, colors.flatten.pack("f*"), GL_STATIC_DRAW)
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, @normals_buffer_id)
|
||||
glBufferData(GL_ARRAY_BUFFER, 4 * norms.size * Fiddle::SIZEOF_FLOAT, norms.flatten.pack("f*"), GL_STATIC_DRAW)
|
||||
glBufferData(GL_ARRAY_BUFFER, norms.flatten.size * Fiddle::SIZEOF_FLOAT, norms.flatten.pack("f*"), GL_STATIC_DRAW)
|
||||
|
||||
if has_texture?
|
||||
glBindBuffer(GL_ARRAY_BUFFER, @uvs_buffer_id)
|
||||
glBufferData(GL_ARRAY_BUFFER, 3 * uvs.size * Fiddle::SIZEOF_FLOAT, uvs.flatten.pack("f*"), GL_STATIC_DRAW)
|
||||
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, 1 * tex_ids.size * Fiddle::SIZEOF_FLOAT, tex_ids.flatten.pack("f*"), GL_STATIC_DRAW)
|
||||
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)
|
||||
@@ -159,12 +161,6 @@ class IMICFPS
|
||||
def configure_vao
|
||||
glBindVertexArray(@vertex_array_id)
|
||||
|
||||
glEnableVertexAttribArray(0)
|
||||
glEnableVertexAttribArray(1)
|
||||
glEnableVertexAttribArray(2)
|
||||
glEnableVertexAttribArray(3)
|
||||
glEnableVertexAttribArray(4)
|
||||
|
||||
program = Shader.get("default").program
|
||||
|
||||
# index, size, type, normalized, stride, pointer
|
||||
@@ -180,20 +176,17 @@ class IMICFPS
|
||||
glBindBuffer(GL_ARRAY_BUFFER, @normals_buffer_id)
|
||||
glVertexAttribPointer(glGetAttribLocation(program, "inNormal"), 4, GL_FLOAT, GL_FALSE, 0, nil)
|
||||
handleGlError
|
||||
# uvs
|
||||
glBindBuffer(GL_ARRAY_BUFFER, @uvs_buffer_id)
|
||||
glVertexAttribPointer(glGetAttribLocation(program, "inUV"), 3, GL_FLOAT, GL_FALSE, 0, nil)
|
||||
handleGlError
|
||||
# texture ids
|
||||
glBindBuffer(GL_ARRAY_BUFFER, @textures_buffer_id)
|
||||
glVertexAttribPointer(glGetAttribLocation(program, "inTextureID"), 1, GL_FLOAT, GL_FALSE, 0, nil)
|
||||
handleGlError
|
||||
|
||||
glDisableVertexAttribArray(4)
|
||||
glDisableVertexAttribArray(3)
|
||||
glDisableVertexAttribArray(2)
|
||||
glDisableVertexAttribArray(1)
|
||||
glDisableVertexAttribArray(0)
|
||||
if has_texture?
|
||||
# uvs
|
||||
glBindBuffer(GL_ARRAY_BUFFER, @uvs_buffer_id)
|
||||
glVertexAttribPointer(glGetAttribLocation(program, "inUV"), 3, GL_FLOAT, GL_FALSE, 0, nil)
|
||||
handleGlError
|
||||
# texture ids
|
||||
glBindBuffer(GL_ARRAY_BUFFER, @textures_buffer_id)
|
||||
glVertexAttribPointer(glGetAttribLocation(program, "inTextureID"), 1, GL_FLOAT, GL_FALSE, 0, nil)
|
||||
handleGlError
|
||||
end
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||
glBindVertexArray(0)
|
||||
@@ -201,6 +194,7 @@ class IMICFPS
|
||||
|
||||
def build_collision_tree
|
||||
@aabb_tree = AABBTree.new
|
||||
|
||||
@faces.each do |face|
|
||||
box = BoundingBox.new
|
||||
box.min = face.vertices.first.dup
|
||||
@@ -215,10 +209,11 @@ class IMICFPS
|
||||
end
|
||||
|
||||
# FIXME: Handle negatives
|
||||
box.min -= Vector.new(-0.1, -0.1, -0.1)
|
||||
box.max += Vector.new( 0.1, 0.1, 0.1)
|
||||
box.min *= 1.5
|
||||
box.max *= 1.5
|
||||
@aabb_tree.insert(face, box)
|
||||
end
|
||||
|
||||
puts @aabb_tree.inspect if $debug.get(:stats)
|
||||
end
|
||||
|
||||
|
||||
@@ -2,12 +2,17 @@ class IMICFPS
|
||||
class OpenGLRenderer
|
||||
include CommonMethods
|
||||
|
||||
def initialize
|
||||
@immediate_mode_warning = false
|
||||
end
|
||||
|
||||
def draw_object(camera, lights, object)
|
||||
if Shader.available?("default")
|
||||
Shader.use("default") do |shader|
|
||||
shader.set_uniform("projection", camera.projection_matrix)
|
||||
shader.set_uniform("view", camera.view_matrix)
|
||||
shader.set_uniform("model", object.model_matrix)
|
||||
shader.set_uniform("hasTexture", object.model.has_texture?)
|
||||
|
||||
# TODO: Upload and use lights
|
||||
|
||||
@@ -16,10 +21,12 @@ 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
|
||||
|
||||
handleGlError
|
||||
lights.each(&:draw)
|
||||
camera.draw
|
||||
glEnable(GL_DEPTH_TEST)
|
||||
|
||||
glEnable(GL_NORMALIZE)
|
||||
glPushMatrix
|
||||
@@ -44,14 +51,18 @@ class IMICFPS
|
||||
glEnableVertexAttribArray(0)
|
||||
glEnableVertexAttribArray(1)
|
||||
glEnableVertexAttribArray(2)
|
||||
glEnableVertexAttribArray(3)
|
||||
glEnableVertexAttribArray(4)
|
||||
if model.has_texture?
|
||||
glEnableVertexAttribArray(3)
|
||||
glEnableVertexAttribArray(4)
|
||||
end
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, model.vertices.count)
|
||||
window.number_of_vertices+=model.vertices.size
|
||||
glDrawArrays(GL_TRIANGLES, 0, model.faces.count * 3)
|
||||
window.number_of_vertices += model.faces.count * 3
|
||||
|
||||
glDisableVertexAttribArray(4)
|
||||
glDisableVertexAttribArray(3)
|
||||
if model.has_texture?
|
||||
glDisableVertexAttribArray(4)
|
||||
glDisableVertexAttribArray(3)
|
||||
end
|
||||
glDisableVertexAttribArray(2)
|
||||
glDisableVertexAttribArray(1)
|
||||
glDisableVertexAttribArray(0)
|
||||
@@ -80,9 +91,6 @@ class IMICFPS
|
||||
glColorPointer(3, GL_FLOAT, 0, o.flattened_materials)
|
||||
glNormalPointer(GL_FLOAT, 0, o.flattened_normals)
|
||||
|
||||
# glBindBuffer(GL_ARRAY_BUFFER, model.vertices_buffer)
|
||||
# glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0)
|
||||
|
||||
if $debug.get(:wireframe) # This is kinda expensive
|
||||
glDisable(GL_LIGHTING)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
|
||||
|
||||
@@ -10,6 +10,9 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def draw(camera, lights, entities)
|
||||
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
|
||||
|
||||
@@ -61,11 +61,12 @@ OpenGL Renderer: #{glGetString(GL_RENDERER)}
|
||||
OpenGL Version: #{glGetString(GL_VERSION)}
|
||||
OpenGL Shader Language Version: #{glGetString(GL_SHADING_LANGUAGE_VERSION)}
|
||||
|
||||
Camera pitch: #{@camera.orientation.z.round(2)} Yaw: #{@camera.orientation.y.round(2)} Roll #{@camera.orientation.x.round(2)}
|
||||
Camera X:#{@camera.position.x.round(2)} Y:#{@camera.position.y.round(2)} Z:#{@camera.position.z.round(2)}
|
||||
#{if @camera.entity then "Actor X:#{@camera.entity.position.x.round(2)} Y:#{@camera.entity.position.y.round(2)} Z:#{@camera.entity.position.z.round(2)}";end}
|
||||
Field Of View: #{@camera.field_of_view}
|
||||
Mouse Sesitivity: #{@camera.mouse_sensitivity}
|
||||
Camera Pitch: #{@camera.orientation.x.round(2)} Yaw: #{@camera.orientation.y.round(2)} Roll #{@camera.orientation.z.round(2)}
|
||||
Camera X: #{@camera.position.x.round(2)} Y: #{@camera.position.y.round(2)} Z: #{@camera.position.z.round(2)}
|
||||
Camera Field Of View: #{@camera.field_of_view}
|
||||
Camera Mouse Sesitivity: #{@camera.mouse_sensitivity}
|
||||
|
||||
#{if @camera.entity then "Actor X: #{@camera.entity.position.x.round(2)} Y: #{@camera.entity.position.y.round(2)} Z: #{@camera.entity.position.z.round(2)}";end}
|
||||
Last Frame: #{Gosu.milliseconds - window.delta_time}ms (#{Gosu.fps} fps)
|
||||
|
||||
Vertices: #{formatted_number(window.number_of_vertices)}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# version 330 core
|
||||
|
||||
in vec3 outPosition;
|
||||
in vec3 outColor;
|
||||
in vec4 outNormal;
|
||||
in vec3 outUV;
|
||||
@@ -11,5 +12,5 @@ vec4 lokiVar;
|
||||
void main() {
|
||||
lokiVar = vec4(outColor, 1.0) + outNormal + vec4(outUV, 1.0) + vec4(outTextureID, 1.0, 1.0, 1.0);
|
||||
lokiVar = normalize(lokiVar);
|
||||
gl_FragColor = vec4(lokiVar);
|
||||
gl_FragColor = vec4(outColor, 1.0);
|
||||
}
|
||||
@@ -6,21 +6,26 @@ layout(location = 2) in vec4 inNormal;
|
||||
layout(location = 3) in vec3 inUV;
|
||||
layout(location = 4) in float inTextureID;
|
||||
|
||||
out vec3 outPosition;
|
||||
out vec3 outColor;
|
||||
out vec4 outNormal;
|
||||
out vec3 outUV;
|
||||
out float outTextureID;
|
||||
out float outHasTexture;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
uniform mat4 model;
|
||||
uniform int hasTexture;
|
||||
|
||||
void main() {
|
||||
// projection * view * model * position
|
||||
outPosition = inPosition;
|
||||
outColor = inColor;
|
||||
outNormal= inNormal;
|
||||
outUV = inUV;
|
||||
outTextureID = inTextureID;
|
||||
outHasTexture = hasTexture;
|
||||
|
||||
gl_Position = projection * view * model * vec4(inPosition, 1.0);
|
||||
}
|
||||
Reference in New Issue
Block a user