From eab4f32a256a9881e262fc62971b26e8098d1be0 Mon Sep 17 00:00:00 2001 From: RandomityGuy <31925790+RandomityGuy@users.noreply.github.com> Date: Fri, 4 Jun 2021 23:36:32 +0530 Subject: [PATCH] skybox test --- src/MarbleWorld.hx | 11 ++++++- src/ResourceLoader.hx | 13 ++++++++ src/Sky.hx | 69 +++++++++++++++++++++++++++++++++++++++++++ src/Util.hx | 10 +++++++ 4 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 src/Sky.hx diff --git a/src/MarbleWorld.hx b/src/MarbleWorld.hx index 7dd6b9cd..c52250f6 100644 --- a/src/MarbleWorld.hx +++ b/src/MarbleWorld.hx @@ -1,5 +1,7 @@ package src; +import src.Sky; +import h3d.scene.Mesh; import src.InstanceManager; import h3d.scene.MeshBatch; import src.DtsObject; @@ -22,13 +24,18 @@ class MarbleWorld { public var dtsObjects:Array = []; public var currentTime:Float = 0; + public var sky:Sky; - var scene:Scene; + public var scene:Scene; public function new(scene:Scene) { this.collisionWorld = new CollisionWorld(); this.scene = scene; this.instanceManager = new InstanceManager(scene); + this.sky = new Sky(); + sky.dmlPath = "data/skies/sky_day.dml"; + sky.init(cast this); + scene.addChild(sky); } public function addInterior(obj:InteriorObject) { @@ -69,6 +76,8 @@ class MarbleWorld { marble.level = cast this; if (marble.controllable) { this.scene.addChild(marble.camera); + // Ugly hack + sky.follow = marble; } this.collisionWorld.addMovingEntity(marble.collider); this.scene.addChild(marble); diff --git a/src/ResourceLoader.hx b/src/ResourceLoader.hx index 737d8e7e..95205c35 100644 --- a/src/ResourceLoader.hx +++ b/src/ResourceLoader.hx @@ -1,5 +1,6 @@ package src; +import hxd.res.Image; import h3d.mat.Texture; import h3d.scene.Object; import sys.FileSystem; @@ -17,6 +18,7 @@ class ResourceLoader { static var interiorResources:Map = new Map(); static var dtsResources:Map = new Map(); static var textureCache:Map = new Map(); + static var imageCache:Map = new Map(); public static function loadInterior(path:String) { if (interiorResources.exists(path)) @@ -50,6 +52,17 @@ class ResourceLoader { return null; } + public static function getImage(path:String) { + if (imageCache.exists(path)) + return imageCache.get(path); + if (fileSystem.exists(path)) { + var tex = loader.load(path).toImage(); + imageCache.set(path, tex); + return tex; + } + return null; + } + public static function clearInteriorResources() { interiorResources = new Map(); } diff --git a/src/Sky.hx b/src/Sky.hx new file mode 100644 index 00000000..3434a145 --- /dev/null +++ b/src/Sky.hx @@ -0,0 +1,69 @@ +package src; + +import src.Util; +import src.MarbleWorld; +import hxd.BitmapData; +import h3d.shader.CubeMap; +import h3d.mat.Texture; +import haxe.io.Path; +import sys.io.File; +import src.ResourceLoader; +import h3d.scene.Object; + +class Sky extends Object { + public var dmlPath:String; + + public function new() { + super(); + } + + public function init(level:MarbleWorld) { + var texture = createSkyboxCubeTextured(this.dmlPath); + var sky = new h3d.prim.Sphere(300, 128, 128); + sky.addNormals(); + var skyMesh = new h3d.scene.Mesh(sky, this); + skyMesh.material.mainPass.culling = Front; + skyMesh.material.mainPass.addShader(new h3d.shader.CubeMap(texture)); + skyMesh.material.shadows = false; + skyMesh.culled = false; + } + + function createSkyboxCubeTextured(dmlPath:String) { + if (ResourceLoader.fileSystem.exists(dmlPath)) { + var dmlFile = File.getContent(dmlPath); + var dmlDirectory = Path.directory(dmlPath); + var lines = dmlFile.split('\n').map(x -> x.toLowerCase()); + var skyboxImages = []; + + var skyboxIndices = [3, 1, 2, 0, 4, 5]; + + for (i in 0...6) { + var line = lines[i]; + var filenames = ResourceLoader.getFullNamesOf(dmlDirectory + '/' + line); + if (filenames.length == 0) { + skyboxImages.push(new BitmapData(128, 128)); + } else { + var image = ResourceLoader.getImage(filenames[0]).toBitmap(); + skyboxImages.push(image); + } + } + var maxwidth = 0; + var maxheight = 0; + for (texture in skyboxImages) { + if (texture.height > maxheight) + maxheight = texture.height; + if (texture.width > maxwidth) + maxwidth = texture.width; + } + + Util.rotateImage(skyboxImages[0], Math.PI / 2); + + var cubemaptexture = new Texture(maxheight, maxwidth, [Cube]); + for (i in 0...6) { + cubemaptexture.uploadBitmap(skyboxImages[skyboxIndices[i]], 0, i); + } + return cubemaptexture; + } + return null; + } +} diff --git a/src/Util.hx b/src/Util.hx index 987e7f6c..d68fc1f5 100644 --- a/src/Util.hx +++ b/src/Util.hx @@ -1,5 +1,6 @@ package src; +import hxd.BitmapData; import h3d.Vector; class Util { @@ -32,4 +33,13 @@ class Util { public static function lerpThreeVectors(v1:Vector, v2:Vector, t:Float) { return new Vector(lerp(v1.x, v2.x, t), lerp(v1.y, v2.y, t), lerp(v1.z, v2.z, t)); } + + public static function rotateImage(bitmap:BitmapData, angle:Float) { + // var bmp = new Bitmap(Tile.fromBitmap(bitmap)); + // bmp.rotate(angle); + // var output = new Texture(bitmap.width, bitmap.height, [TextureFlags.Target]); + // bmp.drawTo(output); + // var pixels = output.capturePixels(); + // bitmap.setPixels(pixels); + } }