mirror of
https://github.com/cyberarm/i-mic-fps.git
synced 2025-12-15 07:32:35 +00:00
Added command to reload shaders at runtime, added support for shared scripts to Manifest, lights are now loadable from MapParser, misc changes.
This commit is contained in:
@@ -21,8 +21,10 @@ collision: "mesh"
|
||||
# Path to collision model or null to use `model`
|
||||
collision_mesh: null
|
||||
# Array of scripts to load, relative to package/name/scripts/
|
||||
# Optionally shared scripts can be loaded from package/shared/scripts/ if prefixed with an exclaimation mark "!"
|
||||
scripts: [
|
||||
"script"
|
||||
"script",
|
||||
"!shared_script"
|
||||
]
|
||||
# Array of assets to preload that this asset uses/requires
|
||||
uses: [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: "Alternate Tank"
|
||||
model: "alternate_tank.obj"
|
||||
scripts: [
|
||||
"vehicle"
|
||||
"!vehicle"
|
||||
]
|
||||
@@ -6,6 +6,6 @@ on.create do |event|
|
||||
map.insert_entity("base", "door", event.entity.position + Vector.new(3.3, 0, 6), Vector.new(0, 0, 0))
|
||||
map.insert_entity("base", "door", event.entity.position + Vector.new(3.3, 0, 6), Vector.new(0, 180, 0))
|
||||
|
||||
map.insert_particle_emitter(Vector.new(3.0, 15.379, 0.029), Texture.new("base", "shared", "particles", "smoke", "smoke.png"))
|
||||
map.insert_particle_emitter(Vector.new(5.0, 15.379, 0.029), Texture.new("base", "shared", "particles", "smoke", "smoke.png"))
|
||||
map.insert_particle_emitter(Vector.new(3.0, 15.379, 0.029), Texture.new(path: ["base", "shared", "particles", "smoke", "smoke.png"]))
|
||||
map.insert_particle_emitter(Vector.new(5.0, 15.379, 0.029), Texture.new(path: ["base", "shared", "particles", "smoke", "smoke.png"]))
|
||||
end
|
||||
@@ -19,7 +19,7 @@ class IMICFPS
|
||||
|
||||
@devisor = 500.0
|
||||
@name_image = Gosu::Image.from_text("#{Etc.getlogin}", 100, font: "Consolas", align: :center)
|
||||
@name_texture_id = Texture.new(@name_image).id
|
||||
@name_texture_id = Texture.new(image: @name_image).id
|
||||
end
|
||||
|
||||
def draw_nameplate
|
||||
|
||||
@@ -8,10 +8,10 @@ class IMICFPS
|
||||
def initialize(
|
||||
id:,
|
||||
type: Light::POINT,
|
||||
ambient: Vector.new(0.5, 0.5, 0.5, 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),
|
||||
ambient: Vector.new(0.5, 0.5, 0.5),
|
||||
diffuse: Vector.new(1, 1, 1),
|
||||
specular: Vector.new(0.2, 0.2, 0.2),
|
||||
position: Vector.new(0, 0, 0),
|
||||
intensity: 1
|
||||
)
|
||||
@light_id = id
|
||||
|
||||
@@ -35,7 +35,16 @@ class IMICFPS
|
||||
def parse_scripts(scripts)
|
||||
list = []
|
||||
scripts.each do |script|
|
||||
list << Script.new(script, File.read("#{file_path}/scripts/#{script}.rb"))
|
||||
path = ""
|
||||
|
||||
if script.start_with?("!")
|
||||
script = script.sub("!", "")
|
||||
path = File.expand_path("../shared/", file_path) + "/scripts/" + script
|
||||
else
|
||||
path = "#{file_path}/scripts/#{script}"
|
||||
end
|
||||
|
||||
list << Script.new(script, File.read("#{path}.rb"))
|
||||
end
|
||||
|
||||
return list
|
||||
|
||||
23
lib/map.rb
23
lib/map.rb
@@ -6,8 +6,8 @@ class IMICFPS
|
||||
|
||||
attr_reader :collision_manager
|
||||
attr_reader :gravity
|
||||
def initialize(map_loader:, gravity: IMICFPS::EARTH_GRAVITY)
|
||||
@map_loader = map_loader
|
||||
def initialize(map_parser:, gravity: IMICFPS::EARTH_GRAVITY)
|
||||
@map_parser = map_parser
|
||||
@gravity = gravity
|
||||
|
||||
@entities = []
|
||||
@@ -19,23 +19,26 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def setup
|
||||
add_entity(Terrain.new(map_entity: @map_loader.terrain, manifest: Manifest.new(package: @map_loader.terrain.package, name: @map_loader.terrain.name)))
|
||||
add_entity(Terrain.new(map_entity: @map_parser.terrain, manifest: Manifest.new(package: @map_parser.terrain.package, name: @map_parser.terrain.name)))
|
||||
|
||||
add_entity(Skydome.new(map_entity: @map_loader.skydome, manifest: Manifest.new(package: @map_loader.skydome.package, name: @map_loader.skydome.name), backface_culling: false))
|
||||
add_entity(Skydome.new(map_entity: @map_parser.skydome, manifest: Manifest.new(package: @map_parser.skydome.package, name: @map_parser.skydome.name), backface_culling: false))
|
||||
|
||||
@map_loader.entities.each do |ent|
|
||||
@map_parser.lights.each do |l|
|
||||
add_light(Light.new(id: available_light, position: l.position, diffuse: l.diffuse, ambient: l.ambient, specular: l.specular, intensity: l.intensity))
|
||||
end
|
||||
|
||||
@map_parser.entities.each do |ent|
|
||||
add_entity(Entity.new(map_entity: ent, manifest: Manifest.new(package: ent.package, name: ent.name)))
|
||||
end
|
||||
|
||||
add_entity(Player.new(spawnpoint: @map_loader.spawnpoints.sample, manifest: Manifest.new(package: "base", name: "character")))
|
||||
add_entity(Player.new(spawnpoint: @map_parser.spawnpoints.sample, manifest: Manifest.new(package: "base", name: "character")))
|
||||
|
||||
# TODO: Load lights from MapParser
|
||||
add_light(Light.new(id: available_light, position: Vector.new(30, 10.0, 30)))
|
||||
add_light(Light.new(id: available_light, position: Vector.new(0, 100, 0), diffuse: Color.new(1.0, 0.5, 0.1)))
|
||||
# add_light(Light.new(id: available_light, position: Vector.new(30, 10.0, 30)))
|
||||
# add_light(Light.new(id: available_light, position: Vector.new(0, 100, 0), diffuse: Color.new(1.0, 0.5, 0.1)))
|
||||
end
|
||||
|
||||
def data
|
||||
@map_loader
|
||||
@map_parser
|
||||
end
|
||||
|
||||
def render(camera)
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
class IMICFPS
|
||||
class MapParser
|
||||
attr_reader :metadata, :terrain, :skydome, :entities, :spawnpoints
|
||||
attr_reader :metadata, :terrain, :skydome, :lights, :entities, :spawnpoints
|
||||
attr_reader :assets, :missing_assets
|
||||
def initialize(map_file:)
|
||||
@metadata = MapParser::MetaData.new
|
||||
@terrain = MapParser::Entity.new
|
||||
@skydome = MapParser::Entity.new
|
||||
@lights = []
|
||||
@entities = []
|
||||
@spawnpoints = []
|
||||
|
||||
@@ -76,6 +77,36 @@ class IMICFPS
|
||||
raise "Map skydome data is missing!"
|
||||
end
|
||||
|
||||
if section = data["lights"]
|
||||
section.each do |l|
|
||||
light = MapParser::Light.new
|
||||
light.type = IMICFPS::Light::POINT # TODO: fix me
|
||||
light.position = Vector.new(
|
||||
l["position"]["x"],
|
||||
l["position"]["y"],
|
||||
l["position"]["z"]
|
||||
)
|
||||
light.diffuse = Color.new(
|
||||
l["diffuse"]["red"],
|
||||
l["diffuse"]["green"],
|
||||
l["diffuse"]["blue"]
|
||||
)
|
||||
light.ambient = Color.new(
|
||||
l["ambient"]["red"],
|
||||
l["ambient"]["green"],
|
||||
l["ambient"]["blue"]
|
||||
)
|
||||
light.specular = Color.new(
|
||||
l["specular"]["red"],
|
||||
l["specular"]["green"],
|
||||
l["specular"]["blue"]
|
||||
)
|
||||
light.intensity = l["intensity"]
|
||||
|
||||
@lights << light
|
||||
end
|
||||
end
|
||||
|
||||
if section = data["entities"]
|
||||
section.each do |ent|
|
||||
entity = MapParser::Entity.new
|
||||
@@ -132,6 +163,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
MetaData = Struct.new(:name, :gamemode, :authors, :datetime, :thumbnail, :description)
|
||||
Light = Struct.new(:type, :position, :diffuse, :ambient, :specular, :intensity)
|
||||
Entity = Struct.new(:package, :name, :position, :orientation, :scale, :water_level, :scripts)
|
||||
SpawnPoint = Struct.new(:team, :position, :orientation)
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def set_texture(texture_path)
|
||||
@texture_id = Texture.new(texture_path).id
|
||||
@texture_id = Texture.new(path: texture_path).id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -36,7 +36,7 @@ class IMICFPS
|
||||
if id
|
||||
_model = @model.objects.find { |o| o.id == id }
|
||||
elsif name
|
||||
_model = @model.objects.find { |o| o.id == id }
|
||||
_model = @model.objects.find { |o| o.name == name }
|
||||
else
|
||||
raise "Must provide either an id: or name:"
|
||||
end
|
||||
|
||||
@@ -4,10 +4,6 @@ class IMICFPS
|
||||
[:obj]
|
||||
end
|
||||
|
||||
def initialize(model)
|
||||
@model = model
|
||||
end
|
||||
|
||||
def parse
|
||||
lines = 0
|
||||
list = File.read(@model.file_path).split("\n")
|
||||
|
||||
@@ -124,12 +124,14 @@ class IMICFPS
|
||||
glEnableClientState(GL_VERTEX_ARRAY)
|
||||
glEnableClientState(GL_COLOR_ARRAY)
|
||||
glEnableClientState(GL_NORMAL_ARRAY)
|
||||
|
||||
if model.has_texture?
|
||||
glEnable(GL_TEXTURE_2D)
|
||||
glBindTexture(GL_TEXTURE_2D, model.materials[model.textured_material].texture_id)
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
|
||||
glTexCoordPointer(3, GL_FLOAT, 0, o.flattened_textures)
|
||||
end
|
||||
|
||||
glVertexPointer(4, GL_FLOAT, 0, o.flattened_vertices)
|
||||
glColorPointer(3, GL_FLOAT, 0, o.flattened_materials)
|
||||
glNormalPointer(GL_FLOAT, 0, o.flattened_normals)
|
||||
@@ -160,10 +162,12 @@ class IMICFPS
|
||||
glDisableClientState(GL_VERTEX_ARRAY)
|
||||
glDisableClientState(GL_COLOR_ARRAY)
|
||||
glDisableClientState(GL_NORMAL_ARRAY)
|
||||
|
||||
if model.has_texture?
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY)
|
||||
glDisable(GL_TEXTURE_2D)
|
||||
end
|
||||
|
||||
glDisable(GL_CULL_FACE) if model.entity.backface_culling
|
||||
glDisable(GL_COLOR_MATERIAL)
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@ class IMICFPS
|
||||
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 = {
|
||||
# entity: scale
|
||||
"character": 0.25,
|
||||
"information_panel": 0.25,
|
||||
"purchase_terminal": 0.35,
|
||||
|
||||
@@ -3,7 +3,7 @@ class IMICFPS
|
||||
|
||||
attr_reader :map
|
||||
def setup
|
||||
@map = Map.new(map_loader: @options[:map_parser])
|
||||
@map = Map.new(map_parser: @options[:map_parser])
|
||||
@map.setup
|
||||
|
||||
@player = @map.find_entity_by(name: "character")
|
||||
|
||||
@@ -11,18 +11,19 @@ class IMICFPS
|
||||
end
|
||||
|
||||
attr_reader :id
|
||||
def initialize(*path)
|
||||
if path.size > 1
|
||||
path = "#{GAME_ROOT_PATH}/assets/#{path.join("/")}"
|
||||
else
|
||||
path = path.first
|
||||
def initialize(path: nil, image: nil, retro: false)
|
||||
raise "keyword :path or :image must be provided!" if path.nil? && image.nil?
|
||||
@retro = retro
|
||||
|
||||
if path.is_a?(Array)
|
||||
if path.size > 1
|
||||
path = "#{GAME_ROOT_PATH}/assets/#{path.join("/")}"
|
||||
else
|
||||
path = path.first
|
||||
end
|
||||
end
|
||||
|
||||
unless path.is_a?(String)
|
||||
@id = create_from_image(path)
|
||||
else
|
||||
@id = from_cache(path)
|
||||
end
|
||||
@id = create_from_image(path ? path : image)
|
||||
end
|
||||
|
||||
def from_cache(path)
|
||||
@@ -51,7 +52,8 @@ class IMICFPS
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.width, texture.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, array_of_pixels)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) if @retro
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) unless @retro
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
|
||||
glGenerateMipmap(GL_TEXTURE_2D)
|
||||
gl_error?
|
||||
|
||||
62
lib/ui/commands/reload_shader_command.rb
Normal file
62
lib/ui/commands/reload_shader_command.rb
Normal file
@@ -0,0 +1,62 @@
|
||||
class IMICFPS
|
||||
class Commands
|
||||
class ReloadShaderCommand < Command
|
||||
def group
|
||||
:reload_shader
|
||||
end
|
||||
|
||||
def command
|
||||
:reload_shader
|
||||
end
|
||||
|
||||
def handle(arguments, console)
|
||||
if arguments.size > 2
|
||||
console.stdin("to many arguments for #{Style.highlight("#{command}")}, got #{Style.error(arguments.size)} expected #{Style.notice(1)}.")
|
||||
return
|
||||
end
|
||||
|
||||
shader = nil
|
||||
stdout = $stdout
|
||||
$stdout = StringIO.new
|
||||
|
||||
case arguments.size
|
||||
when 0
|
||||
console.stdin( usage )
|
||||
return
|
||||
when 1
|
||||
name = arguments.first
|
||||
shader = Shader.new(
|
||||
name: name,
|
||||
includes_dir: "shaders/include",
|
||||
vertex: "shaders/vertex/#{name}.glsl",
|
||||
fragment: "shaders/fragment/#{name}.glsl"
|
||||
)
|
||||
when 2
|
||||
vertex = arguments.first
|
||||
fragment = arguments.last
|
||||
shader = Shader.new(
|
||||
name: vertex,
|
||||
includes_dir: "shaders/include",
|
||||
vertex: "shaders/vertex/#{vertex}.glsl",
|
||||
fragment: "shaders/fragment/#{fragment}.glsl"
|
||||
)
|
||||
end
|
||||
|
||||
string = $stdout.string
|
||||
|
||||
if shader.compiled?
|
||||
console.stdin("#{Style.notice("Successfully reloaded shader")}: #{shader.name}")
|
||||
else
|
||||
console.stdin("#{Style.error("Failed to reload #{shader.name}")}")
|
||||
console.stdin(string)
|
||||
end
|
||||
ensure
|
||||
$stdout = stdout
|
||||
end
|
||||
|
||||
def usage
|
||||
"#{Style.highlight(command)} #{Style.notice("vertex_name [fragment_name]")}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -20,6 +20,57 @@
|
||||
"scale":0.08
|
||||
},
|
||||
|
||||
"lights":[
|
||||
{
|
||||
"type":"directional",
|
||||
"intensity": 1,
|
||||
"position": {
|
||||
"x":30,
|
||||
"y":10,
|
||||
"z":30
|
||||
},
|
||||
"diffuse": {
|
||||
"red":1,
|
||||
"green":1,
|
||||
"blue":1
|
||||
},
|
||||
"ambient": {
|
||||
"red":0.5,
|
||||
"green":0.5,
|
||||
"blue":0.5
|
||||
},
|
||||
"specular": {
|
||||
"red":0.2,
|
||||
"green":0.2,
|
||||
"blue":0.2
|
||||
}
|
||||
},
|
||||
{
|
||||
"type":"directional",
|
||||
"intensity": 1,
|
||||
"position": {
|
||||
"x":0,
|
||||
"y":100,
|
||||
"z":0
|
||||
},
|
||||
"diffuse": {
|
||||
"red":1,
|
||||
"green":0.5,
|
||||
"blue":0.1
|
||||
},
|
||||
"ambient": {
|
||||
"red":0.5,
|
||||
"green":0.5,
|
||||
"blue":0.5
|
||||
},
|
||||
"specular": {
|
||||
"red":0.2,
|
||||
"green":0.2,
|
||||
"blue":0.2
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"entities":[
|
||||
{
|
||||
"package":"base",
|
||||
|
||||
Reference in New Issue
Block a user