Merge pull request #3683 from pchote/fancy-explosion-support

Add engine support for D2K explosions
This commit is contained in:
Matthias Mailänder
2013-08-14 08:22:13 -07:00
9 changed files with 55 additions and 26 deletions

View File

@@ -32,6 +32,8 @@ namespace OpenRA.FileFormats.Graphics
IGraphicsDevice Create( Size size, WindowMode windowMode ); IGraphicsDevice Create( Size size, WindowMode windowMode );
} }
public enum BlendMode { None, Alpha, Additive }
public interface IGraphicsDevice public interface IGraphicsDevice
{ {
IVertexBuffer<Vertex> CreateVertexBuffer( int length ); IVertexBuffer<Vertex> CreateVertexBuffer( int length );
@@ -55,8 +57,7 @@ namespace OpenRA.FileFormats.Graphics
void EnableDepthBuffer(); void EnableDepthBuffer();
void DisableDepthBuffer(); void DisableDepthBuffer();
void EnableAlphaBlending(); void SetBlendMode(BlendMode mode);
void DisableAlphaBlending();
} }
public interface IVertexBuffer<T> public interface IVertexBuffer<T>

View File

@@ -34,7 +34,7 @@ namespace OpenRA.Graphics
{ {
if (nv > 0) if (nv > 0)
{ {
renderer.Device.EnableAlphaBlending(); renderer.Device.SetBlendMode(BlendMode.Alpha);
shader.Render(() => shader.Render(() =>
{ {
var vb = renderer.GetTempVertexBuffer(); var vb = renderer.GetTempVertexBuffer();
@@ -42,7 +42,7 @@ namespace OpenRA.Graphics
renderer.SetLineWidth(LineWidth * Game.viewport.Zoom); renderer.SetLineWidth(LineWidth * Game.viewport.Zoom);
renderer.DrawBatch(vb, 0, nv, PrimitiveType.LineList); renderer.DrawBatch(vb, 0, nv, PrimitiveType.LineList);
}); });
renderer.Device.DisableAlphaBlending(); renderer.Device.SetBlendMode(BlendMode.None);
nv = 0; nv = 0;
} }
} }

View File

