void PickBody() { DropBody(); PickedEntity = RayCastEntity(out Vector3 PickPoint, out Vector3 Normal); if (PickedEntity != null) { DbgDraw.DrawLine(FireOrigin, PickPoint, Time: 5000); DbgDraw.DrawCircle(PickPoint + Normal * 0.1f, Normal, FishGfx.Color.Red, 5, 8, Time: 5000); PickDist = Vector3.Distance(FireOrigin, PickPoint); GlobalPickPoint = PickPoint; Matrix4x4.Invert(PickedEntity.RigidBody.CenterOfMassTransform, out Matrix4x4 InvCenterOfMass); LocalPickPoint = PickPoint = Vector3.Transform(PickPoint, InvCenterOfMass); PickedEntity.Unfreeze(); PickedEntity.DisableSleep(); PointConst = new Point2PointConstraint(PickedEntity.RigidBody, PickPoint); PointConst.Setting.ImpulseClamp = 10000; PointConst.Setting.Tau = 0.01f; PointConst.Setting.Damping = 0.99f; Map.World.AddConstraint(PointConst); OldAngularDamping = PickedEntity.RigidBody.AngularDamping; OldLinearDamping = PickedEntity.RigidBody.LinearDamping; PickedEntity.RigidBody.SetDamping(OldLinearDamping, 0.99f); IsPickingBody = true; } }
Vector3 DrawRay(Vector3 From, Vector3 To) { if (Map.RayCast(From, To, out Vector3 HitPos, out Vector3 Normal, out RigidBody Body)) { DbgDraw.DrawLine(From, HitPos, Time: 30000); return(HitPos); } DbgDraw.DrawLine(From, To, Time: 30000); return(To); }
public override void Reload(bool Pressed) { if (Pressed) { EntPhysics Ent = RayCastEntity(out Vector3 PickPoint); if (Ent != null) { Ent.Unfreeze(); } //DbgDraw.DrawFrustum(Engine.Camera3D, Time: 10000); //DbgDraw.DrawFrustum(Engine.Map.GetEntities<Player>().First().ViewModelCamera, Time: 10000); Vector3[] Pts = Engine.Camera3D.GetFrustumPoints(); /*// Near * DbgDraw.DrawLine(Pts[0], Pts[1], Time: 10000); * DbgDraw.DrawLine(Pts[1], Pts[2], Time: 10000); * DbgDraw.DrawLine(Pts[2], Pts[3], Time: 10000); * DbgDraw.DrawLine(Pts[3], Pts[0], Time: 10000); * * // Far * DbgDraw.DrawLine(Pts[4], Pts[5], Time: 10000); * DbgDraw.DrawLine(Pts[5], Pts[6], Time: 10000); * DbgDraw.DrawLine(Pts[6], Pts[7], Time: 10000); * DbgDraw.DrawLine(Pts[7], Pts[4], Time: 10000);*/ // Connecting lines Vector3 A = DrawRay(Pts[0], Pts[4]); Vector3 B = DrawRay(Pts[1], Pts[5]); Vector3 C = DrawRay(Pts[2], Pts[6]); Vector3 D = DrawRay(Pts[3], Pts[7]); DbgDraw.DrawLine(A, B, FishGfx.Color.Red, Time: 30000); DbgDraw.DrawLine(B, C, FishGfx.Color.Red, Time: 30000); DbgDraw.DrawLine(C, D, FishGfx.Color.Red, Time: 30000); DbgDraw.DrawLine(D, A, FishGfx.Color.Red, Time: 30000); } }
static void RunGame() { TimeStopwatch = Stopwatch.StartNew(); InitConsole(); Engine.VFS = new VirtualFileSystem(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); Engine.VFS.Mount("/content/", "./content"); Engine.VFS.Mount("/materials/", "C:/Program Files (x86)/Steam/steamapps/common/GarrysMod/garrysmod/addons/quake_3_gmod_160207505/materials"); string[] SourceGameDirs = Engine.SourceGameDirs.Value.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries).Where(Pth => Directory.Exists(Pth)).ToArray(); if (SourceGameDirs.Length > 0) { foreach (var GameDir in SourceGameDirs) { Engine.VFS.GetSourceProvider().AddRoot(GameDir); } } if (Directory.Exists(Path.Combine(Engine.GamePath, "content"))) { Engine.VFS.Mount("/content/", Path.Combine(Engine.GamePath, "content")); } List <string> ZipResources = new List <string>(); ZipResources.AddRange(Engine.VFS.GetFiles("/content/").Where(P => Path.GetExtension(P) == ".pk3" || Path.GetExtension(P) == ".zip")); foreach (var ZipResource in ZipResources) { Engine.VFS.MountArchive("/content/", ZipResource); } FileWatcher.Init("content"); Importers.RegisterAll(Reflect.GetExeAssembly()); Engine.GUI = new NuklearGUI(); Engine.Window = new RenderWindow(Engine.WindowWidth, Engine.WindowHeight, "libTech", Engine.WindowResizable); Engine.Window.OnMouseMove += Engine.GUI.OnMouseMove; Engine.Window.OnKey += OnKey; Engine.Window.OnChar += Engine.GUI.OnChar; RenderDoc.Init(); GConsole.Init(); GConsole.WriteLine("Running {0}", RenderAPI.Renderer, RenderAPI.Version); string ExtensionsFile = "extensions.txt"; if (File.Exists(ExtensionsFile)) { File.Delete(ExtensionsFile); } File.WriteAllLines(ExtensionsFile, RenderAPI.Extensions); EngineRenderer.Init(); Engine.GUI.Init(Engine.Window, new ShaderProgram(new ShaderStage(ShaderType.VertexShader, "content/shaders/gui.vert"), new ShaderStage(ShaderType.FragmentShader, "content/shaders/gui.frag"))); Engine.UI = new libGUI(Engine.Window); DbgDraw.Init(); Lua.Init(); GConsole.Color = Color.Orange; foreach (var DllName in FailedToLoadDLLs) { GConsole.WriteLine("Failed to load '{0}'", DllName); } GConsole.Color = Color.White; // Graphics init Gfx.ShadersDirectory = "content/shaders"; //Gfx.Line3D = DefaultShaders.Line3D; //Gfx.Point3D = DefaultShaders.Point3D; //Gfx.Default3D = DefaultShaders.DefaultColor3D; // Camera init Engine.Camera2D = new Camera(); Engine.Camera2D.SetOrthogonal(0, 0, Engine.Window.WindowWidth, Engine.Window.WindowHeight); Engine.Camera3D = new Camera(); Engine.Camera3D.SetPerspective(Engine.Window.WindowWidth, Engine.Window.WindowHeight, FarPlane: 16000); LoadGameDll(Engine.GamePath); Stopwatch SWatch = Stopwatch.StartNew(); int MaxFPS = Engine.MaxFPS; if (MaxFPS <= 0) { MaxFPS = 900; } float FrameCap = 1.0f / MaxFPS; float Dt = 1.0f / 60.0f; while (!Engine.Window.ShouldClose) { Engine.FrameTime.Push(Dt); Update(Dt); EngineRenderer.Draw(Dt); // TODO: Move frame cap somewhere else while ((SWatch.ElapsedMilliseconds / 1000.0f) < FrameCap) { Thread.Sleep(0); } Dt = SWatch.ElapsedMilliseconds / 1000.0f; SWatch.Restart(); } }
public static void Draw(float Dt, bool AmbientLighting = true, bool PointLighting = true) { RenderDoc.StartFrame(); Engine.GetTexture("skybox").BindTextureUnit(10); DbgDraw.Enabled = Engine.DebugDraw; ShaderUniforms.Current.Resolution = Engine.Window.WindowSize; // Deferred opaque pass RenderAPI.DbgPushGroup("Deferred opaque pass"); Engine.GBuffer.Push(); { RenderState RS = Gfx.PeekRenderState(); RS.EnableBlend = false; Gfx.PushRenderState(RS); Gfx.Clear(Color.Transparent); ShaderUniforms.Current.Camera = Engine.Camera3D; Engine.Map?.DrawOpaque(); Engine.Game.DrawOpaque(); Gfx.PopRenderState(); } Engine.GBuffer.Pop(); RenderAPI.DbgPopGroup(); // Lighting/transparency pass RenderAPI.DbgPushGroup("Lighting/transparency pass"); Engine.ScreenRT.Push(); { // Clear canvas, copy depth buffer, draw skybox RenderAPI.DbgMessage("Lighting/transparency pass"); Gfx.Clear(Color.Black); Engine.GBuffer.Framebuffer.Blit(false, true, false, Destination: Engine.ScreenRT.Framebuffer); Engine.Map?.DrawSkybox(); Engine.GBuffer.Color.BindTextureUnit(0); Engine.GBuffer.Position.BindTextureUnit(1); Engine.GBuffer.Normal.BindTextureUnit(2); Engine.GBuffer.DepthStencil.BindTextureUnit(3); { RenderState State = Gfx.PeekRenderState(); State.FrontFace = FrontFace.CounterClockwise; State.EnableBlend = true; State.BlendFunc_Src = BlendFactor.SrcAlpha; State.BlendFunc_Dst = BlendFactor.One; State.EnableDepthTest = false; Gfx.PushRenderState(State); ShaderUniforms.Current.Camera = Engine.Camera2D; if (AmbientLighting) { RenderAPI.DbgPushGroup("Deferred ambient"); // Ambient lighting ShaderProgram AmbientShader = Engine.GetShader("deferred_ambient"); AmbientShader.Bind(ShaderUniforms.Current); Engine.ScreenQuad.Draw(); AmbientShader.Unbind(); RenderAPI.DbgPopGroup(); } // Point lighting Gfx.PopRenderState(); State.FrontFace = FrontFace.CounterClockwise; State.EnableDepthMask = false; State.EnableDepthTest = true; State.EnableStencilTest = true; Gfx.PushRenderState(State); ShaderUniforms.Current.Camera = Engine.Camera3D; if (Engine.Map != null && PointLighting) { DynamicLight[] Lights = Engine.Map.GetLights(); RenderAPI.DbgPushGroup("Point lighting"); for (int i = 0; i < Lights.Length; i++) { DbgDraw.DrawCross(Lights[i].Position); State.SetColorMask(false); State.EnableBlend = false; State.EnableDepthTest = true; State.EnableCullFace = false; State.StencilFunc(StencilFunction.Always, 0, 0); State.StencilOpSeparate(StencilFace.Front, StencilOperation.Keep, StencilOperation.IncrWrap, StencilOperation.Keep); State.StencilOpSeparate(StencilFace.Back, StencilOperation.Keep, StencilOperation.DecrWrap, StencilOperation.Keep); State.DepthFunc = DepthFunc.LessOrEqual; Gfx.PushRenderState(State); Gfx.ClearStencil(); DrawPointLightMask(Lights[i]); DrawPointLightShadow(Lights[i]); Gfx.PopRenderState(); State.EnableBlend = true; State.SetColorMask(true); State.EnableDepthTest = false; State.EnableCullFace = true; State.StencilFunc(StencilFunction.Equal, 1, 0xFF); State.StencilOp(StencilOperation.Keep, StencilOperation.Keep, StencilOperation.Keep); Gfx.PushRenderState(State); ShadePointLight(Lights[i]); Gfx.PopRenderState(); } RenderAPI.DbgPopGroup(); } Gfx.PopRenderState(); } Engine.GBuffer.DepthStencil.UnbindTextureUnit(3); Engine.GBuffer.Normal.UnbindTextureUnit(2); Engine.GBuffer.Position.UnbindTextureUnit(1); Engine.GBuffer.Color.UnbindTextureUnit(0); // Draw transparent items RenderAPI.DbgPushGroup("Transparent items"); Engine.Map?.DrawTransparent(); Engine.Game.DrawTransparent(); RenderAPI.DbgPopGroup(); // Draw debug lines DbgDraw.FinalizeDraw((long)(Engine.Time * 1000)); } Engine.ScreenRT.Pop(); RenderAPI.DbgPopGroup(); RenderAPI.DbgPushGroup("2D pass"); { RenderState State = Gfx.PeekRenderState(); State.EnableDepthTest = false; Gfx.PushRenderState(State); { Gfx.Clear(); ShaderUniforms.Current.Camera = Engine.Camera2D; ShaderUniforms.Current.TextureSize = Engine.ScreenRT.Color.Size; ShaderUniforms.Current.MultisampleCount = Engine.ScreenRT.Color.Multisamples; Gfx.TexturedRectangle(0, 0, Engine.Window.WindowWidth, Engine.Window.WindowHeight, Texture: Engine.ScreenRT.Color, Shader: Engine.GetShader("framebuffer")); Engine.GUI.Draw(() => { float FT = Engine.FrameTime.Average(); float FPS = 1.0f / FT; string DebugString = string.Format("{0} ms\n{1} FPS\n{2} Lights", FT, FPS, Engine.Map.GetLights().Length); int Lines = 3; Gfx.DrawText(Engine.UI.DebugFont, new Vector2(2, Engine.WindowHeight - Engine.UI.DebugFont.ScaledLineHeight * Lines - 2), DebugString, Color.White); Engine.UI.Draw(); Engine.Game.DrawGUI(Dt); }); } Gfx.PopRenderState(); } RenderAPI.DbgPopGroup(); Engine.Window.SwapBuffers(); RenderDoc.EndFrame(); }