Modern 'GL now renders properly, camera works as expected, added fallback to immediate mode if shader fails to compile.

This commit is contained in:
2019-12-08 17:50:20 -06:00
parent e076ce8612
commit af19166af2
9 changed files with 68 additions and 67 deletions

View File

@@ -1,5 +1,5 @@
source "https://rubygems.org"
gem "opengl-bindings"
gem "opengl-bindings", require: "opengl"
gem "cyberarm_engine"
group(:packaging) do

View File

@@ -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

View File

@@ -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

View File

@@ -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)
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,6 +176,8 @@ class IMICFPS
glBindBuffer(GL_ARRAY_BUFFER, @normals_buffer_id)
glVertexAttribPointer(glGetAttribLocation(program, "inNormal"), 4, GL_FLOAT, GL_FALSE, 0, nil)
handleGlError
if has_texture?
# uvs
glBindBuffer(GL_ARRAY_BUFFER, @uvs_buffer_id)
glVertexAttribPointer(glGetAttribLocation(program, "inUV"), 3, GL_FLOAT, GL_FALSE, 0, nil)
@@ -188,12 +186,7 @@ class IMICFPS
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)
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

View File

@@ -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)
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
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)

View File

@@ -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

View File

@@ -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 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}
Field Of View: #{@camera.field_of_view}
Mouse Sesitivity: #{@camera.mouse_sensitivity}
Last Frame: #{Gosu.milliseconds - window.delta_time}ms (#{Gosu.fps} fps)
Vertices: #{formatted_number(window.number_of_vertices)}

View File

@@ -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);
}

View File

@@ -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);
}