@@ -31,14 +31,14 @@ namespace OpenRA.Graphics
{ {
if (nv > 0) if (nv > 0)
{ {
renderer.Device.EnableAlphaBlending(); renderer.Device.SetBlendMode(BlendMode.Alpha);
shader.Render(() => shader.Render(() =>
{ {
var vb = renderer.GetTempVertexBuffer(); var vb = renderer.GetTempVertexBuffer();
vb.SetData(vertices, nv); vb.SetData(vertices, nv);
renderer.DrawBatch(vb, 0, nv, PrimitiveType.QuadList); renderer.DrawBatch(vb, 0, nv, PrimitiveType.QuadList);
}); });
renderer.Device.DisableAlphaBlending(); renderer.Device.SetBlendMode(BlendMode.None);
nv = 0; nv = 0;
} }

View File

@@ -12,6 +12,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.FileFormats; using OpenRA.FileFormats;
using OpenRA.FileFormats.Graphics;
namespace OpenRA.Graphics namespace OpenRA.Graphics
{ {
@@ -36,16 +37,20 @@ namespace OpenRA.Graphics
Name = name; Name = name;
var d = info.NodesDict; var d = info.NodesDict;
var offset = float2.Zero; var offset = float2.Zero;
var blendMode = BlendMode.Alpha;
Start = int.Parse(d["Start"].Value); Start = int.Parse(d["Start"].Value);
if (d.ContainsKey("Offset")) if (d.ContainsKey("Offset"))
offset = FieldLoader.GetValue<float2>("Offset", d["Offset"].Value); offset = FieldLoader.GetValue<float2>("Offset", d["Offset"].Value);
if (d.ContainsKey("BlendMode"))
blendMode = FieldLoader.GetValue<BlendMode>("BlendMode", d["BlendMode"].Value);
// Apply offset to each sprite in the sequence // Apply offset to each sprite in the sequence
// Different sequences may apply different offsets to the same frame // Different sequences may apply different offsets to the same frame
sprites = Game.modData.SpriteLoader.LoadAllSprites(srcOverride ?? unit).Select( sprites = Game.modData.SpriteLoader.LoadAllSprites(srcOverride ?? unit).Select(
s => new Sprite(s.sheet, s.bounds, s.offset + offset, s.channel)).ToArray(); s => new Sprite(s.sheet, s.bounds, s.offset + offset, s.channel, blendMode)).ToArray();
if (!d.ContainsKey("Length")) if (!d.ContainsKey("Length"))
Length = 1; Length = 1;

View File

@@ -10,6 +10,7 @@
using System; using System;
using System.Drawing; using System.Drawing;
using OpenRA.FileFormats.Graphics;
namespace OpenRA.Graphics namespace OpenRA.Graphics
{ {
@@ -105,7 +106,7 @@ namespace OpenRA.Graphics
p = new Point(0,0); p = new Point(0,0);
} }
var rect = new Sprite(current, new Rectangle(p, imageSize), spriteOffset, channel); var rect = new Sprite(current, new Rectangle(p, imageSize), spriteOffset, channel, BlendMode.Alpha);
p.X += imageSize.Width; p.X += imageSize.Width;
return rect; return rect;

View File

@@ -9,6 +9,7 @@
#endregion #endregion
using System.Drawing; using System.Drawing;
using OpenRA.FileFormats.Graphics;
namespace OpenRA.Graphics namespace OpenRA.Graphics
{ {
@@ -16,21 +17,26 @@ namespace OpenRA.Graphics
{ {
public readonly Rectangle bounds; public readonly Rectangle bounds;
public readonly Sheet sheet; public readonly Sheet sheet;
public readonly BlendMode blendMode;
public readonly TextureChannel channel; public readonly TextureChannel channel;
public readonly float2 size; public readonly float2 size;
public readonly float2 offset; public readonly float2 offset;
readonly float2[] textureCoords; readonly float2[] textureCoords;
public Sprite(Sheet sheet, Rectangle bounds, TextureChannel channel) public Sprite(Sheet sheet, Rectangle bounds, TextureChannel channel)
: this(sheet, bounds, float2.Zero, channel) {} : this(sheet, bounds, float2.Zero, channel, BlendMode.Alpha) {}
public Sprite(Sheet sheet, Rectangle bounds, float2 offset, TextureChannel channel) public Sprite(Sheet sheet, Rectangle bounds, TextureChannel channel, BlendMode blendMode)
: this(sheet, bounds, float2.Zero, channel, blendMode) {}
public Sprite(Sheet sheet, Rectangle bounds, float2 offset, TextureChannel channel, BlendMode blendMode)
{ {
this.sheet = sheet; this.sheet = sheet;
this.bounds = bounds; this.bounds = bounds;
this.offset = offset; this.offset = offset;
this.channel = channel; this.channel = channel;
this.size = new float2(bounds.Size); this.size = new float2(bounds.Size);
this.blendMode = blendMode;
var left = (float)(bounds.Left) / sheet.Size.Width; var left = (float)(bounds.Left) / sheet.Size.Width;
var top = (float)(bounds.Top) / sheet.Size.Height; var top = (float)(bounds.Top) / sheet.Size.Height;

View File

@@ -20,6 +20,7 @@ namespace OpenRA.Graphics
Vertex[] vertices = new Vertex[Renderer.TempBufferSize]; Vertex[] vertices = new Vertex[Renderer.TempBufferSize];
Sheet currentSheet = null; Sheet currentSheet = null;
BlendMode currentBlend = BlendMode.Alpha;
int nv = 0; int nv = 0;
public SpriteRenderer(Renderer renderer, IShader shader) public SpriteRenderer(Renderer renderer, IShader shader)
@@ -33,14 +34,15 @@ namespace OpenRA.Graphics
if (nv > 0) if (nv > 0)
{ {
shader.SetTexture("DiffuseTexture", currentSheet.Texture); shader.SetTexture("DiffuseTexture", currentSheet.Texture);
renderer.Device.EnableAlphaBlending();
renderer.Device.SetBlendMode(currentBlend);
shader.Render(() => shader.Render(() =>
{ {
var vb = renderer.GetTempVertexBuffer(); var vb = renderer.GetTempVertexBuffer();
vb.SetData(vertices, nv); vb.SetData(vertices, nv);
renderer.DrawBatch(vb, 0, nv, PrimitiveType.QuadList); renderer.DrawBatch(vb, 0, nv, PrimitiveType.QuadList);
}); });
renderer.Device.DisableAlphaBlending(); renderer.Device.SetBlendMode(BlendMode.None);
nv = 0; nv = 0;
currentSheet = null; currentSheet = null;
@@ -64,9 +66,13 @@ namespace OpenRA.Graphics
if (s.sheet != currentSheet) if (s.sheet != currentSheet)
Flush(); Flush();
if (s.blendMode != currentBlend)
Flush();
if (nv + 4 > Renderer.TempBufferSize) if (nv + 4 > Renderer.TempBufferSize)
Flush(); Flush();
currentBlend = s.blendMode;
currentSheet = s.sheet; currentSheet = s.sheet;
Util.FastCreateQuad(vertices, location + s.offset, s, paletteIndex, nv, size); Util.FastCreateQuad(vertices, location + s.offset, s, paletteIndex, nv, size);
nv += 4; nv += 4;
@@ -90,10 +96,14 @@ namespace OpenRA.Graphics
if (s.sheet != currentSheet) if (s.sheet != currentSheet)
Flush(); Flush();
if (s.blendMode != currentBlend)
Flush();
if (nv + 4 > Renderer.TempBufferSize) if (nv + 4 > Renderer.TempBufferSize)
Flush(); Flush();
currentSheet = s.sheet; currentSheet = s.sheet;
currentBlend = s.blendMode;
Util.FastCreateQuad(vertices, a, b, c, d, s, 0, nv); Util.FastCreateQuad(vertices, a, b, c, d, s, 0, nv);
nv += 4; nv += 4;
} }
@@ -101,9 +111,9 @@ namespace OpenRA.Graphics
public void DrawVertexBuffer(IVertexBuffer<Vertex> buffer, int start, int length, PrimitiveType type, Sheet sheet) public void DrawVertexBuffer(IVertexBuffer<Vertex> buffer, int start, int length, PrimitiveType type, Sheet sheet)
{ {
shader.SetTexture("DiffuseTexture", sheet.Texture); shader.SetTexture("DiffuseTexture", sheet.Texture);
renderer.Device.EnableAlphaBlending(); renderer.Device.SetBlendMode(BlendMode.Alpha);
shader.Render(() => renderer.DrawBatch(buffer, start, length, type)); shader.Render(() => renderer.DrawBatch(buffer, start, length, type));
renderer.Device.DisableAlphaBlending(); renderer.Device.SetBlendMode(BlendMode.None);
} }
public void SetPalette(ITexture palette) public void SetPalette(ITexture palette)

View File

@@ -41,8 +41,7 @@ namespace OpenRA.Renderer.Null
public void EnableDepthBuffer() { } public void EnableDepthBuffer() { }
public void DisableDepthBuffer() { } public void DisableDepthBuffer() { }
public void EnableAlphaBlending() { } public void SetBlendMode(BlendMode mode) { }
public void DisableAlphaBlending() { }
public void Clear() { } public void Clear() { }
public void Present() { } public void Present() { }

View File

@@ -147,17 +147,24 @@ namespace OpenRA.Renderer.SdlCommon
ErrorHandler.CheckGlError(); ErrorHandler.CheckGlError();
} }
public void EnableAlphaBlending() public void SetBlendMode(BlendMode mode)
{ {
Gl.glEnable(Gl.GL_BLEND); switch (mode)
ErrorHandler.CheckGlError(); {
Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA); case BlendMode.None:
ErrorHandler.CheckGlError(); Gl.glDisable(Gl.GL_BLEND);
} break;
case BlendMode.Alpha:
public void DisableAlphaBlending() Gl.glEnable(Gl.GL_BLEND);
{ ErrorHandler.CheckGlError();
Gl.glDisable(Gl.GL_BLEND); Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);
break;
case BlendMode.Additive:
Gl.glEnable(Gl.GL_BLEND);
ErrorHandler.CheckGlError();
Gl.glBlendFunc(Gl.GL_ONE, Gl.GL_ONE);
break;
}
ErrorHandler.CheckGlError(); ErrorHandler.CheckGlError();
} }