Implement sonic blast rendering effect.
This commit is contained in:
committed by
Gustas Kažukauskas
parent
3111d06fcf
commit
5da2f1ba8a
65
OpenRA.Mods.D2k/Graphics/SonicBlastRenderable.cs
Normal file
65
OpenRA.Mods.D2k/Graphics/SonicBlastRenderable.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.D2k.Traits;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
namespace OpenRA.Mods.D2k.Graphics
|
||||
{
|
||||
public class SonicBlastRenderable : IRenderable, IFinalizedRenderable
|
||||
{
|
||||
public static readonly IEnumerable<IRenderable> None = Array.Empty<IRenderable>();
|
||||
readonly SonicBlastRenderer renderer;
|
||||
readonly float3 r;
|
||||
|
||||
public WPos Pos { get; }
|
||||
public int ZOffset => 0;
|
||||
|
||||
public SonicBlastRenderable(SonicBlastRenderer renderer, WPos pos)
|
||||
{
|
||||
this.renderer = renderer;
|
||||
Pos = pos;
|
||||
r = renderer.Info.Size * new float3(0.5f, 0.5f, 0);
|
||||
}
|
||||
|
||||
public bool IsDecoration => false;
|
||||
|
||||
public IRenderable WithZOffset(int newOffset) => this;
|
||||
public IRenderable OffsetBy(in WVec offset) => this;
|
||||
public IRenderable AsDecoration() => this;
|
||||
|
||||
public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; }
|
||||
|
||||
public void Render(WorldRenderer wr)
|
||||
{
|
||||
renderer.Draw(wr.Screen3DPxPosition(Pos));
|
||||
}
|
||||
|
||||
public void RenderDebugGeometry(WorldRenderer wr)
|
||||
{
|
||||
var pos = wr.Screen3DPxPosition(Pos);
|
||||
var tl = wr.Viewport.WorldToViewPx(pos - r);
|
||||
var br = wr.Viewport.WorldToViewPx(pos + r);
|
||||
Game.Renderer.RgbaColorRenderer.DrawRect(tl, br, 1, Color.Red);
|
||||
}
|
||||
|
||||
public Rectangle ScreenBounds(WorldRenderer wr)
|
||||
{
|
||||
var pos = wr.Screen3DPxPosition(Pos);
|
||||
var tl = wr.Viewport.WorldToViewPx(pos - r);
|
||||
var br = wr.Viewport.WorldToViewPx(pos + r);
|
||||
return new Rectangle(tl.X, tl.Y, br.X - tl.X, br.Y - tl.Y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,9 +14,9 @@ using System.Linq;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Mods.Common.Graphics;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Mods.D2k.Graphics;
|
||||
using OpenRA.Mods.D2k.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.D2k.Projectiles
|
||||
@@ -30,9 +30,6 @@ namespace OpenRA.Mods.D2k.Projectiles
|
||||
[Desc("The number of ticks between the blast causing warhead impacts in its area of effect.")]
|
||||
public readonly int DamageInterval = 1;
|
||||
|
||||
[Desc("Equivalent to sequence ZOffset. Controls Z sorting.")]
|
||||
public readonly int ZOffset = 0;
|
||||
|
||||
[Desc("The minimum distance the blast travels.")]
|
||||
public readonly WDist MinDistance = WDist.Zero;
|
||||
|
||||
@@ -57,9 +54,6 @@ namespace OpenRA.Mods.D2k.Projectiles
|
||||
[Desc("Can this projectile be blocked when hitting actors with an nameof(BlocksProjectiles) trait.")]
|
||||
public readonly bool Blockable = false;
|
||||
|
||||
[Desc("Color of the blast.")]
|
||||
public readonly Color Color = Color.SkyBlue;
|
||||
|
||||
public IProjectile Create(ProjectileArgs args)
|
||||
{
|
||||
return new SonicBlast(this, args);
|
||||
@@ -72,6 +66,7 @@ namespace OpenRA.Mods.D2k.Projectiles
|
||||
readonly ProjectileArgs args;
|
||||
|
||||
readonly WDist speed;
|
||||
readonly SonicBlastRenderer renderer;
|
||||
|
||||
[Sync]
|
||||
WPos pos, lastPos;
|
||||
@@ -85,6 +80,8 @@ namespace OpenRA.Mods.D2k.Projectiles
|
||||
this.info = info;
|
||||
this.args = args;
|
||||
var world = args.SourceActor.World;
|
||||
renderer = world.WorldActor.Trait<SonicBlastRenderer>();
|
||||
|
||||
if (info.Speed.Length > 1)
|
||||
speed = new WDist(world.SharedRandom.Next(info.Speed[0].Length, info.Speed[1].Length));
|
||||
else
|
||||
@@ -151,10 +148,7 @@ namespace OpenRA.Mods.D2k.Projectiles
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr)
|
||||
{
|
||||
if (!wr.World.FogObscures(pos))
|
||||
{
|
||||
var blastRender = new BeamRenderable(pos, info.ZOffset, lastPos - pos, BeamRenderableShape.Cylindrical, info.Width, info.Color);
|
||||
return new[] { (IRenderable)blastRender };
|
||||
}
|
||||
return new[] { (IRenderable)new SonicBlastRenderable(renderer, pos) };
|
||||
|
||||
return SpriteRenderable.None;
|
||||
}
|
||||
|
||||
96
OpenRA.Mods.D2k/Traits/World/SonicBlastRenderer.cs
Normal file
96
OpenRA.Mods.D2k/Traits/World/SonicBlastRenderer.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.D2k.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Renders sonic blasts")]
|
||||
public class SonicBlastRendererInfo : TraitInfo
|
||||
{
|
||||
[Desc("Diameter of the sonic effect circle.")]
|
||||
public readonly int Size = 16;
|
||||
|
||||
[Desc("Amount to scale the visuals within the effect circle.")]
|
||||
public readonly float Zoom = 2.5f;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new SonicBlastRenderer(this); }
|
||||
}
|
||||
|
||||
public sealed class SonicBlastRenderer : IRenderPostProcessPass, INotifyActorDisposing
|
||||
{
|
||||
public readonly SonicBlastRendererInfo Info;
|
||||
|
||||
readonly Renderer renderer;
|
||||
readonly IShader shader;
|
||||
readonly IVertexBuffer<RenderPostProcessPassTexturedVertex> buffer;
|
||||
readonly List<float3> positions = new();
|
||||
|
||||
public SonicBlastRenderer(SonicBlastRendererInfo info)
|
||||
{
|
||||
Info = info;
|
||||
renderer = Game.Renderer;
|
||||
shader = renderer.CreateShader(new RenderPostProcessPassTexturedShaderBindings("sonic"));
|
||||
buffer = renderer.CreateVertexBuffer<RenderPostProcessPassTexturedVertex>(6);
|
||||
|
||||
var r = 0.5f * info.Size;
|
||||
shader.SetVec("Scale", r * (1f / info.Zoom - 1));
|
||||
var vertices = new RenderPostProcessPassTexturedVertex[]
|
||||
{
|
||||
new(-r, -r, -1, -1),
|
||||
new(r, -r, 1, -1),
|
||||
new(r, r, 1, 1),
|
||||
new(r, r, 1, 1),
|
||||
new(-r, r, -1, 1),
|
||||
new(-r, -r, -1, -1)
|
||||
};
|
||||
|
||||
buffer.SetData(ref vertices, 6);
|
||||
}
|
||||
|
||||
public void Draw(float3 pos)
|
||||
{
|
||||
positions.Add(pos);
|
||||
}
|
||||
|
||||
PostProcessPassType IRenderPostProcessPass.Type => PostProcessPassType.AfterWorld;
|
||||
bool IRenderPostProcessPass.Enabled => positions.Count > 0;
|
||||
|
||||
void IRenderPostProcessPass.Draw(WorldRenderer wr)
|
||||
{
|
||||
var scroll = wr.Viewport.TopLeft;
|
||||
var size = renderer.WorldFrameBufferSize;
|
||||
var width = 2f / (renderer.WorldDownscaleFactor * size.Width);
|
||||
var height = 2f / (renderer.WorldDownscaleFactor * size.Height);
|
||||
|
||||
shader.SetVec("Scroll", scroll.X, scroll.Y);
|
||||
shader.SetVec("p1", width, height);
|
||||
shader.SetVec("p2", -1, -1);
|
||||
shader.SetTexture("WorldTexture", Game.Renderer.WorldBufferSnapshot());
|
||||
shader.PrepareRender();
|
||||
foreach (var pos in positions)
|
||||
{
|
||||
shader.SetVec("Pos", pos.X, pos.Y);
|
||||
renderer.DrawBatch(buffer, shader, 0, 6, PrimitiveType.TriangleList);
|
||||
}
|
||||
|
||||
positions.Clear();
|
||||
}
|
||||
|
||||
void INotifyActorDisposing.Disposing(Actor self)
|
||||
{
|
||||
buffer.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
18
glsl/postprocess_textured_sonic.frag
Normal file
18
glsl/postprocess_textured_sonic.frag
Normal file
@@ -0,0 +1,18 @@
|
||||
#version {VERSION}
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform sampler2D WorldTexture;
|
||||
uniform float Scale;
|
||||
|
||||
in vec2 vTexCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
if (dot(vTexCoord, vTexCoord) >= 1.0)
|
||||
discard;
|
||||
|
||||
fragColor = texelFetch(WorldTexture, ivec2(gl_FragCoord.xy + Scale * vTexCoord), 0);
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
TerrainGeometryOverlay:
|
||||
DebugVisualizations:
|
||||
TerrainRenderer:
|
||||
SonicBlastRenderer:
|
||||
ShroudRenderer:
|
||||
ShroudVariants: shrouda, shroudb, shroudc, shroudd
|
||||
FogVariants: foga, fogb, fogc, fogd
|
||||
|
||||
@@ -10,7 +10,6 @@ Sound:
|
||||
Falloff: 0, 0, 100, 0
|
||||
Range: 0, 0c512, 4c0, 6c0
|
||||
MinDistance: 5c0
|
||||
Color: 00FFFFC8
|
||||
Warhead@1Dam: SpreadDamage
|
||||
Falloff: 100, 0
|
||||
Spread: 1c756
|
||||
|
||||
Reference in New Issue
Block a user