diff --git a/i-mic-fps.rb b/i-mic-fps.rb index ece7b59..e32469d 100644 --- a/i-mic-fps.rb +++ b/i-mic-fps.rb @@ -100,6 +100,9 @@ require_relative "lib/map_parser" require_relative "lib/manifest" require_relative "lib/map" +require_relative "lib/scene" +require_relative "lib/scenes/turn_table" + require_relative "lib/crosshair" require_relative "lib/demo" diff --git a/lib/game_objects/entity.rb b/lib/game_objects/entity.rb index 17b60c7..d821d90 100644 --- a/lib/game_objects/entity.rb +++ b/lib/game_objects/entity.rb @@ -9,7 +9,7 @@ class IMICFPS attr_accessor :position, :orientation, :scale, :velocity attr_reader :name, :debug_color, :bounding_box, :drag, :camera, :manifest - def initialize(manifest:, map_entity: nil, spawnpoint: nil, backface_culling: true, auto_manage: true) + def initialize(manifest:, map_entity: nil, spawnpoint: nil, backface_culling: true, run_scripts: true) @manifest = manifest if map_entity @@ -41,7 +41,7 @@ class IMICFPS @last_position = Vector.new(@position.x, @position.y, @position.z) @sandboxes = [] - load_scripts + load_scripts if run_scripts setup diff --git a/lib/game_objects/light.rb b/lib/game_objects/light.rb index 93027d7..336bb0b 100644 --- a/lib/game_objects/light.rb +++ b/lib/game_objects/light.rb @@ -9,7 +9,7 @@ class IMICFPS id:, type: Light::POINT, ambient: Vector.new(0.5, 0.5, 0.5, 1), - diffuse: Vector.new(1, 0.5, 0, 1), + diffuse: Vector.new(1, 1, 1, 1), specular: Vector.new(0.2, 0.2, 0.2, 1), position: Vector.new(0, 0, 0, 0), intensity: 1 diff --git a/lib/map.rb b/lib/map.rb index d88f329..09b2eca 100644 --- a/lib/map.rb +++ b/lib/map.rb @@ -14,7 +14,7 @@ class IMICFPS @lights = [] @collision_manager = CollisionManager.new(map: self) - @renderer = Renderer.new + @renderer = window.renderer Publisher.new end diff --git a/lib/renderer/opengl_renderer.rb b/lib/renderer/opengl_renderer.rb index 3f34401..4964df9 100644 --- a/lib/renderer/opengl_renderer.rb +++ b/lib/renderer/opengl_renderer.rb @@ -13,7 +13,7 @@ class IMICFPS # @g_buffer.bind_for_writing gl_error? - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) + # glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) Shader.use("default") do |shader| lights.each_with_index do |light, i| @@ -42,7 +42,7 @@ class IMICFPS end end - # @g_buffer.unbind_framebuffer + @g_buffer.unbind_framebuffer gl_error? else puts "Shader 'default' failed to compile, using immediate mode for rendering..." unless @@immediate_mode_warning diff --git a/lib/renderer/renderer.rb b/lib/renderer/renderer.rb index 89e19bc..3ca54bf 100644 --- a/lib/renderer/renderer.rb +++ b/lib/renderer/renderer.rb @@ -9,6 +9,18 @@ class IMICFPS @opengl_renderer = OpenGLRenderer.new end + def preload_default_shaders + shaders = ["default"] + shaders.each do |shader| + Shader.new( + name: shader, + includes_dir: "shaders/include", + vertex: "shaders/vertex/#{shader}.glsl", + fragment: "shaders/fragment/#{shader}.glsl" + ) + end + end + def draw(camera, lights, entities) glViewport(0, 0, window.width, window.height) glEnable(GL_DEPTH_TEST) diff --git a/lib/scene.rb b/lib/scene.rb new file mode 100644 index 0000000..083d9d9 --- /dev/null +++ b/lib/scene.rb @@ -0,0 +1,22 @@ +class IMICFPS + class Scene + attr_reader :camera, :entities, :lights + + def initialize + @camera = Camera.new(position: Vector.new) + @entities = [] + @lights = [] + + setup + end + + def setup + end + + def draw + end + + def update(dt) + end + end +end \ No newline at end of file diff --git a/lib/scenes/turn_table.rb b/lib/scenes/turn_table.rb new file mode 100644 index 0000000..c2e8021 --- /dev/null +++ b/lib/scenes/turn_table.rb @@ -0,0 +1,40 @@ +class IMICFPS + class TurnTableScene < Scene + def setup + camera.field_of_view = 45 + lights << (Light.new(id: OpenGL::GL_LIGHT1, position: Vector.new(30, 10.0, 30), diffuse: Color.new(0, 0, 0), specular: Color.new(0, 0, 0))) + lights << (Light.new(id: OpenGL::GL_LIGHT2, position: Vector.new(0, 10, 5), diffuse: Color.new(1.0, 1.0, 1.0), specular: Color.new(0, 0, 0))) + + options = { + "character": 0.25, + "information_panel": 0.25, + "purchase_terminal": 0.35, + "door": 0.2, + "ttank": 0.13, + "alternate_tank": 0.065, + "tree": 0.08, + # "evergreen_tree": 0.08, + "power_plant": 0.025, + "war_factory": 0.03, + "randomish_terrain": 0.004, + "river_terrain": 0.004, + } + choice = options.keys.sample + + @entity = Entity.new(manifest: Manifest.new(package: "base", name: choice), run_scripts: false) + @entity.scale = Vector.new(1, 1, 1) * options[choice] + @entity.position.x = 0.75 + @entity.position.y = -0.5 + @entity.position.z = -1.5 + @entity.bind_model + + entities << @entity + + @max_tilt = 5.0 + end + + def update(dt) + @entity.orientation.y += 10 * dt + end + end +end \ No newline at end of file diff --git a/lib/states/game_states/loading_state.rb b/lib/states/game_states/loading_state.rb index 73a400e..927f478 100644 --- a/lib/states/game_states/loading_state.rb +++ b/lib/states/game_states/loading_state.rb @@ -13,7 +13,6 @@ class IMICFPS @dummy_entity = nil @assets = [] @asset_index = 0 - add_asset(:shader, nil, "default") add_asset(:model, @map_parser.terrain.package, @map_parser.terrain.name) add_asset(:model, @map_parser.skydome.package, @map_parser.skydome.name) @@ -43,6 +42,7 @@ class IMICFPS end def update + super @percentage.text = "#{((@asset_index.to_f / @assets.count) * 100.0).round}%" @act = true if @cycled diff --git a/lib/ui/menu.rb b/lib/ui/menu.rb index 4093bf2..12bca4d 100644 --- a/lib/ui/menu.rb +++ b/lib/ui/menu.rb @@ -8,21 +8,25 @@ class IMICFPS @base_color = Gosu::Color.rgb(255, 127, 0) @background_alpha = 200 window.needs_cursor = true + + @__version_text = CyberarmEngine::Text.new("#{IMICFPS::NAME} v#{IMICFPS::VERSION} (#{IMICFPS::RELEASE_NAME})") + @__version_text.x = window.width - (@__version_text.width + 10) + @__version_text.y = window.height - (@__version_text.height + 10) super(*args) end def title(text, color = @base_color) - @elements << Text.new(text, color: color, size: 100, x: 0, y: 15, alignment: :center) + @elements << Text.new(text, color: color, size: 100, x: 0, y: 15) @_title = @elements.last end def subtitle(text, color = Gosu::Color::WHITE) - @elements << Text.new(text, color: color, size: 50, x: 0, y: 100, alignment: :center) + @elements << Text.new(text, color: color, size: 50, x: 0, y: 100) @_subtitle = @elements.last end def link(text, color = Gosu::Color.rgb(0,127,127), &block) - text = Text.new(text, color: color, size: 50, x: 0, y: 100 + (60 * @elements.count), alignment: :center) + text = Text.new(text, color: color, size: 50, x: 0, y: 100 + (60 * @elements.count)) @elements << Link.new(text, self, block) end @@ -30,38 +34,44 @@ class IMICFPS draw_background draw_menu_box draw_menu + + @__version_text.draw + + if window.scene + window.gl(-1) do + window.renderer.draw(window.scene.camera, window.scene.lights, window.scene.entities) + end + + window.scene.draw + end end def draw_background - @background ||= Gosu.record(Gosu.screen_width, Gosu.screen_height) do - ((Gosu.screen_height+@slope)/@size).times do |i| - fill_quad( - 0, i*@size, - 0, @slope+(i*@size), - window.width/2, (-@slope)+(i*@size), - window.width/2, i*@size, - Gosu::Color.rgba(@base_color.red-i*@color_step, @base_color.green-i*@color_step, @base_color.blue-i*@color_step, @background_alpha) - ) - fill_quad( - window.width, i*@size, - window.width, @slope+(i*@size), - window.width/2, (-@slope)+(i*@size), - window.width/2, i*@size, - Gosu::Color.rgba(@base_color.red-i*@color_step, @base_color.green-i*@color_step, @base_color.blue-i*@color_step, @background_alpha) - ) - end - + ((Gosu.screen_height+@slope)/@size).times do |i| + fill_quad( + 0, i*@size, + 0, @slope+(i*@size), + window.width/2, (-@slope)+(i*@size), + window.width/2, i*@size, + Gosu::Color.rgba(@base_color.red-i*@color_step, @base_color.green-i*@color_step, @base_color.blue-i*@color_step, @background_alpha), + -2 + ) + fill_quad( + window.width, i*@size, + window.width, @slope+(i*@size), + window.width/2, (-@slope)+(i*@size), + window.width/2, i*@size, + Gosu::Color.rgba(@base_color.red-i*@color_step, @base_color.green-i*@color_step, @base_color.blue-i*@color_step, @background_alpha), + -2 + ) end - - @background.draw(0, 0, 0) end def draw_menu_box draw_rect( window.width/4, 0, window.width/2, window.height, - Gosu::Color.rgba(0, 0, 0, 150) - # Gosu::Color.rgba(@base_color.red+@color_step, @base_color.green+@color_step, @base_color.blue+@color_step, 200) + Gosu::Color.rgba(0, 0, 0, 150), ) end @@ -73,8 +83,16 @@ class IMICFPS def update @elements.each do |e| + e.x = window.width / 2 - e.width / 2 e.update end + + if window.scene + window.scene.update(window.dt) + end + + @__version_text.x = window.width - (@__version_text.width + 10) + @__version_text.y = window.height - (@__version_text.height + 10) end def fill_quad(x1, y1, x2, y2, x3, y3, x4, y4, color = Gosu::Color::WHITE, z = 0, mode = :default) @@ -125,6 +143,7 @@ class IMICFPS end def x; text.x; end + def x=(n); text.x = n; end def y; text.y; end def width; text.width; end def height; text.height; end diff --git a/lib/ui/menus/main_menu.rb b/lib/ui/menus/main_menu.rb index ff65aec..db18d76 100644 --- a/lib/ui/menus/main_menu.rb +++ b/lib/ui/menus/main_menu.rb @@ -37,8 +37,6 @@ as a commandline argument to override reported version." message += linux_mesa_message if RUBY_PLATFORM =~ /linux/ && gl_version.downcase.include?(" mesa ") @old_gl_warning = Gosu::Image.from_markup(message, 24, align: :center) end - - @text = CyberarmEngine::Text.new("#{IMICFPS::NAME} v#{IMICFPS::VERSION} (#{IMICFPS::RELEASE_NAME})") end def draw @@ -47,10 +45,6 @@ as a commandline argument to override reported version." if @old_gl_warning @old_gl_warning.draw(window.width / 2 - @old_gl_warning.width / 2, window.height - (@old_gl_warning.height + 10), Float::INFINITY) end - - @text.draw - @text.x = window.width - (@text.width + 10) - @text.y = window.height - (@text.height + 10) end end end diff --git a/lib/window.rb b/lib/window.rb index 2b7b338..eb64235 100644 --- a/lib/window.rb +++ b/lib/window.rb @@ -1,7 +1,7 @@ class IMICFPS class Window < CyberarmEngine::Engine attr_accessor :number_of_vertices, :needs_cursor - attr_reader :camera, :config + attr_reader :renderer, :scene, :config attr_reader :console, :delta_time def initialize(window_width = 1280, window_height = 720, fullscreen = false) @@ -23,6 +23,10 @@ class IMICFPS @console = Console.new Commands::Command.setup + @renderer = Renderer.new + @renderer.preload_default_shaders + @scene = TurnTableScene.new + at_exit do @config.save! end diff --git a/shaders/fragment/default.glsl b/shaders/fragment/default.glsl index 117dd49..6dee361 100644 --- a/shaders/fragment/default.glsl +++ b/shaders/fragment/default.glsl @@ -4,7 +4,7 @@ in vec3 outPosition; in vec3 outColor; -in vec4 outNormal; +in vec3 outNormal; in vec3 outUV; in float outTextureID; in float outHasTexture; @@ -12,7 +12,6 @@ in Light outLights[MAX_LIGHTS]; in float outTotalLights; in vec3 outFragPos; in vec3 outCameraPos; -in vec3 outInverseNormal; in float outDisableLighting; uniform sampler2D diffuse_texture; @@ -55,7 +54,7 @@ vec3 calculateBasicLight(Light light) { float specularStrength = 0.5; vec3 viewDir = normalize(outCameraPos - outFragPos); - vec3 reflectDir = reflect(-lightDir, outInverseNormal); + vec3 reflectDir = reflect(-lightDir, outNormal); float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); vec3 specular = specularStrength * spec * light.specular; @@ -77,7 +76,7 @@ vec3 calculateLighting() { } void main() { - lokiVar = vec4(outColor, 1.0) + outNormal + vec4(outUV, 1.0) + vec4(outTextureID, 1.0, 1.0, 1.0); + lokiVar = vec4(outColor, 1.0) + vec4(outNormal, 1.0) + vec4(outUV, 1.0) + vec4(outTextureID, 1.0, 1.0, 1.0); lokiVar = normalize(lokiVar); vec3 result; diff --git a/shaders/vertex/default.glsl b/shaders/vertex/default.glsl index a8287a3..2ae3eea 100644 --- a/shaders/vertex/default.glsl +++ b/shaders/vertex/default.glsl @@ -4,13 +4,13 @@ layout(location = 0) in vec3 inPosition; layout(location = 1) in vec3 inColor; -layout(location = 2) in vec4 inNormal; +layout(location = 2) in vec3 inNormal; layout(location = 3) in vec3 inUV; layout(location = 4) in float inTextureID; out vec3 outPosition; out vec3 outColor; -out vec4 outNormal; +out vec3 outNormal; out vec3 outUV; out float outTextureID; out float outHasTexture; @@ -19,7 +19,6 @@ out float outTotalLights; out vec3 outFragPos; out vec3 outViewPos; out vec3 outCameraPos; -out vec3 outInverseNormal; out float outDisableLighting; uniform mat4 projection; @@ -36,7 +35,7 @@ void main() { // projection * view * model * position outPosition = inPosition; outColor = inColor; - outNormal= inNormal; + outNormal= normalize(transpose(inverse(mat3(model))) * inNormal); outUV = inUV; outTextureID = inTextureID; outHasTexture = hasTexture; @@ -44,7 +43,6 @@ void main() { outTotalLights = totalLights; outCameraPos = cameraPos; outDisableLighting = disableLighting; - outInverseNormal = mat3(transpose(inverse(model))) * vec3(inNormal); outFragPos = vec3(model * vec4(inPosition, 1.0));