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:
2020-03-24 09:51:20 -05:00
parent 2ad1385fb4
commit 578c00673d
18 changed files with 201 additions and 39 deletions

View File

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

View File

@@ -1,5 +1,5 @@
name: "Alternate Tank"
model: "alternate_tank.obj"
scripts: [
"vehicle"
"!vehicle"
]

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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