public void PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys) { if (RenderComponent == null || RenderComponent.PrepareRender(camera, nr, sys)) { //Guns etc. aren't drawn when parent isn't on LOD0 var isZero = RenderComponent == null || RenderComponent.CurrentLevel == 0; foreach (var child in Children) { if ((child.RenderComponent != null && !child.RenderComponent.InheritCull) || isZero) { child.PrepareRender(camera, nr, sys); } } } foreach (var child in ForceRenderCheck) { child.PrepareRender(camera, nr, sys); } }
public override bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys) { if (fx == null) { return(false); } this.sys = sys; cameraPos = camera.Position; dist = Vector3.DistanceSquared(pos, camera.Position); fx.Resources = sys.ResourceManager; if (Active && dist < (20000 * 20000)) { sys.AddObject(this); fx.Pool = sys.FxPool; fx.UpdateCull(camera); return(true); } fx.Pool = null; return(false); }
public override bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys) { beams = sys.Beams; renderCount = 0; for (int i = 0; i < Projectiles.Projectiles.Length; i++) { if (Projectiles.Projectiles[i].Alive) { if (Projectiles.Projectiles[i].Effect != null) { Projectiles.Projectiles[i].Effect.Resources = sys.ResourceManager; Projectiles.Projectiles[i].Effect.Pool = sys.FxPool; } toRender[renderCount++] = Projectiles.Projectiles[i]; } } if (renderCount > 0) { sys.AddObject(this); } return(true); }
public override bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys) { var visible = ( VectorMath.DistanceSquared(camera.Position, pos) < CULL && camera.Frustum.Intersects(new BoundingSphere(pos, equip.BulbSize * 3)) ); this.sys = sys; if (visible) { sys.AddObject(this); return(true); } else { return(false); } /*if (lt_on && camera.Frustum.Intersects(new BoundingSphere(pos, 100))) * { * sys.PointLightDX(pos, 50, new Color4(equip.GlowColor, 1), new Vector3(1, 0.01f, 0.000055f)); * }*///TODO: Configurable }
public override void Draw(ICamera camera, CommandBuffer commands, SystemLighting lights, NebulaRenderer nr) { Body.Update(camera, TimeSpan.Zero, TimeSpan.Zero); var bhps = Body.GetHardpoints().Where((arg) => arg.Hp.Name.ToLowerInvariant() == "hp_head").First(); Body.DrawBuffer(commands, transform, Lighting.Empty); Head.Update(camera, TimeSpan.Zero, TimeSpan.Zero); Head.DrawBuffer(commands, bhps.GetTransform(transform), Lighting.Empty); var hhps = Head.GetHardpoints().ToArray(); LeftHand.Update(camera, TimeSpan.Zero, TimeSpan.Zero); var lhhps = LeftHand.GetHardpoints().ToArray(); RightHand.Update(camera, TimeSpan.Zero, TimeSpan.Zero); var rhhps = RightHand.GetHardpoints().ToArray(); }
public override bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys) { this.sysr = sys; if (Nebula != null && nr != Nebula) { return(false); } var dsq = VectorMath.DistanceSquared(pos, camera.Position); if (LODRanges != null) //Fastest cull { var maxd = LODRanges[LODRanges.Length - 1] * sysr.LODMultiplier; maxd *= maxd; if (dsq > maxd) { return(false); } } if (Model != null) { if (Model.Levels.Length != 0) { var center = VectorMath.Transform(Model.Levels[0].Center, World); var lvl = GetLevel(Model, center, camera.Position); if (lvl == null) { return(false); } var bsphere = new BoundingSphere( center, Model.Levels[0].Radius ); if (!camera.Frustum.Intersects(bsphere)) { return(false); //Culled } sys.AddObject(this); return(true); } } else if (Cmp != null || CmpParts != null) { //Check if -something- renders var partCol = (IEnumerable <Part>)CmpParts ?? Cmp.Parts; bool cmpParts = CmpParts != null; foreach (Part p in partCol) { if (cmpParts) { p.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); } var model = p.Model; Matrix4 w = World; if (p.Construct != null) { w = p.Construct.Transform * World; } if (model.Levels.Length > 0) { var center = VectorMath.Transform(model.Levels[0].Center, w); var lvl = GetLevel(model, center, camera.Position); if (lvl == null) { continue; } var bsphere = new BoundingSphere( center, model.Levels[0].Radius ); if (camera.Frustum.Intersects(bsphere)) { sys.AddObject(this); return(true); } } } return(false); } else if (Sph != null) { var bsphere = new BoundingSphere( pos, Math.Max(Sph.Radius, radiusAtmosphere)); if (!camera.Frustum.Intersects(bsphere)) { return(false); } sys.AddObject(this); return(true); } return(false); }
public override void Draw(ICamera camera, CommandBuffer commands, SystemLighting lights, NebulaRenderer nr) { if (sysr == null || vertices == null) { return; } float z = RenderHelpers.GetZ(Matrix4x4.Identity, camera.Position, pos); if (z > 900000) // Reduce artefacts from fast Z-sort calculation. This'll probably cause issues somewhere else { z = 900000; } var dist_scale = nr != null ? nr.Nebula.SunBurnthroughScale : 1; var alpha = nr != null ? nr.Nebula.SunBurnthroughIntensity : 1; if (radialShader == null) { radialShader = ShaderCache.Get("sun.vs", "sun_radial.frag"); radialTex0 = radialShader.Shader.GetLocation("tex0"); radialSize = radialShader.Shader.GetLocation("SizeMultiplier"); radialAlpha = radialShader.Shader.GetLocation("outerAlpha"); } if (spineShader == null) { spineShader = ShaderCache.Get("sun.vs", "sun_spine.frag"); spineTex0 = spineShader.Shader.GetLocation("tex0"); spineSize = spineShader.Shader.GetLocation("SizeMultiplier"); } radialShader.SetViewProjection(camera); radialShader.SetView(camera); spineShader.SetViewProjection(camera); spineShader.SetView(camera); int idx = sysr.StaticBillboards.DoVertices(ref ID, vertices); if (Sun.CenterSprite != null) { //draw center var cr = (Texture2D)sysr.ResourceManager.FindTexture(Sun.CenterSprite); commands.AddCommand(radialShader.Shader, RadialSetup, Cleanup, commands.WorldBuffer.Identity, new RenderUserData() { Float = 0, Color = new Color4(dist_scale, alpha, 0, 0), Texture = cr }, sysr.StaticBillboards.VertexBuffer, PrimitiveTypes.TriangleList, idx, 2, true, SortLayers.SUN, z); //next idx += 6; } //draw glow var gr = (Texture2D)sysr.ResourceManager.FindTexture(Sun.GlowSprite); commands.AddCommand(radialShader.Shader, RadialSetup, Cleanup, commands.WorldBuffer.Identity, new RenderUserData() { Float = 1, Color = new Color4(dist_scale, alpha, 0, 0), Texture = gr }, sysr.StaticBillboards.VertexBuffer, PrimitiveTypes.TriangleList, idx, 2, true, SortLayers.SUN, z + 108f); //next idx += 6; //draw spines if (Sun.SpinesSprite != null && nr == null) { var spinetex = (Texture2D)sysr.ResourceManager.FindTexture(Sun.SpinesSprite); commands.AddCommand(spineShader.Shader, SpineSetup, Cleanup, commands.WorldBuffer.Identity, new RenderUserData() { Texture = spinetex }, sysr.StaticBillboards.VertexBuffer, PrimitiveTypes.TriangleList, idx, 2 * Sun.Spines.Count, true, SortLayers.SUN, z + 1112f); } }
public override void Draw(ICamera camera, CommandBuffer commands, SystemLighting lights, NebulaRenderer nr) { Skeleton.GetTransforms(transform, out var headTransform, out var leftTransform, out var rightTransform ); Skeleton.UploadBoneData(commands.BonesBuffer); var lighting = RenderHelpers.ApplyLights( lights, LightGroup, Vector3.Transform(Vector3.Zero, transform), RADIUS, nr, LitAmbient, LitDynamic, NoFog ); Skeleton.Body.SetSkinning(Skeleton.BodySkinning); Skeleton.Body.Update(camera, 0.0, 0.0); Skeleton.Body.DrawBuffer(commands, transform, ref lighting); if (Skeleton.Head != null) { Skeleton.Head.SetSkinning(Skeleton.HeadSkinning); Skeleton.Head.Update(camera, 0.0, 0.0); Skeleton.Head.DrawBuffer(commands, headTransform, ref lighting); } if (Skeleton.LeftHand != null) { Skeleton.LeftHand.SetSkinning(Skeleton.LeftHandSkinning); Skeleton.LeftHand.Update(camera, 0.0, 0.0); Skeleton.LeftHand.DrawBuffer(commands, leftTransform, ref lighting); } if (Skeleton.RightHand != null) { Skeleton.RightHand.SetSkinning(Skeleton.RightHandSkinning); Skeleton.RightHand.Update(camera, 0.0, 0.0); Skeleton.RightHand.DrawBuffer(commands, rightTransform, ref lighting); } }
public unsafe void Draw() { if (game.Config.MSAASamples > 0) { if (_mwidth != Game.Width || _mheight != Game.Height) { _mwidth = Game.Width; _mheight = Game.Height; if (msaa != null) { msaa.Dispose(); } msaa = new MultisampleTarget(Game.Width, Game.Height, Game.Config.MSAASamples); } msaa.Bind(); } NebulaRenderer nr = CheckNebulae(); //are we in a nebula? bool transitioned = false; if (nr != null) { transitioned = nr.FogTransitioned(); } rstate.DepthEnabled = true; //Add Nebula light if (GLExtensions.Features430 && ExtraLights) { //TODO: Re-add [LightSource] to the compute shader, it shouldn't regress. PointLight p2; if (nr != null && nr.DoLightning(out p2)) { pointLights.Add(p2); } } //Async calcs for (int i = 0; i < Objects.Count; i += 16) { JThreads.Instance.AddTask((o) => { var offset = (int)o; for (int j = 0; j < 16 && ((j + offset) < Objects.Count); j++) { Objects[j + offset].PrepareRender(camera, nr); } }, i); } JThreads.Instance.BeginExecute(); if (transitioned) { //Fully in fog. Skip Starsphere rstate.ClearColor = nr.Nebula.FogColor; rstate.ClearAll(); } else { rstate.DepthEnabled = false; if (starSystem == null) { rstate.ClearColor = NullColor; } else { rstate.ClearColor = starSystem.BackgroundColor; } rstate.ClearAll(); //Starsphere for (int i = 0; i < StarSphereModels.Length; i++) { Matrix4 ssworld = Matrix4.CreateTranslation(camera.Position); if (StarSphereWorlds != null) { ssworld = StarSphereWorlds[i] * ssworld; } StarSphereModels[i].Draw(rstate, ssworld, Lighting.Empty); } //Render fog transition: if any if (nr != null) { rstate.DepthEnabled = false; nr.RenderFogTransition(); rstate.DepthEnabled = true; } } DebugRenderer.StartFrame(camera, rstate); Polyline.SetCamera(camera); commands.StartFrame(); rstate.DepthEnabled = true; //Optimisation for dictionary lookups LightEquipRenderer.FrameStart(); //Clear depth buffer for game objects rstate.ClearDepth(); game.Billboards.Begin(camera, commands); JThreads.Instance.FinishExecute(); //Make sure visibility calculations are complete if (GLExtensions.Features430 && ExtraLights) { //Forward+ heck yeah! //ISSUES: Z prepass here doesn't work - gives blank texture (investigate DepthMap.cs) //(WORKED AROUND) Lights being culled too aggressively - Pittsburgh planet light, intro_planet_chunks //Z test - cull transparent and opaque differently (opaqueLightBuffer enable) //Optimisation work needs to be done //When these are fixed this can be enabled by default //Copy lights into buffer int plc = pointLights.Count; using (var h = pointLightBuffer.Map()) { var ptr = (PointLight *)h.Handle; for (int i = 0; i < pointLights.Count; i++) { ptr[i] = pointLights[i]; } //Does the rest of the buffer need to be cleared? } pointLights.Clear(); //Setup Visible Buffers var tilesW = (Game.Width + (Game.Width % 16)) / 16; var tilesH = (Game.Height + (Game.Height % 16)) / 16; SystemLighting.NumberOfTilesX = tilesW; if (_twidth != tilesW || _theight != tilesH) { _twidth = tilesW; _theight = tilesH; //if (opaqueLightBuffer != null) opaqueLightBuffer.Dispose(); if (transparentLightBuffer != null) { transparentLightBuffer.Dispose(); } //opaqueLightBuffer = new ShaderStorageBuffer((tilesW * tilesH) * 512 * sizeof(int)); transparentLightBuffer = new ShaderStorageBuffer((tilesW * tilesH) * 512 * sizeof(int)); } //Depth if (_dwidth != Game.Width || _dheight != Game.Height) { _dwidth = Game.Width; _dheight = Game.Height; if (depthMap != null) { depthMap.Dispose(); } depthMap = new DepthMap(Game.Width, game.Height); } depthMap.BindFramebuffer(); rstate.ClearDepth(); rstate.DepthFunction = DepthFunction.Less; for (int i = 0; i < Objects.Count; i++) { if (Objects[i].Visible) { Objects[i].DepthPrepass(camera, rstate); } } rstate.DepthFunction = DepthFunction.LessEqual; RenderTarget2D.ClearBinding(); if (game.Config.MSAASamples > 0) { msaa.Bind(); } //Run compute shader pointLightBuffer.BindIndex(0); transparentLightBuffer.BindIndex(1); //opaqueLightBuffer.BindIndex(2); pointLightCull.Uniform1i("depthTexture", 7); depthMap.BindTo(7); pointLightCull.Uniform1i("numLights", plc); pointLightCull.Uniform1i("windowWidth", Game.Width); pointLightCull.Uniform1i("windowHeight", Game.Height); var v = camera.View; var p = camera.Projection; p.Invert(); pointLightCull.UniformMatrix4fv("viewMatrix", ref v); pointLightCull.UniformMatrix4fv("invProjection", ref p); GL.MemoryBarrier(GL.GL_SHADER_STORAGE_BARRIER_BIT); //I don't think these need to be here - confirm then remove? pointLightCull.Dispatch((uint)tilesW, (uint)tilesH, 1); GL.MemoryBarrier(GL.GL_SHADER_STORAGE_BARRIER_BIT); } else { SystemLighting.NumberOfTilesX = -1; //Simple depth pre-pass rstate.DepthFunction = DepthFunction.Less; for (int i = 0; i < Objects.Count; i++) { if (Objects[i].Visible) { Objects[i].DepthPrepass(camera, rstate); } } rstate.DepthFunction = DepthFunction.LessEqual; } //Actual Drawing for (int i = 0; i < Objects.Count; i++) { if (Objects[i].Visible) { Objects[i].Draw(camera, commands, SystemLighting, nr); } } for (int i = 0; i < AsteroidFields.Count; i++) { AsteroidFields[i].Draw(cache, SystemLighting, commands, nr); } game.Nebulae.NewFrame(); if (nr == null) { for (int i = 0; i < Nebulae.Count; i++) { Nebulae[i].Draw(commands); } } else { nr.Draw(commands); } game.Nebulae.SetData(); game.Billboards.End(); Polyline.FrameEnd(); //Opaque Pass rstate.DepthEnabled = true; commands.DrawOpaque(rstate); //Transparent Pass rstate.DepthWrite = false; commands.DrawTransparent(rstate); rstate.DepthWrite = true; DebugRenderer.Render(); if (Game.Config.MSAASamples > 0) { msaa.BlitToScreen(); } rstate.DepthEnabled = true; }
public override void Draw(ICamera camera, CommandBuffer commands, SystemLighting lights, NebulaRenderer nr) { for (int i = 0; i < renderCount; i++) { var p = toRender[i]; if (p.Data.Munition.ConstEffect_Spear != null) { beams.AddBeamSpear(p.Position, p.Normal.Normalized(), p.Data.Munition.ConstEffect_Spear); } if (p.Data.Munition.ConstEffect_Bolt != null) { beams.AddBeamBolt(p.Position, p.Normal.Normalized(), p.Data.Munition.ConstEffect_Bolt); } } }
public virtual void PrepareRender(ICamera camera, NebulaRenderer nr) { }
public override void Draw(ICamera camera, CommandBuffer commands, SystemLighting lights, NebulaRenderer nr) { dist = VectorMath.DistanceSquared(pos, camera.Position); if (Active && dist < (20000 * 20000)) { fx.Draw(sys.Polyline, sys.Game.Billboards, sys.DebugRenderer, tr, SParam); } }
public void Draw(ResourceManager res, SystemLighting lighting, CommandBuffer buffer, NebulaRenderer nr) { //Null check if (_camera == null) { return; } //Asteroids! if (Vector3.DistanceSquared(cameraPos, field.Zone.Position) <= renderDistSq) { float fadeNear = field.FillDist - 100f; float fadeFar = field.FillDist; if (field.Cube.Count > 0) { if (cubeCount == -1) { return; } asteroidsTask.Wait(); for (int i = 0; i < cubeDrawCalls.Count; i++) { cubeDrawCalls[i].Material.Update(_camera); } var lt = RenderHelpers.ApplyLights(lighting, 0, cameraPos, field.FillDist, nr); if (lt.FogMode == FogModes.Linear) { lastFog = lt.FogRange.Y; } else { lastFog = float.MaxValue; } int fadeCount = 0; int regCount = 0; for (int j = 0; j < cubeCount; j++) { var center = cubes[j].pos; var z = RenderHelpers.GetZ(cameraPos, center); for (int i = 0; i < cubeDrawCalls.Count; i++) { var dc = cubeDrawCalls[i]; if ((Vector3.Distance(center, cameraPos) + cubeRadius) < fadeNear) { buffer.AddCommand( dc.Material.Render, null, buffer.WorldBuffer.SubmitMatrix(ref cubes[j].tr), lt, cube_vbo, PrimitiveTypes.TriangleList, 0, dc.StartIndex, dc.Count / 3, SortLayers.OBJECT ); regCount++; } else { buffer.AddCommandFade( dc.Material.Render, buffer.WorldBuffer.SubmitMatrix(ref cubes[j].tr), lt, cube_vbo, PrimitiveTypes.TriangleList, dc.StartIndex, dc.Count / 3, SortLayers.OBJECT, new Vector2(fadeNear, fadeFar), z ); fadeCount++; } } } } if (field.BillboardCount != -1) { var cameraLights = RenderHelpers.ApplyLights(lighting, 0, cameraPos, 1, nr); if (billboardTex == null || billboardTex.IsDisposed) { billboardTex = (Texture2D)res.FindTexture(field.BillboardShape.Texture); } billboardTask.Wait(); for (int i = 0; i < billboardCount; i++) { var alpha = BillboardAlpha(Vector3.Distance(calculatedBillboards[i].Position, cameraPos)); if (alpha <= 0) { continue; } var coords = billboardCoords [calculatedBillboards [i].Texture]; sys.Billboards.DrawTri( billboardTex, calculatedBillboards [i].Position, calculatedBillboards[i].Size, new Color4(field.BillboardTint * cameraLights.Ambient, alpha), coords[0], coords[2], coords[1], 0, SortLayers.OBJECT ); } } } //Band is last if (renderBand) { if (!_camera.Frustum.Intersects(new BoundingSphere(field.Zone.Position, lightingRadius))) { return; } var tex = (Texture2D)res.FindTexture(field.Band.Shape); var bandHandle = buffer.WorldBuffer.SubmitMatrix(ref bandTransform); for (int i = 0; i < SIDES; i++) { var p = bandCylinder.GetSidePosition(i); var zcoord = RenderHelpers.GetZ(bandTransform, cameraPos, p); p = Vector3.Transform(p, bandTransform); var lt = RenderHelpers.ApplyLights(lighting, 0, p, lightingRadius, nr); if (lt.FogMode != FogModes.Linear || Vector3.DistanceSquared(cameraPos, p) <= (lightingRadius + lt.FogRange.Y) * (lightingRadius + lt.FogRange.Y)) { buffer.AddCommand( bandShader.Shader, bandShaderDelegate, bandShaderCleanup, bandHandle, lt, new RenderUserData() { Float = field.Band.TextureAspect, Color = field.Band.ColorShift, Camera = _camera, Texture = tex, }, bandCylinder.VertexBuffer, PrimitiveTypes.TriangleList, 0, i * 6, 2, true, SortLayers.OBJECT, zcoord ); } } } }
public override void Draw(ICamera camera, CommandBuffer commands, SystemLighting lights, NebulaRenderer nr) { for (int i = 0; i < renderCount; i++) { var p = toRender[i]; var currDist = (p.Position - p.Start).Length(); if (p.Data.Munition.ConstEffect_Spear != null) { beams.AddBeamSpear(p.Position, p.Normal.Normalized(), p.Data.Munition.ConstEffect_Spear, currDist); } if (p.Data.Munition.ConstEffect_Bolt != null) { beams.AddBeamBolt(p.Position, p.Normal.Normalized(), p.Data.Munition.ConstEffect_Bolt, currDist); } if (p.Effect != null) { p.Effect.Draw(Matrix4x4.CreateTranslation(p.Position), 0); } } }
public override void Draw(ICamera camera, CommandBuffer commands, SystemLighting lights, NebulaRenderer nr) { if (Model != null) { Model.Update(camera, TimeSpan.FromSeconds(sysr.Game.TotalTime), sysr.ResourceManager); foreach (var part in Model.AllParts) { if (part.Mesh == null) { continue; } if (!part.Active) { continue; } var w = part.LocalTransform * World; var center = Vector3.Transform(part.Mesh.Center, w); var lvl = GetLevel(part, center, camera.Position); if (lvl == -1) { continue; } var lighting = RenderHelpers.ApplyLights(lights, LightGroup, center, part.GetRadius(), nr, LitAmbient, LitDynamic, NoFog); var r = part.GetRadius() + lighting.FogRange.Y; if (lighting.FogMode != FogModes.Linear || Vector3.DistanceSquared(camera.Position, center) <= (r * r)) { part.Mesh.DrawBuffer(lvl, sysr.ResourceManager, commands, w, ref lighting, Model.MaterialAnims); } } } }
public override void Draw(ICamera camera, CommandBuffer commands, SystemLighting lights, NebulaRenderer nr) { if (sys == null) { return; } if (frameStart) { sys.Game.ResourceManager.TryGetShape("bulb", out bulbshape); bulbtex = (Texture2D)sys.Game.ResourceManager.FindTexture(bulbshape.Texture); sys.Game.ResourceManager.TryGetShape("shine", out shineshape); shinetex = (Texture2D)sys.Game.ResourceManager.FindTexture(shineshape.Texture); frameStart = false; } if (VectorMath.DistanceSquared(camera.Position, pos) > CULL) { return; } if (camera.Frustum.Intersects(new BoundingSphere(pos, 100))) { sys.Game.Billboards.Draw( shinetex, pos, new Vector2(equip.GlowSize) * 2, new Color4(colorGlow, 1f), new Vector2(shineshape.Dimensions.X, shineshape.Dimensions.Y), new Vector2(shineshape.Dimensions.X + shineshape.Dimensions.Width, shineshape.Dimensions.Y), new Vector2(shineshape.Dimensions.X, shineshape.Dimensions.Y + shineshape.Dimensions.Height), new Vector2(shineshape.Dimensions.X + shineshape.Dimensions.Width, shineshape.Dimensions.Y + shineshape.Dimensions.Height), 0, SortLayers.LIGHT_SHINE, BlendMode.Additive ); sys.Game.Billboards.Draw( bulbtex, pos, new Vector2(equip.BulbSize) * 2, new Color4(colorBulb, 1), new Vector2(bulbshape.Dimensions.X, bulbshape.Dimensions.Y), new Vector2(bulbshape.Dimensions.X + bulbshape.Dimensions.Width, bulbshape.Dimensions.Y), new Vector2(bulbshape.Dimensions.X, bulbshape.Dimensions.Y + bulbshape.Dimensions.Height), new Vector2(bulbshape.Dimensions.X + bulbshape.Dimensions.Width, bulbshape.Dimensions.Y + bulbshape.Dimensions.Height), 0, SortLayers.LIGHT_BULB, BlendMode.Additive ); } }
public override void Draw(ICamera camera, CommandBuffer commands, SystemLighting lights, NebulaRenderer nr) { fx.Draw(sys.Polyline, sys.Game.Billboards, sys.DebugRenderer, tr, SParam); }
public abstract void Draw(ICamera camera, CommandBuffer commands, SystemLighting lights, NebulaRenderer nr);
public void Draw(ResourceManager res, SystemLighting lighting, CommandBuffer buffer, NebulaRenderer nr) { //Null check if (_camera == null) { return; } //Asteroids! if (VectorMath.DistanceSquared(cameraPos, field.Zone.Position) <= renderDistSq) { float fadeNear = field.FillDist * 0.9f; float fadeFar = field.FillDist; if (field.Cube.Count > 0) { if (cubeCount == -1) { return; } for (int i = 0; i < cubeDrawCalls.Count; i++) { cubeDrawCalls[i].Material.Update(_camera); } var lt = RenderHelpers.ApplyLights(lighting, 0, cameraPos, field.FillDist, nr); while (!_asteroidsCalculated) { } for (int j = 0; j < cubeCount; j++) { var center = cubes[j].pos; var z = RenderHelpers.GetZ(cameraPos, center); for (int i = 0; i < cubeDrawCalls.Count; i++) { var dc = cubeDrawCalls[i]; if (VectorMath.DistanceSquared(center, cameraPos) < (fadeNear * fadeNear)) { //TODO: Accurately determine whether or not a cube has fading } buffer.AddCommandFade( dc.Material.Render, cubes[j].tr, lt, cube_vbo, PrimitiveTypes.TriangleList, dc.StartIndex, dc.Count / 3, SortLayers.OBJECT, new Vector2(fadeNear, fadeFar), z ); } } } if (field.BillboardCount != -1 || false) { var cameraLights = RenderHelpers.ApplyLights(lighting, 0, cameraPos, 1, nr); if (billboardTex == null || billboardTex.IsDisposed) { billboardTex = (Texture2D)res.FindTexture(field.BillboardShape.Texture); } for (int i = 0; i < astbillboards.Length; i++) { if (!astbillboards [i].Inited) { astbillboards [i].Spawn(this); } var d = VectorMath.DistanceSquared(cameraPos, astbillboards [i].Position); if (d < (field.BillboardDistance * field.BillboardDistance) || d > (field.FillDist * field.FillDist)) { astbillboards [i].Spawn(this); } if (astbillboards [i].Visible) { var alpha = 1f; var coords = billboardCoords [astbillboards [i].Texture]; sys.Game.Billboards.DrawTri( billboardTex, astbillboards [i].Position, astbillboards[i].Size, new Color4(field.BillboardTint * cameraLights.Ambient.Rgb, alpha), coords[0], coords[2], coords[1], 0, SortLayers.OBJECT ); } } } } //Band is last if (renderBand) { if (!_camera.Frustum.Intersects(new BoundingSphere(field.Zone.Position, lightingRadius))) { return; } var tex = (Texture2D)res.FindTexture(field.Band.Shape); for (int i = 0; i < SIDES; i++) { var p = bandCylinder.GetSidePosition(i); var zcoord = RenderHelpers.GetZ(bandTransform, cameraPos, p); p = bandTransform.Transform(p); var lt = RenderHelpers.ApplyLights(lighting, 0, p, lightingRadius, nr); if (lt.FogMode != FogModes.Linear || VectorMath.DistanceSquared(cameraPos, p) <= (lightingRadius + lt.FogRange.Y) * (lightingRadius + lt.FogRange.Y)) { buffer.AddCommand( bandShader.Shader, bandShaderDelegate, bandShaderCleanup, bandTransform, lt, new RenderUserData() { Float = field.Band.TextureAspect, Color = field.Band.ColorShift, Camera = _camera, Texture = tex, Matrix2 = bandNormal }, bandCylinder.VertexBuffer, PrimitiveTypes.TriangleList, 0, i * 6, 2, true, SortLayers.OBJECT, zcoord ); } } } }
public virtual bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys) { return(false); }
public override void Draw(ICamera camera, CommandBuffer commands, SystemLighting lights, NebulaRenderer nr) { if (sysr == null) { return; } float z = RenderHelpers.GetZ(Matrix4.Identity, camera.Position, pos); if (z > 900000) // Reduce artefacts from fast Z-sort calculation. This'll probably cause issues somewhere else { z = 900000; } var dist_scale = nr != null ? nr.Nebula.SunBurnthroughScale : 1; // TODO: Modify this based on nebula burn-through. var alpha = nr != null ? nr.Nebula.SunBurnthroughIntensity : 1; var glow_scale = dist_scale * Sun.GlowScale; if (Sun.CenterSprite != null) { var center_scale = dist_scale * Sun.CenterScale; DrawRadial( (Texture2D)sysr.Game.ResourceManager.FindTexture(Sun.CenterSprite), new Vector3(pos), new Vector2(Sun.Radius, Sun.Radius) * center_scale, new Color4(Sun.CenterColorInner, 1), new Color4(Sun.CenterColorOuter, alpha), 0, z ); } DrawRadial( (Texture2D)sysr.Game.ResourceManager.FindTexture(Sun.GlowSprite), new Vector3(pos), new Vector2(Sun.Radius, Sun.Radius) * glow_scale, new Color4(Sun.GlowColorInner, 0), new Color4(Sun.GlowColorOuter, alpha), 0, z + 108f ); if (Sun.SpinesSprite != null && nr == null) { double current_angle = 0; double delta_angle = (2 * Math.PI) / Sun.Spines.Count; var spinetex = (Texture2D)sysr.Game.ResourceManager.FindTexture(Sun.SpinesSprite); for (int i = 0; i < Sun.Spines.Count; i++) { var s = Sun.Spines[i]; current_angle += delta_angle; DrawSpine( spinetex, pos, new Vector2(Sun.Radius, Sun.Radius) * Sun.SpinesScale * new Vector2(s.WidthScale / s.LengthScale, s.LengthScale), s.InnerColor, s.OuterColor, s.Alpha, (float)current_angle, z + 1112f + (2f * i) ); } } }
public override void Draw(ICamera camera, CommandBuffer commands, SystemLighting lights, NebulaRenderer nr) { if (fx == null) { return; } fx.Draw(tr, SParam); }
public override bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys) { sysr = sys; sys.AddObject(this); return(true); }
public unsafe void Draw() { if (gconfig.MSAASamples > 0) { if (_mwidth != Game.Width || _mheight != Game.Height) { _mwidth = Game.Width; _mheight = Game.Height; if (msaa != null) { msaa.Dispose(); } msaa = new MultisampleTarget(Game.Width, Game.Height, gconfig.MSAASamples); } rstate.RenderTarget = msaa; } NebulaRenderer nr = CheckNebulae(); //are we in a nebula? bool transitioned = false; if (nr != null) { transitioned = nr.FogTransitioned(); } rstate.DepthEnabled = true; //Add Nebula light if (GLExtensions.Features430 && ExtraLights) { //TODO: Re-add [LightSource] to the compute shader, it shouldn't regress. PointLight p2; if (nr != null && nr.DoLightning(out p2)) { pointLights.Add(p2); } } //Async calcs objects = new List <ObjectRenderer>(250); /*for (int i = 0; i < World.Objects.Count; i += 16) * { * JThreads.Instance.AddTask((o) => * { * var offset = (int)o; * for (int j = 0; j < 16 && ((j + offset) < World.Objects.Count); j++) World.Objects[j + offset].PrepareRender(camera, nr, this); * }, i); * } * JThreads.Instance.BeginExecute();*/ for (int i = 0; i < World.Objects.Count; i++) { World.Objects[i].PrepareRender(camera, nr, this); } if (transitioned) { //Fully in fog. Skip Starsphere rstate.ClearColor = nr.Nebula.FogColor; rstate.ClearAll(); } else { rstate.DepthEnabled = false; if (starSystem == null) { rstate.ClearColor = NullColor; } else { rstate.ClearColor = starSystem.BackgroundColor; } rstate.ClearAll(); //Starsphere if (camera is ThnCamera thn) { thn.DefaultZ(); } for (int i = 0; i < StarSphereModels.Length; i++) { Matrix4x4 ssworld = Matrix4x4.CreateTranslation(camera.Position); if (StarSphereWorlds != null) { ssworld = StarSphereWorlds[i] * ssworld; } var lighting = Lighting.Empty; if (StarSphereLightings != null) { lighting = StarSphereLightings[i]; } StarSphereModels[i].DrawImmediate(rstate, resman, ssworld, ref lighting); } if (camera is ThnCamera thn2) { thn2.CameraZ(); } //Render fog transition: if any if (nr != null) { rstate.DepthEnabled = false; nr.RenderFogTransition(); rstate.DepthEnabled = true; } } DebugRenderer.StartFrame(camera, rstate); Polyline.SetCamera(camera); commands.StartFrame(rstate); rstate.DepthEnabled = true; //Optimisation for dictionary lookups LightEquipRenderer.FrameStart(); //Clear depth buffer for game objects rstate.ClearDepth(); billboards.Begin(camera, commands); //JThreads.Instance.FinishExecute(); //Make sure visibility calculations are complete if (GLExtensions.Features430 && ExtraLights) { //Forward+ heck yeah! //(WORKED AROUND) Lights being culled too aggressively - Pittsburgh planet light, intro_planet_chunks //Z test doesn't seem to be working (commented out in shader) //May need optimisation int plc = pointLights.Count; using (var h = pointLightBuffer.Map()) { var ptr = (PointLight *)h.Handle; for (int i = 0; i < pointLights.Count; i++) { ptr[i] = pointLights[i]; } } pointLights.Clear(); //Setup Visible Buffers var tilesW = (Game.Width + (Game.Width % 16)) / 16; var tilesH = (Game.Height + (Game.Height % 16)) / 16; SystemLighting.NumberOfTilesX = tilesW; if (_twidth != tilesW || _theight != tilesH) { _twidth = tilesW; _theight = tilesH; //if (opaqueLightBuffer != null) opaqueLightBuffer.Dispose(); if (transparentLightBuffer != null) { transparentLightBuffer.Dispose(); } //opaqueLightBuffer = new ShaderStorageBuffer((tilesW * tilesH) * 512 * sizeof(int)); transparentLightBuffer = new ShaderStorageBuffer((tilesW * tilesH) * 512 * sizeof(int)); } //Depth if (_dwidth != Game.Width || _dheight != Game.Height) { _dwidth = Game.Width; _dheight = Game.Height; if (depthMap != null) { depthMap.Dispose(); } depthMap = new DepthMap(Game.Width, game.Height); } depthMap.BindFramebuffer(); rstate.ClearDepth(); rstate.DepthFunction = DepthFunction.Less; foreach (var obj in objects) { obj.DepthPrepass(camera, rstate); } rstate.DepthFunction = DepthFunction.LessEqual; rstate.RenderTarget = null; if (gconfig.MSAASamples > 0) { rstate.RenderTarget = msaa; } //Run compute shader pointLightBuffer.BindIndex(0); transparentLightBuffer.BindIndex(1); //opaqueLightBuffer.BindIndex(2); pointLightCull.Uniform1i("depthTexture", 7); depthMap.BindTo(7); pointLightCull.Uniform1i("numLights", plc); pointLightCull.Uniform1i("windowWidth", Game.Width); pointLightCull.Uniform1i("windowHeight", Game.Height); var v = camera.View; var p = camera.Projection; Matrix4x4.Invert(p, out p); pointLightCull.UniformMatrix4fv("viewMatrix", ref v); pointLightCull.UniformMatrix4fv("invProjection", ref p); GL.MemoryBarrier(GL.GL_SHADER_STORAGE_BARRIER_BIT); //I don't think these need to be here - confirm then remove? pointLightCull.Dispatch((uint)tilesW, (uint)tilesH, 1); GL.MemoryBarrier(GL.GL_SHADER_STORAGE_BARRIER_BIT); } else { SystemLighting.NumberOfTilesX = -1; //Simple depth pre-pass rstate.ColorWrite = false; rstate.DepthFunction = DepthFunction.Less; foreach (var obj in objects) { obj.DepthPrepass(camera, rstate); } rstate.DepthFunction = DepthFunction.LessEqual; rstate.ColorWrite = true; } //Actual Drawing Beams.Begin(commands, resman, camera); foreach (var obj in objects) { obj.Draw(camera, commands, SystemLighting, nr); } Beams.End(); FxPool.Draw(camera, Polyline, resman, DebugRenderer); for (int i = 0; i < AsteroidFields.Count; i++) { AsteroidFields[i].Draw(cache, SystemLighting, commands, nr); } nebulae.NewFrame(); if (nr == null) { for (int i = 0; i < Nebulae.Count; i++) { Nebulae[i].Draw(commands); } } else { nr.Draw(commands); } nebulae.SetData(); billboards.End(); Polyline.FrameEnd(); //Opaque Pass rstate.DepthEnabled = true; commands.DrawOpaque(rstate); //Transparent Pass rstate.DepthWrite = false; commands.DrawTransparent(rstate); rstate.DepthWrite = true; PhysicsHook?.Invoke(); foreach (var point in debugPoints) { var lX = point + new Vector3(5, 0, 0); var lmX = point + new Vector3(-5, 0, 0); var lY = point + new Vector3(0, -5, 0); var lmY = point + new Vector3(0, 5, 0); var lZ = point + new Vector3(0, 0, 5); var lmZ = point + new Vector3(0, 0, -5); DebugRenderer.DrawLine(lX, lmX); DebugRenderer.DrawLine(lY, lmY); DebugRenderer.DrawLine(lZ, lmZ); } debugPoints = new Vector3[0]; DebugRenderer.Render(); if (gconfig.MSAASamples > 0) { msaa.BlitToScreen(); rstate.RenderTarget = null; } rstate.DepthEnabled = true; }
public override void Draw(ICamera camera, CommandBuffer commands, SystemLighting lights, NebulaRenderer nr) { Init(); if (Dfm != null) { Dfm.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); var center = VectorMath.Transform(Vector3.Zero, World); //var lighting = RenderHelpers.ApplyLights(lights, LightGroup, center, 20, nr, LitAmbient, LitDynamic, NoFog); Dfm.DrawBuffer(commands, World, ref Lighting.Empty); } if (Model != null) { if (Model.Levels.Length > 0) { Model.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); var center = VectorMath.Transform(Model.Levels[0].Center, World); var lvl = GetLevel(Model, center, camera.Position); if (lvl == null) { return; } var lighting = RenderHelpers.ApplyLights(lights, LightGroup, center, Model.Levels[0].Radius, nr, LitAmbient, LitDynamic, NoFog); var r = Model.Levels [0].Radius + lighting.FogRange.Y; if (lighting.FogMode != FogModes.Linear || VectorMath.DistanceSquared(camera.Position, center) <= (r * r)) { Model.DrawBufferLevel(lvl, commands, World, ref lighting); } } } else if (Cmp != null) { Cmp.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); foreach (Part p in Cmp.Parts) { var model = p.Model; Matrix4 w = World; if (p.Construct != null) { w = p.Construct.Transform * World; } if (model.Levels.Length > 0) { var center = VectorMath.Transform(model.Levels[0].Center, w); var lvl = GetLevel(model, center, camera.Position); if (lvl == null) { continue; } var bsphere = new BoundingSphere( center, model.Levels[0].Radius ); if (camera.Frustum.Intersects(bsphere)) { var lighting = RenderHelpers.ApplyLights(lights, LightGroup, center, model.Levels[0].Radius, nr, LitAmbient, LitDynamic, NoFog); var r = model.Levels [0].Radius + lighting.FogRange.Y; if (lighting.FogMode != FogModes.Linear || VectorMath.DistanceSquared(camera.Position, center) <= (r * r)) { model.DrawBufferLevel(lvl, commands, w, ref lighting); } } } } } else if (CmpParts != null) { _parentCmp.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); foreach (Part p in CmpParts) { p.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); var model = p.Model; Matrix4 w = World; if (p.Construct != null) { w = p.Construct.Transform * World; } if (model.Levels.Length > 0) { var center = VectorMath.Transform(model.Levels[0].Center, w); var lvl = GetLevel(model, center, camera.Position); if (lvl == null) { continue; } var bsphere = new BoundingSphere( center, model.Levels[0].Radius ); if (camera.Frustum.Intersects(bsphere)) { var lighting = RenderHelpers.ApplyLights(lights, LightGroup, center, model.Levels[0].Radius, nr, LitAmbient, LitDynamic, NoFog); var r = model.Levels[0].Radius + lighting.FogRange.Y; if (lighting.FogMode != FogModes.Linear || VectorMath.DistanceSquared(camera.Position, center) <= (r * r)) { model.DrawBufferLevel(lvl, commands, w, ref lighting); } } } } } else if (Sph != null) { Sph.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); var l = RenderHelpers.ApplyLights(lights, LightGroup, pos, Sph.Radius, nr, LitAmbient, LitDynamic, NoFog); var r = Sph.Radius + l.FogRange.Y; if (l.FogMode != FogModes.Linear || VectorMath.DistanceSquared(camera.Position, pos) <= (r * r)) { Sph.DrawBuffer(commands, World, ref l); } } }
public static Lighting ApplyLights(SystemLighting src, int lightGroup, Vector3 c, float r, NebulaRenderer nebula, bool lambient = true, bool ldynamic = true, bool nofog = false) { var lights = Lighting.Create(); lights.Ambient = lambient ? src.Ambient : Color4.Black; lights.NumberOfTilesX = src.NumberOfTilesX; if (nofog) { lights.FogMode = FogModes.None; } else { lights.FogMode = src.FogMode; lights.FogDensity = src.FogDensity; lights.FogColor = src.FogColor; lights.FogRange = src.FogRange; } int lc = 0; if (ldynamic) { lights.Lights.SourceLighting = src; for (int i = 0; i < src.Lights.Count; i++) { if (src.Lights[i].LightGroup != lightGroup) { continue; } if (!src.Lights[i].Active) { continue; } var l = src.Lights[i].Light; var r2 = r + l.Range; //l.Kind > 0 - test if not directional if (l.Kind > 0 && VectorMath.DistanceSquared(l.Position, c) > (r2 * r2)) { continue; } //Advanced spotlight cull if ((l.Kind == LightKind.Spotlight) && SpotlightTest(ref l, c, r)) { continue; } if ((lc + 1) > MAX_LIGHTS) { throw new Exception("Too many lights!"); } lc++; lights.Lights.SourceEnabled[i] = true; } } if (nebula != null) { Color4? ambient; bool fogenabled; Vector2 fogrange; Color4 fogcolor; RenderLight?lightning; nebula.GetLighting(out fogenabled, out ambient, out fogrange, out fogcolor, out lightning); if (ambient != null) { lights.Ambient = ambient.Value; } if (fogenabled) { lights.FogMode = FogModes.Linear; lights.FogColor = fogcolor; lights.FogRange = fogrange; } if (lightning != null && src.NumberOfTilesX == -1) { if ((lc + 1) > MAX_LIGHTS) { throw new Exception("Too many lights!"); } lights.Lights.Nebula0 = lightning.Value; lights.Lights.NebulaCount = 1; } } return(lights); }
public override void Draw(ICamera camera, CommandBuffer commands, SystemLighting lights, NebulaRenderer nr) { if (frameStart) { sys.Game.ResourceManager.TryGetShape("bulb", out bulbshape); bulbtex = (Texture2D)sys.Game.ResourceManager.FindTexture(bulbshape.Texture); sys.Game.ResourceManager.TryGetShape("shine", out shineshape); shinetex = (Texture2D)sys.Game.ResourceManager.FindTexture(shineshape.Texture); frameStart = false; } sys.Game.Billboards.Draw( shinetex, pos, new Vector2(equip.GlowSize) * 2, new Color4(colorGlow, 1f), new Vector2(shineshape.Dimensions.X, shineshape.Dimensions.Y), new Vector2(shineshape.Dimensions.X + shineshape.Dimensions.Width, shineshape.Dimensions.Y), new Vector2(shineshape.Dimensions.X, shineshape.Dimensions.Y + shineshape.Dimensions.Height), new Vector2(shineshape.Dimensions.X + shineshape.Dimensions.Width, shineshape.Dimensions.Y + shineshape.Dimensions.Height), 0, SortLayers.LIGHT_SHINE, BlendMode.Additive ); sys.Game.Billboards.Draw( bulbtex, pos, new Vector2(equip.BulbSize) * 2, new Color4(colorBulb, 1), new Vector2(bulbshape.Dimensions.X, bulbshape.Dimensions.Y), new Vector2(bulbshape.Dimensions.X + bulbshape.Dimensions.Width, bulbshape.Dimensions.Y), new Vector2(bulbshape.Dimensions.X, bulbshape.Dimensions.Y + bulbshape.Dimensions.Height), new Vector2(bulbshape.Dimensions.X + bulbshape.Dimensions.Width, bulbshape.Dimensions.Y + bulbshape.Dimensions.Height), 0, SortLayers.LIGHT_BULB, BlendMode.Additive ); }
public override void Draw(ICamera camera, CommandBuffer commands, SystemLighting lights, NebulaRenderer nr) { var code_beam = (Texture2D)res.FindTexture("code_beam"); code_beam.SetWrapModeS(WrapMode.ClampToEdge); code_beam.SetWrapModeT(WrapMode.ClampToEdge); for (int i = 0; i < renderCount; i++) { var p = toRender[i]; if (p.Data.Munition.ConstEffect_Beam != null) { var beam = p.Data.Munition.ConstEffect_Beam; Vector2 tl, tr, bl, br; CoordsFromTexture(beam.HeadTexture, out tl, out tr, out bl, out br); billboards.Draw( code_beam, p.Position, new Vector2(beam.HeadWidth, beam.HeadWidth), beam.CoreColor, tl, tr, bl, br, 0, SortLayers.OBJECT, BlendMode.Additive ); CoordsFromTexture(beam.TrailTexture, out tl, out tr, out bl, out br); } else if (p.Data.Munition.ConstEffect_Bolt != null) { //bolt var bolt = p.Data.Munition.ConstEffect_Bolt; Vector2 tl, tr, bl, br; CoordsFromTexture(bolt.HeadTexture, out tl, out tr, out bl, out br); billboards.Draw( code_beam, p.Position, new Vector2(bolt.HeadWidth, bolt.HeadWidth), bolt.CoreColor, tl, tr, bl, br, 0, SortLayers.OBJECT, BlendMode.Additive ); } } }