1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-06-16 12:35:22 +00:00

Tons of performance gained.

This commit is contained in:
Tim Sarbin 2018-11-23 15:22:35 -05:00
parent 8f1d43863d
commit e348d7b1e1
5 changed files with 78 additions and 65 deletions

View File

@ -26,15 +26,15 @@ namespace OpenDiablo2.Common.Models
ImageData = new Int16[0];
}
public Color GetColor(int x, int y, Palette palette)
public UInt32 GetColor(int x, int y, Palette palette)
{
var index = ImageData[x + (y * Width)];
if (index == -1)
return Color.Transparent;
return 0;
var color = palette.Colors[(int)index];
var color = palette.Colors[index];
return Color.FromArgb(255, color.R, color.G, color.B);
return ((UInt32)255 << 24) + ((UInt32)color.R << 16) + ((UInt32)color.G << 8) + (UInt32)color.B;
}
}

View File

@ -13,6 +13,7 @@ namespace OpenDiablo2.Core
{
private readonly GlobalConfiguration globalConfiguration;
private readonly MPQ[] mpqs;
private Dictionary<string, int> mpqLookup = new Dictionary<string, int>();
public MPQProvider(GlobalConfiguration globalConfiguration)
{
@ -22,12 +23,22 @@ namespace OpenDiablo2.Core
.Where(x => !Path.GetFileName(x).StartsWith("patch"))
.Select(file => new MPQ(file))
.ToArray();
for(var i = 0; i < mpqs.Count(); i++)
{
foreach(var file in mpqs[i].Files)
{
mpqLookup[file.ToLower()] = i;
}
}
}
public IEnumerable<MPQ> GetMPQs() => mpqs;
public Stream GetStream(string fileName)
=> mpqs.First(x => x.Files.Any(z =>z.ToLower() == fileName.ToLower())).OpenFile(fileName);
{
return mpqs[mpqLookup[fileName.ToLower()]].OpenFile(fileName);
}
public IEnumerable<IEnumerable<string>> GetTextFile(string fileName)
{

View File

@ -111,8 +111,9 @@ namespace OpenDiablo2.SDL2_
h = font.sprite.FrameSize.Height
};
SDL.SDL_SetTextureColorMod(font.sprite.textures[character], TextColor.R, TextColor.G, TextColor.B);
SDL.SDL_RenderCopy(renderer, font.sprite.textures[character], IntPtr.Zero, ref rect);
font.sprite.Frame = character;
SDL.SDL_SetTextureColorMod(font.sprite.texture, TextColor.R, TextColor.G, TextColor.B);
SDL.SDL_RenderCopy(renderer, font.sprite.texture, IntPtr.Zero, ref rect);
}

View File

@ -70,6 +70,8 @@ namespace OpenDiablo2.SDL2_
public void Clear()
{
SDL.SDL_SetRenderTarget(renderer, IntPtr.Zero);
SDL.SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL.SDL_RenderClear(renderer);
}
@ -148,7 +150,7 @@ namespace OpenDiablo2.SDL2_
w = spr.FrameSize.Width,
h = spr.FrameSize.Height
};
SDL.SDL_RenderCopy(renderer, spr.textures[spr.Frame], IntPtr.Zero, ref destRect);
SDL.SDL_RenderCopy(renderer, spr.texture, IntPtr.Zero, ref destRect);
}
@ -162,9 +164,7 @@ namespace OpenDiablo2.SDL2_
for (var x = 0; x < xSegments; x++)
{
var textureIndex = x + (y * xSegments) + (offset * xSegments * ySegments);
textureIndex = Math.Min(spr.textures.Count() - 1, Math.Max(0, textureIndex));
if (textureIndex >= spr.textures.Count())
continue;
spr.Frame = Math.Min(spr.TotalFrames - 1, Math.Max(0, textureIndex));
var destRect = new SDL.SDL_Rect
{
@ -173,7 +173,7 @@ namespace OpenDiablo2.SDL2_
w = spr.FrameSize.Width,
h = spr.FrameSize.Height
};
SDL.SDL_RenderCopy(renderer, spr.textures[textureIndex], IntPtr.Zero, ref destRect);
SDL.SDL_RenderCopy(renderer, spr.texture, IntPtr.Zero, ref destRect);
}
}
}

View File

