mirror of
https://github.com/cyberarm/cyberarm_engine.git
synced 2025-12-18 22:02:34 +00:00
Added a large portion of I-MIC-FPS's opengl rendering and model loading systems
This commit is contained in:
248
lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb
Normal file
248
lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb
Normal file
@@ -0,0 +1,248 @@
|
||||
module CyberarmEngine
|
||||
class BoundingBoxRenderer
|
||||
attr_reader :bounding_boxes, :vertex_count
|
||||
def initialize
|
||||
@bounding_boxes = {}
|
||||
@vertex_count = 0
|
||||
end
|
||||
|
||||
def render(entities)
|
||||
entities.each do |entity|
|
||||
create_bounding_box(entity,color = nil)
|
||||
draw_bounding_boxes
|
||||
end
|
||||
|
||||
(@bounding_boxes.keys - entities.map { |e| e.object_id }).each do |key|
|
||||
@bounding_boxes.delete(key)
|
||||
end
|
||||
end
|
||||
|
||||
def create_bounding_box(entity, color = nil)
|
||||
color ||= entity.debug_color
|
||||
entity_id = entity.object_id
|
||||
|
||||
if @bounding_boxes[entity_id]
|
||||
if @bounding_boxes[entity_id][:color] != color
|
||||
@bounding_boxes[entity_id][:colors] = mesh_colors(color).pack("f*")
|
||||
@bounding_boxes[entity_id][:color] = color
|
||||
return
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
@bounding_boxes[entity_id] = {
|
||||
entity: entity,
|
||||
color: color,
|
||||
objects: []
|
||||
}
|
||||
|
||||
box = entity.normalize_bounding_box
|
||||
|
||||
normals = mesh_normals
|
||||
colors = mesh_colors(color)
|
||||
vertices = mesh_vertices(box)
|
||||
|
||||
@vertex_count+=vertices.size
|
||||
|
||||
@bounding_boxes[entity_id][:vertices_size] = vertices.size
|
||||
@bounding_boxes[entity_id][:vertices] = vertices.pack("f*")
|
||||
@bounding_boxes[entity_id][:normals] = normals.pack("f*")
|
||||
@bounding_boxes[entity_id][:colors] = colors.pack("f*")
|
||||
|
||||
entity.model.objects.each do |mesh|
|
||||
data = {}
|
||||
box = mesh.bounding_box.normalize(entity)
|
||||
|
||||
normals = mesh_normals
|
||||
colors = mesh_colors(mesh.debug_color)
|
||||
vertices = mesh_vertices(box)
|
||||
|
||||
@vertex_count+=vertices.size
|
||||
|
||||
data[:vertices_size] = vertices.size
|
||||
data[:vertices] = vertices.pack("f*")
|
||||
data[:normals] = normals.pack("f*")
|
||||
data[:colors] = colors.pack("f*")
|
||||
|
||||
@bounding_boxes[entity_id][:objects] << data
|
||||
end
|
||||
end
|
||||
|
||||
def mesh_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
|
||||
]
|
||||
end
|
||||
|
||||
def mesh_colors(color)
|
||||
[
|
||||
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
|
||||
]
|
||||
end
|
||||
|
||||
def mesh_vertices(box)
|
||||
[
|
||||
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
|
||||
]
|
||||
end
|
||||
|
||||
def draw_bounding_boxes
|
||||
@bounding_boxes.each do |key, bounding_box|
|
||||
glPushMatrix
|
||||
|
||||
glTranslatef(
|
||||
bounding_box[:entity].position.x,
|
||||
bounding_box[:entity].position.y,
|
||||
bounding_box[:entity].position.z
|
||||
)
|
||||
draw_bounding_box(bounding_box)
|
||||
@bounding_boxes[key][:objects].each {|o| draw_bounding_box(o)}
|
||||
|
||||
glPopMatrix
|
||||
end
|
||||
end
|
||||
|
||||
def draw_bounding_box(bounding_box)
|
||||
glEnableClientState(GL_VERTEX_ARRAY)
|
||||
glEnableClientState(GL_COLOR_ARRAY)
|
||||
glEnableClientState(GL_NORMAL_ARRAY)
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, bounding_box[:vertices])
|
||||
glColorPointer(3, GL_FLOAT, 0, bounding_box[:colors])
|
||||
glNormalPointer(GL_FLOAT, 0, bounding_box[:normals])
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
|
||||
glDisable(GL_LIGHTING)
|
||||
glDrawArrays(GL_TRIANGLES, 0, bounding_box[: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
|
||||
end
|
||||
end
|
||||
162
lib/cyberarm_engine/opengl/renderer/g_buffer.rb
Normal file
162
lib/cyberarm_engine/opengl/renderer/g_buffer.rb
Normal file
@@ -0,0 +1,162 @@
|
||||
module CyberarmEngine
|
||||
class GBuffer
|
||||
attr_reader :screen_vbo, :vertices, :uvs
|
||||
def initialize(width:, height:)
|
||||
@width, @height = width, height
|
||||
|
||||
@framebuffer = nil
|
||||
@buffers = [:position, :diffuse, :normal, :texcoord]
|
||||
@textures = {}
|
||||
@screen_vbo = nil
|
||||
@ready = false
|
||||
|
||||
@vertices = [
|
||||
-1.0, -1.0, 0,
|
||||
1.0, -1.0, 0,
|
||||
-1.0, 1.0, 0,
|
||||
|
||||
-1.0, 1.0, 0,
|
||||
1.0, -1.0, 0,
|
||||
1.0, 1.0, 0,
|
||||
].freeze
|
||||
|
||||
@uvs = [
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
|
||||
0, 1,
|
||||
1, 0,
|
||||
1, 1
|
||||
].freeze
|
||||
|
||||
create_framebuffer
|
||||
create_screen_vbo
|
||||
end
|
||||
|
||||
def create_framebuffer
|
||||
buffer = ' ' * 4
|
||||
glGenFramebuffers(1, buffer)
|
||||
@framebuffer = buffer.unpack('L2').first
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, @framebuffer)
|
||||
|
||||
create_textures
|
||||
|
||||
status = glCheckFramebufferStatus(GL_FRAMEBUFFER)
|
||||
|
||||
if status != GL_FRAMEBUFFER_COMPLETE
|
||||
message = ""
|
||||
|
||||
case status
|
||||
when GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
|
||||
message = "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"
|
||||
when GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
|
||||
message = "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"
|
||||
when GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER
|
||||
message = "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"
|
||||
when GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER
|
||||
message = "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER"
|
||||
when GL_FRAMEBUFFER_UNSUPPORTED
|
||||
message = "GL_FRAMEBUFFER_UNSUPPORTED"
|
||||
else
|
||||
message = "Unknown error!"
|
||||
end
|
||||
puts "Incomplete framebuffer: #{status}\nError: #{message}"
|
||||
else
|
||||
@ready = true
|
||||
end
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0)
|
||||
end
|
||||
|
||||
def create_textures
|
||||
@buffers.size.times do |i|
|
||||
buffer = ' ' * 4
|
||||
glGenTextures(1, buffer)
|
||||
texture_id = buffer.unpack('L2').first
|
||||
@textures[@buffers[i]] = texture_id
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, @width, @height, 0, GL_RGBA, GL_FLOAT, nil)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, texture_id, 0)
|
||||
end
|
||||
|
||||
buffer = ' ' * 4
|
||||
glGenTextures(1, buffer)
|
||||
texture_id = buffer.unpack('L2').first
|
||||
@textures[:depth] = texture_id
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, @width, @height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nil)
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture_id, 0)
|
||||
|
||||
draw_buffers = [ GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 ]
|
||||
glDrawBuffers(draw_buffers.size, draw_buffers.pack("I*"))
|
||||
end
|
||||
|
||||
def create_screen_vbo
|
||||
buffer = ' ' * 4
|
||||
glGenVertexArrays(1, buffer)
|
||||
@screen_vbo = buffer.unpack('L2').first
|
||||
|
||||
buffer = " " * 4
|
||||
glGenBuffers(1, buffer)
|
||||
@positions_buffer_id = buffer.unpack('L2').first
|
||||
|
||||
buffer = " " * 4
|
||||
glGenBuffers(1, buffer)
|
||||
@uvs_buffer_id = buffer.unpack('L2').first
|
||||
|
||||
glBindVertexArray(@screen_vbo)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, @positions_buffer_id)
|
||||
glBufferData(GL_ARRAY_BUFFER, @vertices.size * Fiddle::SIZEOF_FLOAT, @vertices.pack("f*"), GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nil)
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, @uvs_buffer_id)
|
||||
glBufferData(GL_ARRAY_BUFFER, @uvs.size * Fiddle::SIZEOF_FLOAT, @uvs.pack("f*"), GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, nil)
|
||||
|
||||
glEnableVertexAttribArray(0)
|
||||
glEnableVertexAttribArray(1)
|
||||
|
||||
glBindVertexArray(0)
|
||||
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 set_read_buffer_depth
|
||||
glReadBuffer(GL_DEPTH_ATTACHMENT)
|
||||
end
|
||||
|
||||
def unbind_framebuffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0)
|
||||
end
|
||||
|
||||
def texture(type)
|
||||
@textures[type]
|
||||
end
|
||||
|
||||
def clean_up
|
||||
glDeleteFramebuffers(1, [@framebuffer].pack("L"))
|
||||
|
||||
glDeleteTextures(@textures.values.size, @textures.values.pack("L*"))
|
||||
|
||||
glDeleteBuffers(2, [@positions_buffer_id, @uvs_buffer_id].pack("L*"))
|
||||
glDeleteVertexArrays(1, [@screen_vbo].pack("L"))
|
||||
gl_error?
|
||||
end
|
||||
end
|
||||
end
|
||||
285
lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb
Normal file
285
lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb
Normal file
@@ -0,0 +1,285 @@
|
||||
module CyberarmEngine
|
||||
class OpenGLRenderer
|
||||
@@immediate_mode_warning = false
|
||||
|
||||
attr_accessor :show_wireframe
|
||||
def initialize(width:, height:, show_wireframe: false)
|
||||
@width, @height = width, height
|
||||
@show_wireframe = show_wireframe
|
||||
|
||||
@g_buffer = GBuffer.new(width: @width, height: @height)
|
||||
end
|
||||
|
||||
def canvas_size_changed
|
||||
@g_buffer.unbind_framebuffer
|
||||
@g_buffer.clean_up
|
||||
|
||||
@g_buffer = GBuffer.new(width: @width, height: @height)
|
||||
end
|
||||
|
||||
def render(camera, lights, entities)
|
||||
glViewport(0, 0, @width, @height)
|
||||
glEnable(GL_DEPTH_TEST)
|
||||
|
||||
if Shader.available?("g_buffer") && Shader.available?("lighting")
|
||||
@g_buffer.bind_for_writing
|
||||
gl_error?
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0)
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
||||
|
||||
Shader.use("g_buffer") do |shader|
|
||||
gl_error?
|
||||
|
||||
entities.each do |entity|
|
||||
next unless entity.visible && entity.renderable
|
||||
|
||||
shader.uniform_transform("projection", camera.projection_matrix)
|
||||
shader.uniform_transform("view", camera.view_matrix)
|
||||
shader.uniform_transform("model", entity.model_matrix)
|
||||
shader.uniform_vec3("cameraPosition", camera.position)
|
||||
|
||||
gl_error?
|
||||
draw_model(entity.model, shader)
|
||||
entity.draw
|
||||
end
|
||||
end
|
||||
|
||||
@g_buffer.unbind_framebuffer
|
||||
gl_error?
|
||||
|
||||
@g_buffer.bind_for_reading
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0)
|
||||
|
||||
lighting(lights)
|
||||
gl_error?
|
||||
|
||||
post_processing
|
||||
gl_error?
|
||||
|
||||
# render_framebuffer
|
||||
gl_error?
|
||||
|
||||
@g_buffer.unbind_framebuffer
|
||||
gl_error?
|
||||
else
|
||||
puts "Shaders are disabled or failed to compile, using immediate mode for rendering..." unless @@immediate_mode_warning
|
||||
@@immediate_mode_warning = true
|
||||
|
||||
gl_error?
|
||||
lights.each(&:draw)
|
||||
camera.draw
|
||||
|
||||
glEnable(GL_NORMALIZE)
|
||||
entities.each do |entity|
|
||||
next unless entity.visible && entity.renderable
|
||||
|
||||
glPushMatrix
|
||||
|
||||
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 copy_g_buffer_to_screen
|
||||
@g_buffer.set_read_buffer(:position)
|
||||
glBlitFramebuffer(0, 0, @g_buffer.width, @g_buffer.height,
|
||||
0, 0, @g_buffer.width / 2, @g_buffer.height / 2,
|
||||
GL_COLOR_BUFFER_BIT, GL_LINEAR)
|
||||
|
||||
@g_buffer.set_read_buffer(:diffuse)
|
||||
glBlitFramebuffer(0, 0, @g_buffer.width, @g_buffer.height,
|
||||
0, @g_buffer.height / 2, @g_buffer.width / 2, @g_buffer.height,
|
||||
GL_COLOR_BUFFER_BIT, GL_LINEAR)
|
||||
|
||||
@g_buffer.set_read_buffer(:normal)
|
||||
glBlitFramebuffer(0, 0, @g_buffer.width, @g_buffer.height,
|
||||
@g_buffer.width / 2, @g_buffer.height / 2, @g_buffer.width, @g_buffer.height,
|
||||
GL_COLOR_BUFFER_BIT, GL_LINEAR)
|
||||
|
||||
@g_buffer.set_read_buffer(:texcoord)
|
||||
glBlitFramebuffer(0, 0, @g_buffer.width, @g_buffer.height,
|
||||
@g_buffer.width / 2, 0, @g_buffer.width, @g_buffer.height / 2,
|
||||
GL_COLOR_BUFFER_BIT, GL_LINEAR)
|
||||
end
|
||||
|
||||
def lighting(lights)
|
||||
Shader.use("lighting") do |shader|
|
||||
glBindVertexArray(@g_buffer.screen_vbo)
|
||||
|
||||
glDisable(GL_DEPTH_TEST)
|
||||
glEnable(GL_BLEND)
|
||||
|
||||
glActiveTexture(GL_TEXTURE0)
|
||||
glBindTexture(GL_TEXTURE_2D, @g_buffer.texture(:diffuse))
|
||||
shader.uniform_integer("diffuse", 0)
|
||||
|
||||
glActiveTexture(GL_TEXTURE1)
|
||||
glBindTexture(GL_TEXTURE_2D, @g_buffer.texture(:position))
|
||||
shader.uniform_integer("position", 1)
|
||||
|
||||
glActiveTexture(GL_TEXTURE2)
|
||||
glBindTexture(GL_TEXTURE_2D, @g_buffer.texture(:texcoord))
|
||||
shader.uniform_integer("texcoord", 2)
|
||||
|
||||
glActiveTexture(GL_TEXTURE3)
|
||||
glBindTexture(GL_TEXTURE_2D, @g_buffer.texture(:normal))
|
||||
shader.uniform_integer("normal", 3)
|
||||
|
||||
glActiveTexture(GL_TEXTURE4)
|
||||
glBindTexture(GL_TEXTURE_2D, @g_buffer.texture(:depth))
|
||||
shader.uniform_integer("depth", 4)
|
||||
|
||||
lights.each_with_index do |light, i|
|
||||
shader.uniform_integer("light[0].type", light.type);
|
||||
shader.uniform_vec3("light[0].direction", light.direction)
|
||||
shader.uniform_vec3("light[0].position", light.position)
|
||||
shader.uniform_vec3("light[0].diffuse", light.diffuse)
|
||||
shader.uniform_vec3("light[0].ambient", light.ambient)
|
||||
shader.uniform_vec3("light[0].specular", light.specular)
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, @g_buffer.vertices.size)
|
||||
end
|
||||
|
||||
glBindVertexArray(0)
|
||||
end
|
||||
end
|
||||
|
||||
def post_processing
|
||||
end
|
||||
|
||||
def render_framebuffer
|
||||
if Shader.available?("lighting")
|
||||
Shader.use("lighting") do |shader|
|
||||
glBindVertexArray(@g_buffer.screen_vbo)
|
||||
|
||||
glDisable(GL_DEPTH_TEST)
|
||||
glEnable(GL_BLEND)
|
||||
|
||||
glActiveTexture(GL_TEXTURE0)
|
||||
glBindTexture(GL_TEXTURE_2D, @g_buffer.texture(:diffuse))
|
||||
shader.uniform_integer("diffuse_texture", 0)
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, @g_buffer.vertices.size)
|
||||
|
||||
glBindVertexArray(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def draw_model(model, shader)
|
||||
glBindVertexArray(model.vertex_array_id)
|
||||
glEnableVertexAttribArray(0)
|
||||
glEnableVertexAttribArray(1)
|
||||
glEnableVertexAttribArray(2)
|
||||
if model.has_texture?
|
||||
glEnableVertexAttribArray(3)
|
||||
glEnableVertexAttribArray(4)
|
||||
end
|
||||
|
||||
if @show_wireframe
|
||||
glLineWidth(2)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
|
||||
Shader.active_shader.uniform_boolean("disableLighting", true)
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, model.faces.count * 3)
|
||||
|
||||
Shader.active_shader.uniform_boolean("disableLighting", false)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
|
||||
glLineWidth(1)
|
||||
end
|
||||
|
||||
offset = 0
|
||||
model.objects.each do |object|
|
||||
shader.uniform_boolean("hasTexture", object.has_texture?)
|
||||
|
||||
if object.has_texture?
|
||||
glBindTexture(GL_TEXTURE_2D, object.materials.find { |mat| mat.texture_id }.texture_id)
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, 0)
|
||||
end
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, offset, object.faces.count * 3)
|
||||
offset += object.faces.count * 3
|
||||
end
|
||||
|
||||
if model.has_texture?
|
||||
glDisableVertexAttribArray(4)
|
||||
glDisableVertexAttribArray(3)
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0)
|
||||
end
|
||||
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_COLOR_MATERIAL)
|
||||
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
|
||||
glShadeModel(GL_FLAT) unless o.faces.first[4]
|
||||
glShadeModel(GL_SMOOTH) if o.faces.first[4]
|
||||
glEnableClientState(GL_VERTEX_ARRAY)
|
||||
glEnableClientState(GL_COLOR_ARRAY)
|
||||
glEnableClientState(GL_NORMAL_ARRAY)
|
||||
|
||||
if o.has_texture?
|
||||
glEnable(GL_TEXTURE_2D)
|
||||
glBindTexture(GL_TEXTURE_2D, o.materials.find { |mat| mat.texture_id }.texture_id)
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
|
||||
glTexCoordPointer(3, GL_FLOAT, 0, o.flattened_uvs)
|
||||
end
|
||||
|
||||
glVertexPointer(4, GL_FLOAT, 0, o.flattened_vertices)
|
||||
glColorPointer(3, GL_FLOAT, 0, o.flattened_materials)
|
||||
glNormalPointer(GL_FLOAT, 0, o.flattened_normals)
|
||||
|
||||
if @show_wireframe # This is kinda expensive
|
||||
glDisable(GL_LIGHTING)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
|
||||
glPolygonOffset(2, 0.5)
|
||||
glLineWidth(3)
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, o.flattened_vertices_size/4)
|
||||
|
||||
glLineWidth(1)
|
||||
glPolygonOffset(0, 0)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
|
||||
glEnable(GL_LIGHTING)
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, o.flattened_vertices_size/4)
|
||||
else
|
||||
glDrawArrays(GL_TRIANGLES, 0, o.flattened_vertices_size/4)
|
||||
end
|
||||
|
||||
# glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY)
|
||||
glDisableClientState(GL_COLOR_ARRAY)
|
||||
glDisableClientState(GL_NORMAL_ARRAY)
|
||||
|
||||
if o.has_texture?
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY)
|
||||
glDisable(GL_TEXTURE_2D)
|
||||
end
|
||||
|
||||
glDisable(GL_COLOR_MATERIAL)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
22
lib/cyberarm_engine/opengl/renderer/renderer.rb
Normal file
22
lib/cyberarm_engine/opengl/renderer/renderer.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
module CyberarmEngine
|
||||
class Renderer
|
||||
attr_reader :opengl_renderer, :bounding_box_renderer
|
||||
|
||||
def initialize
|
||||
@bounding_box_renderer = BoundingBoxRenderer.new
|
||||
@opengl_renderer = OpenGLRenderer.new(width: $window.width, height: $window.height)
|
||||
end
|
||||
|
||||
def draw(camera, lights, entities)
|
||||
@opengl_renderer.render(camera, lights, entities)
|
||||
@bounding_box_renderer.render(entities) if @show_bounding_boxes
|
||||
end
|
||||
|
||||
def canvas_size_changed
|
||||
@opengl_renderer.canvas_size_changed
|
||||
end
|
||||
|
||||
def finalize # cleanup
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user