public override void Draw(WorldState world) { if (DrawGroup == null) { return; } if (_Dirty) { Mesh = Content.Content.Get().RCMeshes.Get(DrawGroup, Source); _Dirty = false; } //immedately draw the mesh. var device = world.Device; var effect = WorldContent.RCObject; if (Room == 65533) { effect.CurrentTechnique = effect.Techniques["DisabledDraw"]; } effect.Parameters["World"].SetValue(World); effect.Parameters["Level"].SetValue((float)(Level - 0.999f)); int i = 0; foreach (var spr in Mesh.Geoms) { if (i == 0 || (((i - 1) > 63) ? ((DynamicSpriteFlags2 & ((ulong)0x1 << ((i - 1) - 64))) > 0) : ((DynamicSpriteFlags & ((ulong)0x1 << (i - 1))) > 0))) { foreach (var geom in spr.Values) { if (geom.PrimCount == 0) { continue; } effect.Parameters["MeshTex"].SetValue(geom.Pixel); foreach (var pass in effect.CurrentTechnique.Passes) { pass.Apply(); if (!geom.Rendered) { continue; } device.Indices = geom.Indices; device.SetVertexBuffer(geom.Verts); device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, geom.PrimCount); } } } i++; } if (Room == 65533) { effect.CurrentTechnique = effect.Techniques["Draw"]; } }
private void OBJToFSOM(OBJ obj) { GameThread.NextUpdate(x => { var mesh = new DGRP3DMesh(ActiveDGRP, obj, Client.GameFacade.GraphicsDevice); if (IffMode) { var fsom = ActiveObject.Resource.Get <FSOM>(ActiveDGRP.ChunkID); if (fsom == null) { fsom = new FSOM(); fsom.ChunkLabel = "OBJ Import Mesh"; fsom.ChunkID = ActiveDGRP.ChunkID; fsom.ChunkProcessed = true; fsom.ChunkType = "FSOM"; fsom.AddedByPatch = true; (ActiveObject.Resource.Sprites ?? ActiveObject.Resource.MainIff).AddChunk(fsom); } Content.Content.Get().Changes.QueueResMod(new ResAction(() => { fsom.SetMesh(mesh); Content.Content.Get().RCMeshes.ClearCache(ActiveDGRP); Debug3D.ForceUpdate(); }, fsom)); } else { Content.Content.Get().RCMeshes.Replace(ActiveDGRP, mesh); Debug3D.ForceUpdate(); } }); }
public DGRP3DMesh Get(DGRP dgrp, OBJD obj) { DGRP3DMesh result = null; var repldir = Path.Combine(FSOEnvironment.ContentDir, "MeshReplace/"); var dir = Path.Combine(FSOEnvironment.UserDir, "MeshCache/"); if (!Cache.TryGetValue(dgrp, out result)) { //does it exist in replacements var name = obj.ChunkParent.Filename.Replace('.', '_') + "_" + dgrp.ChunkID + ".fsom"; try { using (var file = File.OpenRead(Path.Combine(repldir, name))) { result = new DGRP3DMesh(dgrp, file, GD); } } catch (Exception) { result = null; } if (result == null) { //does it exist in iff try { result = dgrp.ChunkParent.Get <FSOM>(dgrp.ChunkID)?.Get(dgrp, GD); } catch (Exception) { result = null; } } if (result == null && !IgnoreRCCache.Contains(dgrp)) { //does it exist in rc cache try { using (var file = File.OpenRead(Path.Combine(dir, name))) { result = new DGRP3DMesh(dgrp, file, GD); } } catch (Exception) { result = null; } } //create it anew if (result == null) { result = new DGRP3DMesh(dgrp, obj, GD, dir); } Cache[dgrp] = result; } return(result); }
public override void Preload(WorldState world) { if (_Dirty) { Mesh = Content.Content.Get().RCMeshes.Get(DrawGroup, Source); _Dirty = false; } }
public BoundingBox?GetBounds() { if (_Dirty.HasFlag(ComponentRenderMode._3D) && DrawGroup != null) { Mesh = Content.Content.Get().RCMeshes.Get(DrawGroup, Source); _Dirty &= ~ComponentRenderMode._3D; } return(Mesh?.Bounds); }
public BoundingBox?GetBounds() { if (_Dirty && DrawGroup != null) { Mesh = Content.Content.Get().RCMeshes.Get(DrawGroup, Source); _Dirty = false; } return(Mesh?.Bounds); }
public DGRP3DMesh Get(DGRP dgrp, GraphicsDevice device) { if (Cached == null) { using (var stream = new MemoryStream(data)) { Cached = new DGRP3DMesh(dgrp, stream, device); } } data = null; return(Cached); }
public void DrawLMap(GraphicsDevice device, sbyte level, float yOff) { if (DrawGroup == null) { return; } if (_Dirty.HasFlag(ComponentRenderMode._3D)) { Mesh = Content.Content.Get().RCMeshes.Get(DrawGroup, Source); _Dirty &= ~ComponentRenderMode._3D; } if (Mesh.MaskType == DGRP3DMaskType.Portal) { return; } //immedately draw the mesh. var effect = WorldContent.RCObject; var mat = World; mat.M42 = ((Level - level) - 1) * 2.95f + yOff; //set y translation to 0 effect.World = mat; int i = 0; foreach (var spr in Mesh.Geoms) { if (i == 0 || (((i - 1) > 63) ? ((DynamicSpriteFlags2 & ((ulong)0x1 << ((i - 1) - 64))) > 0) : ((DynamicSpriteFlags & ((ulong)0x1 << (i - 1))) > 0))) { foreach (var geom in spr.Values) { if (geom.PrimCount == 0) { continue; } foreach (var pass in effect.CurrentTechnique.Passes) { pass.Apply(); if (!geom.Rendered) { continue; } device.Indices = geom.Indices; device.SetVertexBuffer(geom.Verts); device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, geom.PrimCount); } } } i++; } }
public void Replace(DGRP dgrp, DGRP3DMesh mesh) { //todo: dispose old? var name = dgrp.ChunkParent.Filename.Replace('.', '_') + "_" + dgrp.ChunkID + ".fsom"; var repldir = Path.Combine(FSOEnvironment.ContentDir, "MeshReplace/"); mesh.SaveDirectory = repldir; mesh.Save(); Cache[dgrp] = mesh; }
public virtual void Preload(WorldState world, ComponentRenderMode mode) { if (mode.HasFlag(ComponentRenderMode._2D)) { ValidateSprite(world); } if (mode.HasFlag(ComponentRenderMode._3D)) { if (_Dirty.HasFlag(ComponentRenderMode._3D)) { Mesh = Content.Content.Get().RCMeshes.Get(DrawGroup, Source); _Dirty &= ~ComponentRenderMode._3D; } } }
public DGRP3DMesh Get(string name) { var repldir = Path.Combine(FSOEnvironment.ContentDir, "3D/"); if (!NameCache.TryGetValue(name, out var result)) { //does it exist in replacements try { using (var file = File.OpenRead(Path.Combine(repldir, name))) { result = new DGRP3DMesh(null, file, GD); } } catch (Exception) { result = null; } NameCache[name] = result; } return(result); }
/// <summary> /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.Initialize will enumerate through any components /// and initialize them as well. /// </summary> protected override void Initialize() { var kernel = new StandardKernel( new RegulatorsModule(), new NetworkModule(), new CacheModule() ); FSOFacade.Kernel = kernel; var settings = GlobalSettings.Default; if (FSOEnvironment.SoftwareDepth) { settings.GraphicsWidth = (int)(GraphicsDevice.Viewport.Width / FSOEnvironment.DPIScaleFactor); settings.GraphicsHeight = (int)(GraphicsDevice.Viewport.Height / FSOEnvironment.DPIScaleFactor); } //manage settings if (settings.LightingMode == -1) { if (settings.Lighting) { if (settings.Shadows3D) { settings.LightingMode = 2; } else { settings.LightingMode = 1; } } else { settings.LightingMode = 0; } settings.Save(); } LotView.WorldConfig.Current = new LotView.WorldConfig() { LightingMode = settings.LightingMode, SmoothZoom = settings.SmoothZoom, SurroundingLots = settings.SurroundingLotMode, AA = settings.AntiAlias, }; FeatureLevelTest.UpdateFeatureLevel(GraphicsDevice); if (!FSOEnvironment.TexCompressSupport) { settings.TexCompression = 0; } else if ((settings.TexCompression & 2) == 0) { settings.TexCompression = 1; } FSOEnvironment.TexCompress = (!IffFile.RETAIN_CHUNK_DATA) && (settings.TexCompression & 1) > 0; //end settings management OperatingSystem os = Environment.OSVersion; PlatformID pid = os.Platform; GameFacade.Linux = (pid == PlatformID.MacOSX || pid == PlatformID.Unix); FSO.Content.Content.TS1Hybrid = GlobalSettings.Default.TS1HybridEnable; FSO.Content.Content.TS1HybridBasePath = GlobalSettings.Default.TS1HybridPath; FSO.Content.Content.Init(GlobalSettings.Default.StartupPath, GraphicsDevice); VMContext.InitVMConfig(); base.Initialize(); GameFacade.GameThread = Thread.CurrentThread; SceneMgr = new _3DLayer(); SceneMgr.Initialize(GraphicsDevice); FSOFacade.Controller = kernel.Get <GameController>(); GameFacade.Screens = uiLayer; GameFacade.Scenes = SceneMgr; GameFacade.GraphicsDevice = GraphicsDevice; GameFacade.GraphicsDeviceManager = Graphics; GameFacade.Emojis = new Common.Rendering.Emoji.EmojiProvider(GraphicsDevice); GameFacade.Cursor = new CursorManager(GraphicsDevice); if (!GameFacade.Linux) { GameFacade.Cursor.Init(FSO.Content.Content.Get().GetPath(""), false); } /** Init any computed values **/ GameFacade.Init(); //init audio now HITVM.Init(); var hit = HITVM.Get(); hit.SetMasterVolume(HITVolumeGroup.FX, GlobalSettings.Default.FXVolume / 10f); hit.SetMasterVolume(HITVolumeGroup.MUSIC, GlobalSettings.Default.MusicVolume / 10f); hit.SetMasterVolume(HITVolumeGroup.VOX, GlobalSettings.Default.VoxVolume / 10f); hit.SetMasterVolume(HITVolumeGroup.AMBIENCE, GlobalSettings.Default.AmbienceVolume / 10f); GameFacade.Strings = new ContentStrings(); FSOFacade.Controller.StartLoading(); GraphicsDevice.RasterizerState = new RasterizerState() { CullMode = CullMode.None }; try { var audioTest = new SoundEffect(new byte[2], 44100, AudioChannels.Mono); //initialises XAudio. audioTest.CreateInstance().Play(); } catch (Exception e) { //MessageBox.Show("Failed to initialize audio: \r\n\r\n" + e.StackTrace); } this.IsMouseVisible = true; this.IsFixedTimeStep = true; WorldContent.Init(this.Services, Content.RootDirectory); DGRP3DMesh.InitRCWorkers(); if (!FSOEnvironment.SoftwareKeyboard) { AddTextInput(); } base.Screen.Layers.Add(SceneMgr); base.Screen.Layers.Add(uiLayer); GameFacade.LastUpdateState = base.Screen.State; //Bind ninject objects kernel.Bind <FSO.Content.Content>().ToConstant(FSO.Content.Content.Get()); kernel.Load(new ClientDomainModule()); //Have to be eager with this, it sets a singleton instance on itself to avoid packets having //to be created using Ninject for performance reasons kernel.Get <cTSOSerializer>(); var ds = kernel.Get <DataService>(); ds.AddProvider(new ClientAvatarProvider()); this.Window.Title = "FreeSO"; DiscordRpcEngine.Init(); if (!GlobalSettings.Default.Windowed && !GameFacade.GraphicsDeviceManager.IsFullScreen) { GameFacade.GraphicsDeviceManager.ToggleFullScreen(); } }
private void ImportButton_Click(object sender, EventArgs e) { var dialog = new OpenFileDialog { Title = "Select an OBJ file." }; FolderOpen(dialog); var dgrp = ActiveDGRP; try { Stream str; if ((str = dialog.OpenFile()) != null) { var obj = new OBJ(str); //identify and copy replacement textures //only happens when this iff doesnt have a 3d model foreach (var mtl in obj.FacesByObjgroup.Keys) { var split = mtl.Split('_'); if (split.Length < 3 || split[1] == "SPR" || split[0] == "DEPTH") { continue; } var baseDir = Path.GetDirectoryName(dialog.FileName); var copyname = "TEX_" + split[2] + ".png"; if (IffMode) { var texID = ushort.Parse(split[2]); var tex = ActiveObject.Resource.Get <MTEX>(texID); if (tex == null) { tex = new MTEX { ChunkLabel = "OBJ Import Texture", ChunkID = texID, ChunkProcessed = true, ChunkType = "MTEX", AddedByPatch = true }; (ActiveObject.Resource.Sprites ?? ActiveObject.Resource.MainIff).AddChunk(tex); } GameContent.Get.Changes.BlockingResMod(new ResAction(() => { tex.SetData(File.ReadAllBytes(Path.Combine(baseDir, copyname))); }, tex)); } else { var texname = ActiveDGRP.ChunkParent.Filename.Replace('.', '_').Replace("spf", "iff") + "_"; texname += copyname; File.Copy(Path.Combine(baseDir, copyname), Path.Combine(FSOEnvironment.ContentDir, "MeshReplace/", texname), true); } } GameThread.NextUpdate(x => { var mesh = new DGRP3DMesh(ActiveDGRP, obj, Client.GameFacade.GraphicsDevice); if (IffMode) { var fsom = ActiveObject.Resource.Get <FSOM>(ActiveDGRP.ChunkID); if (fsom == null) { fsom = new FSOM { ChunkLabel = "OBJ Import Mesh", ChunkID = ActiveDGRP.ChunkID, ChunkProcessed = true, ChunkType = "FSOM", AddedByPatch = true }; (ActiveObject.Resource.Sprites ?? ActiveObject.Resource.MainIff).AddChunk(fsom); } GameContent.Get.Changes.QueueResMod(new ResAction(() => { fsom.SetMesh(mesh); GameContent.Get.RCMeshes.ClearCache(ActiveDGRP); Debug3D.ForceUpdate(); }, fsom)); } else { GameContent.Get.RCMeshes.Replace(ActiveDGRP, mesh); Debug3D.ForceUpdate(); } }); str.Close(); } } catch (Exception) { } }
public void SetMesh(DGRP3DMesh mesh) { Cached = mesh; data = null; }
public void Draw3D(WorldState world) { if (DrawGroup == null) { return; } if (_Dirty.HasFlag(ComponentRenderMode._3D) || Mesh == null) { Mesh = Content.Content.Get().RCMeshes.Get(DrawGroup, Source); _Dirty &= ~ComponentRenderMode._3D; } //immedately draw the mesh. var device = world.Device; var effect = WorldContent.RCObject; effect.World = World; effect.Level = (float)(Level - 0.999f); var advDir = WorldConfig.Current.Directional && WorldConfig.Current.AdvancedLighting; if (Mesh.DepthMask != null) { var geom = Mesh.DepthMask; //depth mask for drawing into a surface or wall if (geom.Verts != null) { effect.SetTechnique(RCObjectTechniques.DepthClear); effect.CurrentTechnique.Passes[0].Apply(); device.DepthStencilState = DepthClear1; device.Indices = geom.Indices; device.SetVertexBuffer(geom.Verts); device.BlendState = NoColor; device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, geom.PrimCount); device.DepthStencilState = (Mesh.MaskType == DGRP3DMaskType.Portal) ? DepthClear2Strict : DepthClear2; effect.CurrentTechnique.Passes[1].Apply(); device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, geom.PrimCount); device.DepthStencilState = DepthStencilState.Default; device.BlendState = BlendState.NonPremultiplied; effect.SetTechnique(RCObjectTechniques.Draw); } } if (Room == 65533) { effect.SetTechnique(RCObjectTechniques.DisabledDraw); } int i = 0; foreach (var spr in Mesh.Geoms) { if (i == 0 || (((i - 1) > 63) ? ((DynamicSpriteFlags2 & ((ulong)0x1 << ((i - 1) - 64))) > 0) : ((DynamicSpriteFlags & ((ulong)0x1 << (i - 1))) > 0)) || (Mesh.MaskType == DGRP3DMaskType.Portal && i == Mesh.Geoms.Count - 1)) { foreach (var geom in spr.Values) { if (geom.PrimCount == 0) { continue; } if (Mesh.MaskType == DGRP3DMaskType.Portal && i == Mesh.Geoms.Count - 1) { device.DepthStencilState = Portal; } effect.MeshTex = geom.Pixel; var info = geom.Pixel?.Tag as TextureInfo; effect.UVScale = info?.UVScale ?? Vector2.One; var pass = effect.CurrentTechnique.Passes[(advDir && Room < 65533) ? 1 : 0]; pass.Apply(); if (geom.Rendered) { device.Indices = geom.Indices; device.SetVertexBuffer(geom.Verts); device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, geom.PrimCount); } if (Mesh.MaskType == DGRP3DMaskType.Portal && i == Mesh.Geoms.Count - 1) { device.DepthStencilState = DepthStencilState.Default; } } } i++; } if (Mesh.MaskType == DGRP3DMaskType.Portal) { var geom = Mesh.DepthMask; //clear the stencil, so it doesn't interfere with future portals. if (geom.Verts != null) { effect.SetTechnique(RCObjectTechniques.DepthClear); effect.CurrentTechnique.Passes[1].Apply(); device.DepthStencilState = StencilClearOnly; device.Indices = geom.Indices; device.SetVertexBuffer(geom.Verts); device.BlendState = NoColor; device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, geom.PrimCount); device.BlendState = BlendState.NonPremultiplied; } device.DepthStencilState = DepthStencilState.Default; effect.SetTechnique(RCObjectTechniques.Draw); } if (Room == 65533) { effect.SetTechnique(RCObjectTechniques.Draw); } }