@ -1,14 +1,10 @@
using OpenDiablo2.Common.Interfaces;
using System;
using System.Collections.Generic;
using System;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SDL2;
using System.Runtime.InteropServices;
using OpenDiablo2.Common.Interfaces;
using OpenDiablo2.Common.Models;
using SDL2;
namespace OpenDiablo2.SDL2_
{
@ -16,16 +12,24 @@ namespace OpenDiablo2.SDL2_
{
static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
internal readonly ImageSet source;
private readonly IntPtr renderer;
internal IntPtr texture = IntPtr.Zero;
public Point Location { get; set; } = new Point();
public Size FrameSize { get; set; } = new Size();
private int frame;
private int frame = -1;
public int Frame
{
get => frame;
set
{
if (frame == value && texture != IntPtr.Zero)
return;
frame = Math.Max(0, Math.Min(value, TotalFrames));
LoadFrame(frame);
}
}
public int TotalFrames { get; internal set; }
@ -37,9 +41,7 @@ namespace OpenDiablo2.SDL2_
set
{
blend = value;
foreach (var texture in textures)
SDL.SDL_SetTextureBlendMode(texture, blend ? SDL.SDL_BlendMode.SDL_BLENDMODE_ADD : SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
SDL.SDL_SetTextureBlendMode(texture, blend ? SDL.SDL_BlendMode.SDL_BLENDMODE_ADD : SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
}
}
@ -53,9 +55,7 @@ namespace OpenDiablo2.SDL2_
UpdateTextureData();
}
}
internal readonly ImageSet source;
private readonly IntPtr renderer;
internal IntPtr[] textures = new IntPtr[0];
public SDL2Sprite(ImageSet source, IntPtr renderer)
{
@ -63,14 +63,8 @@ namespace OpenDiablo2.SDL2_
this.renderer = renderer;
this.TotalFrames = source.Frames.Count();
this.FrameSize = new Size(Pow2((int)source.Frames.Max(x => x.Width)), Pow2((int)source.Frames.Max(x => x.Height)));
this.textures = new IntPtr[TotalFrames];
for(var i = 0; i < this.textures.Count(); i++)
{
this.textures[i] = IntPtr.Zero;
}
TotalFrames = source.Frames.Count();
FrameSize = new Size(Pow2((int)source.Frames.Max(x => x.Width)), Pow2((int)source.Frames.Max(x => x.Height)));
}
internal Point GetRenderPoint()
@ -84,8 +78,16 @@ namespace OpenDiablo2.SDL2_
// TODO: This is slow. Make fix.
private void UpdateTextureData()
{
for (var i = 0; i < source.Frames.Count(); i++)
LoadFrame(i, renderer);
if (texture == IntPtr.Zero)
{
texture = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING, Pow2(FrameSize.Width), Pow2(FrameSize.Height));
if (texture == IntPtr.Zero)
throw new ApplicationException("Unaple to initialize texture.");
Frame = 0;
}
}
// TODO: Less dumb color correction
@ -97,39 +99,41 @@ namespace OpenDiablo2.SDL2_
(byte)Math.Min((float)source.B * 1.2, 255)
);
object bob = new object();
private void LoadFrame(int index, IntPtr renderer)
private unsafe void LoadFrame(int index)
{
var frame = source.Frames[index];
if (textures[index] == IntPtr.Zero)
textures[index] = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_TARGET, Pow2(FrameSize.Width), Pow2(FrameSize.Height));
IntPtr pixels;
int pitch;
var fullRect = new SDL.SDL_Rect { x = 0, y = 0, w = FrameSize.Width, h = FrameSize.Height };
SDL.SDL_SetTextureBlendMode(texture, blend ? SDL.SDL_BlendMode.SDL_BLENDMODE_ADD : SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
if (textures[index] == IntPtr.Zero)
throw new ApplicationException("Unaple to initialize texture.");
SDL.SDL_SetTextureBlendMode(textures[index], SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
SDL.SDL_SetRenderTarget(renderer, textures[index]);
SDL.SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL.SDL_RenderFillRect(renderer, IntPtr.Zero);
SDL.SDL_SetRenderTarget(renderer, IntPtr.Zero);
var binaryData = new UInt32[frame.Width * frame.Height];
for (var y = 0; y < frame.Height; y++)
SDL.SDL_LockTexture(texture, IntPtr.Zero, out pixels, out pitch);
try
{
for (int x = 0; x < frame.Width; x++)
UInt32* data = (UInt32*)pixels;
var frameOffset = FrameSize.Height - frame.Height;
for (var y = 0; y < FrameSize.Height; y++)
{
var palColor = frame.GetColor(x, (int)y, CurrentPalette);
//var col = AdjustColor(palColor);
binaryData[x + y * frame.Width] = (uint)palColor.ToArgb();
for (int x = 0; x < FrameSize.Width; x++)
{
if ((x >= frame.Width) || (y < frameOffset))
{
data[x + (y * (pitch / 4))] = 0;
continue;
}
var palColor = frame.GetColor(x, (int)(y - frameOffset), CurrentPalette);
//var col = AdjustColor(palColor);
data[x + (y * (pitch / 4))] = palColor;
}
}
}
var rect = new SDL.SDL_Rect { x = 0, y = FrameSize.Height - (int)frame.Height, w = (int)frame.Width, h = (int)frame.Height };
GCHandle pinnedArray = GCHandle.Alloc(binaryData, GCHandleType.Pinned);
SDL.SDL_UpdateTexture(textures[index], ref rect, pinnedArray.AddrOfPinnedObject(), (int)frame.Width * 4);
pinnedArray.Free();
finally
{
SDL.SDL_UnlockTexture(texture);
}
}
@ -144,10 +148,7 @@ namespace OpenDiablo2.SDL2_
public void Dispose()
{
foreach (var texture in textures)
{
SDL.SDL_DestroyTexture(texture);
}
SDL.SDL_DestroyTexture(texture);
}
}
}