Skip to content

Commit

Permalink
Add back some missing functionalities from ISpriteDrawing
Browse files Browse the repository at this point in the history
  • Loading branch information
Xeeynamo committed Jun 2, 2020
1 parent 6abb324 commit 17da8a7
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 41 deletions.
5 changes: 3 additions & 2 deletions OpenKh.Engine/Extensions/SpriteDrawingExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ public static void FillRectangle(this ISpriteDrawing drawing, float x, float y,
drawing.AppendSprite(new SpriteDrawingContext()
.Source(0, 0, 1, 1)
.Position(x, y)
.DestinationSize(width, height));
.DestinationSize(width, height)
.Color(color));
}

public static void DrawRectangle(this ISpriteDrawing drawing, float x, float y, float width, float height, ColorF color, float thickness = 1.0f)
{
drawing.FillRectangle(x, y, width, thickness, color);
drawing.FillRectangle(x, y + height - 1, width + width - 1, thickness, color);
drawing.FillRectangle(x, y + height - 1, width - 1, thickness, color);
drawing.FillRectangle(x, y, thickness, height, color);
drawing.FillRectangle(x + width - 1, y, thickness, height, color);
}
Expand Down
12 changes: 10 additions & 2 deletions OpenKh.Game/MonoSpriteDrawing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using OpenKh.Engine.Renders;
using OpenKh.Game.Shaders;
using OpenKh.Imaging;
using System.Linq;

namespace OpenKh.Game
{
Expand Down Expand Up @@ -58,10 +59,12 @@ public MyVertex(Vector3 position, ColorF color, Vector2 textureCoordinate)

// This size should be enough to pack enough 2D graphics at once
private const int MaxSpriteCountPerDraw = 8000;
private static readonly byte[] WhiteBitmap = Enumerable.Range(0, 2 * 2 * sizeof(int)).Select(x => byte.MaxValue).ToArray();

private readonly GraphicsDevice _graphicsDevice;
private readonly KingdomShader _shader;

private readonly Texture2D _defaultTexture;
private readonly BlendState _blendState;
private readonly SamplerState _samplerState;
private readonly RasterizerState _rasterizerState;
Expand All @@ -79,6 +82,9 @@ public MonoSpriteDrawing(GraphicsDevice graphicsDevice, KingdomShader shader)
_graphicsDevice = graphicsDevice;
_shader = shader;

_defaultTexture = new Texture2D(_graphicsDevice, 2, 2);
_defaultTexture.SetData(WhiteBitmap);

_blendState = BlendState.NonPremultiplied;
_samplerState = new SamplerState
{
Expand Down Expand Up @@ -110,6 +116,7 @@ public MonoSpriteDrawing(GraphicsDevice graphicsDevice, KingdomShader shader)

public void Dispose()
{
_defaultTexture?.Dispose();
_vertexBuffer.Dispose();
_indexBuffer.Dispose();
}
Expand Down Expand Up @@ -139,8 +146,8 @@ public void AppendSprite(SpriteDrawingContext context)
var texture = (context.SpriteTexture as CSpriteTexture)?.Texture;
var vertexIndex = PrepareVertices(texture);

var tw = 1.0f / texture.Width;
var th = 1.0f / texture.Height;
var tw = 1.0f / _lastTextureUsed.Width;
var th = 1.0f / _lastTextureUsed.Height;

_vertices[vertexIndex + 0].Position = new Vector3(context.DestinationX, context.DestinationY, 0.0f);
_vertices[vertexIndex + 0].Color = context.Color0;
Expand Down Expand Up @@ -193,6 +200,7 @@ public void Flush()

private int PrepareVertices(Texture2D texture)
{
texture ??= _defaultTexture;
if (_lastTextureUsed != texture)
{
Flush();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

// Took from Xe.Drawing.Direct3D and transported to OpenKH under the same developer

using OpenKh.Engine.Renders;
using SharpDX.D3DCompiler;
using SharpDX.Direct3D;
using System;
Expand All @@ -41,10 +42,15 @@ namespace OpenKh.Tools.Common.Rendering

public partial class SpriteDrawingDirect3D
{
private CDevice _device = new CDevice();
private static readonly byte[] WhiteBitmap = Enumerable.Range(0, 2 * 2 * sizeof(int)).Select(x => byte.MaxValue).ToArray();

private readonly CDevice _device;
private readonly ISpriteTexture _defaultTexture;

public SpriteDrawingDirect3D()
{
_device = new CDevice();
_defaultTexture = CreateSpriteTexture(2, 2, WhiteBitmap);
}

public d3d.Device5 Device => _device.Device;
Expand Down
20 changes: 11 additions & 9 deletions OpenKh.Tools.Common/Rendering/SpriteDrawingDirect3D.Drawing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ private struct Vertex

public void AppendSprite(SpriteDrawingContext context)
{
var width = context.SpriteTexture.Width;
var height = context.SpriteTexture.Height;
SetTextureToDraw(context.SpriteTexture);
var width = _currentTexture.Width;
var height = _currentTexture.Height;
var viewport = _viewportSize;
var index = RequestVertices(4);
var buffer = _dataBuffer;
SetTextureToDraw(context.SpriteTexture);

buffer[index++] = new Vertex()
{
Expand Down Expand Up @@ -94,15 +94,17 @@ public void AppendSprite(SpriteDrawingContext context)
};
}

private CSpriteTexture _prevSurface;
private void SetTextureToDraw(ISpriteTexture surface)
private CSpriteTexture _currentTexture;
private void SetTextureToDraw(ISpriteTexture texture)
{
if (_prevSurface != surface)
if (_currentTexture != texture)
{
Flush();
var internalSurface = surface as CSpriteTexture;
Context.PixelShader.SetShaderResource(0, internalSurface?.ShaderResourceView);
_prevSurface = internalSurface;

texture ??= _defaultTexture;
var internalTexture = texture as CSpriteTexture;
Context.PixelShader.SetShaderResource(0, internalTexture?.ShaderResourceView);
_currentTexture = internalTexture;
}
}

Expand Down
57 changes: 30 additions & 27 deletions OpenKh.Tools.Common/Rendering/SpriteDrawingDirect3D.Surface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

using OpenKh.Engine.Renders;
using OpenKh.Imaging;
using SharpDX.D3DCompiler;
using SharpDX.IO;
using System;
using System.Drawing;
Expand Down Expand Up @@ -236,18 +237,20 @@ public void Save(string filename)
}
}

public ISpriteTexture CreateSpriteTexture(IImageRead image)
public ISpriteTexture CreateSpriteTexture(IImageRead image) =>
CreateSpriteTexture(image.Size.Width, image.Size.Height, image.ToBgra32());

public ISpriteTexture CreateSpriteTexture(int width, int height)
{
var size = image.Size;
if (size.Width <= 0 || size.Width > 65536)
throw new ArgumentOutOfRangeException(nameof(size.Width), "Must be between 1 and 65536");
if (size.Height <= 0 || size.Height > 65536)
throw new ArgumentOutOfRangeException(nameof(size.Height), "Must be between 1 and 65536");
if (width <= 0 || width > 65536)
throw new ArgumentOutOfRangeException(nameof(width), "Must be between 1 and 65536");
if (height <= 0 || height > 65536)
throw new ArgumentOutOfRangeException(nameof(height), "Must be between 1 and 65536");

var desc = new d3d.Texture2DDescription
{
Width = size.Width,
Height = size.Height,
Width = width,
Height = height,
MipLevels = 1,
ArraySize = 1,
Format = dxgi.Format.B8G8R8A8_UNorm,
Expand All @@ -256,17 +259,23 @@ public ISpriteTexture CreateSpriteTexture(IImageRead image)
SampleDescription = new dxgi.SampleDescription(1, 0)
};

desc.Usage = d3d.ResourceUsage.Immutable;
desc.BindFlags = d3d.BindFlags.ShaderResource;
desc.Usage = d3d.ResourceUsage.Default;
desc.BindFlags = d3d.BindFlags.ShaderResource | d3d.BindFlags.RenderTarget;

var srcDataPtr = Marshal.UnsafeAddrOfPinnedArrayElement(image.ToBgra32(), 0);
var dataSource = new SharpDX.DataRectangle(srcDataPtr, size.Width * sizeof(int));
var texture = new d3d.Texture2D(Device, desc, new[] { dataSource });
var texture = new d3d.Texture2D(Device, desc);
var shaderResourceView = new d3d.ShaderResourceView(Device, texture);
return new CSpriteTexture(texture, shaderResourceView);
}

public ISpriteTexture CreateSpriteTexture(int width, int height)

public ISpriteTexture CreateSpriteTexture(string filename, Color[] filterColors = null)
{
var bitmap = TextureLoader.LoadBitmap(new wic.ImagingFactory2(), filename);
var texture = TextureLoader.CreateTexture2DFromBitmap(Device, bitmap, filterColors);
d3d.ShaderResourceView shaderResourceView = new d3d.ShaderResourceView(Device, texture);
return new CSpriteTexture(texture, shaderResourceView);
}

public ISpriteTexture CreateSpriteTexture(int width, int height, byte[] data)
{
if (width <= 0 || width > 65536)
throw new ArgumentOutOfRangeException(nameof(width), "Must be between 1 and 65536");
Expand All @@ -285,20 +294,14 @@ public ISpriteTexture CreateSpriteTexture(int width, int height)
SampleDescription = new dxgi.SampleDescription(1, 0)
};

desc.Usage = d3d.ResourceUsage.Default;
desc.BindFlags = d3d.BindFlags.ShaderResource | d3d.BindFlags.RenderTarget;
desc.Usage = d3d.ResourceUsage.Immutable;
desc.BindFlags = d3d.BindFlags.ShaderResource;

var texture = new d3d.Texture2D(Device, desc);
var srcDataPtr = Marshal.UnsafeAddrOfPinnedArrayElement(data, 0);
var dataSource = new SharpDX.DataRectangle(srcDataPtr, width * sizeof(int));
var texture = new d3d.Texture2D(Device, desc, new[] { dataSource });
var shaderResourceView = new d3d.ShaderResourceView(Device, texture);
return new CSpriteTexture(texture, shaderResourceView);
}

public ISpriteTexture CreateSurface(string filename, Color[] filterColors = null)
{
var bitmap = TextureLoader.LoadBitmap(new wic.ImagingFactory2(), filename);
var texture = TextureLoader.CreateTexture2DFromBitmap(Device, bitmap, filterColors);
d3d.ShaderResourceView shaderResourceView = new d3d.ShaderResourceView(Device, texture);
return new CSpriteTexture(texture, shaderResourceView);
}
}
}
}

0 comments on commit 17da8a7

Please sign in to comment.