1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-06-20 22:25:24 +00:00

Rendering optimizations

This commit is contained in:
Tim Sarbin 2018-11-24 23:49:56 -05:00
parent 3a0cbe4b8e
commit 0803e5c223
4 changed files with 95 additions and 92 deletions

View File

@ -19,7 +19,6 @@ namespace OpenDiablo2.Common.Interfaces
void Quit();
ISprite LoadSprite(string resourcePath, string palette, Point location);
ISprite LoadSprite(string resourcePath, string palette);
ISprite GenerateMapCell(MPQDS1 mapData, int x, int y, eRenderCellType cellType, Palette palette);
IFont LoadFont(string resourcePath, string palette);
ILabel CreateLabel(IFont font);
ILabel CreateLabel(IFont font, string text);
@ -30,5 +29,6 @@ namespace OpenDiablo2.Common.Interfaces
void Draw(ISprite sprite, int frame);
void Draw(ISprite sprite, int xSegments, int ySegments, int offset);
void Draw(ILabel label);
void DrawMapCell(int xCell, int yCell, int xPixel, int yPixel, MPQDS1 mapData);
}
}

View File

@ -35,9 +35,7 @@ namespace OpenDiablo2.Core.Map_Engine
}
private ISprite loadingSprite;
private ISprite[] tempMapCell;
private int cellOffsetX, cellOffsetY, pixelOffsetX, pixelOffsetY;
//private ISprite[] tempMapCell;
private const int
cellSizeX = 160,
@ -66,6 +64,7 @@ namespace OpenDiablo2.Core.Map_Engine
private void LoadNewMapData()
{
/*
var cellsToLoad = gameState.MapData.Width * gameState.MapData.Height;
tempMapCell = new ISprite[cellsToLoad];
@ -84,7 +83,7 @@ namespace OpenDiablo2.Core.Map_Engine
gameState.CurrentPalette
);
}
*/
//CameraLocation = new Point(((gameState.MapData.Width * cellSizeX) / 2) - 400, ((gameState.MapData.Height * cellSizeY) / 2) - 300);
}
@ -96,21 +95,24 @@ namespace OpenDiablo2.Core.Map_Engine
for (int y = 0; y < gameState.MapData.Width; y++)
for (int x = 0; x < gameState.MapData.Height; x++)
{
RenderFloorCell(
(x + cellOffsetX),
(y + cellOffsetY),
((x - y) * 80) - cOffX,
((x + y) * 40) - cOffY
);
var visualX = ((x - y) * (cellSizeX / 2)) - cOffX;
var visualY = ((x + y) * (cellSizeY / 2)) - cOffY;
if (visualX < -160 || visualX > 800 || visualY < -80 || visualY > 600)
continue;
RenderFloorCell(x, y, ((x - y) * 80) - cOffX, ((x + y) * 40) - cOffY);
}
}
public void RenderFloorCell(int x, int y, int xp, int yp)
private void RenderFloorCell(int x, int y, int xp, int yp)
{
if (x < 0 || y < 0 || x >= gameState.MapData.Width || y >= gameState.MapData.Height)
return;
renderWindow.Draw(tempMapCell[x + (y * gameState.MapData.Width)], new Point(xp, yp));
renderWindow.DrawMapCell(x, y, xp, yp, gameState.MapData);
}
public void Update(long ms)

View File

@ -33,6 +33,8 @@ namespace OpenDiablo2.SDL2_
private readonly IPaletteProvider paletteProvider;
private readonly IResourceManager resourceManager;
private IntPtr cellTexture;
public SDL2RenderWindow(
IMPQProvider mpqProvider,
IPaletteProvider paletteProvider,
@ -59,6 +61,10 @@ namespace OpenDiablo2.SDL2_
SDL.SDL_SetRenderDrawBlendMode(renderer, SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
SDL.SDL_ShowCursor(0);
cellTexture = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING, 256, 256);
SDL.SDL_SetTextureBlendMode(cellTexture, SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
IsRunning = true;
}
@ -106,7 +112,7 @@ namespace OpenDiablo2.SDL2_
else if (evt.type == SDL.SDL_EventType.SDL_MOUSEBUTTONDOWN)
{
switch((uint)evt.button.button)
switch ((uint)evt.button.button)
{
case SDL.SDL_BUTTON_LEFT:
LeftMouseDown = true;
@ -271,7 +277,78 @@ namespace OpenDiablo2.SDL2_
SDL.SDL_RenderCopy(renderer, lbl.texture, IntPtr.Zero, ref destRect);
}
public ISprite GenerateMapCell(MPQDS1 mapData, int x, int y, eRenderCellType cellType, Palette palette)
=> new SDL2Sprite(this.renderer, palette, mapData, x, y, cellType);
public unsafe void DrawMapCell(int xCell, int yCell, int xPixel, int yPixel, MPQDS1 mapData)
{
var floorLayer = mapData.FloorLayers.First();
var floor = floorLayer.Props[xCell + (yCell * mapData.Width)];
if (floor.Prop1 == 0)
return;
var palette = paletteProvider.PaletteTable[$"ACT{mapData.Act}"];
var sub_index = floor.Prop2;
var main_index = (floor.Prop3 >> 4) + ((floor.Prop4 & 0x03) << 4);
MPQDT1Tile tile = null;
for (int i = 0; i < mapData.DT1s.Count(); i++)
{
if (mapData.DT1s[i] == null)
continue;
tile = mapData.DT1s[i].Tiles.FirstOrDefault(z => z.MainIndex == main_index && z.SubIndex == sub_index);
if (tile != null)
break;
}
if (tile == null)
throw new ApplicationException("Could not locate tile!");
var frameSize = new Size(tile.Width, Math.Abs(tile.Height));
var srcRect = new SDL.SDL_Rect { x = 0, y = 0, w = frameSize.Width, h = frameSize.Height };
var frameSizeMax = frameSize.Width * frameSize.Height;
SDL.SDL_LockTexture(cellTexture, ref srcRect, out IntPtr pixels, out int pitch);
try
{
UInt32* data = (UInt32*)pixels;
for (var i = 0; i < frameSizeMax; i++)
data[i] = 0x0;
var pitchChange = (pitch / 4);
foreach (var block in tile.Blocks)
{
for (int yy = 0; yy < 32; yy++)
{
var index = block.PositionX + ((block.PositionY + yy) * pitchChange);
for (int xx = 0; xx < 32; xx++)
{
index++;
if (index > frameSizeMax)
continue;
if (index < 0)
continue;
var color = palette.Colors[block.PixelData[xx + (yy * 32)]];
if ((color & 0xFFFFFF) > 0)
data[index] = color;
}
}
}
}
finally
{
SDL.SDL_UnlockTexture(cellTexture);
}
var dstRect = new SDL.SDL_Rect { x = xPixel, y = yPixel, w = frameSize.Width, h = frameSize.Height };
SDL.SDL_RenderCopy(renderer, cellTexture, ref srcRect, ref dstRect);
}
}
}

View File

@ -83,82 +83,6 @@ namespace OpenDiablo2.SDL2_
}
public unsafe SDL2Sprite(IntPtr renderer, Palette palette, MPQDS1 mapData, int x, int y, eRenderCellType cellType)
{
this.renderer = renderer;
var floorLayer = mapData.FloorLayers.First();
var floor = floorLayer.Props[x + (y * mapData.Width)];
if (floor.Prop1 == 0)
{
texture = IntPtr.Zero;
return;
}
var sub_index = floor.Prop2;
var main_index = (floor.Prop3 >> 4) + ((floor.Prop4 & 0x03) << 4);
MPQDT1Tile tile = null;
for (int i = 0; i < mapData.DT1s.Count(); i++)
{
if (mapData.DT1s[i] == null)
continue;
tile = mapData.DT1s[i].Tiles.FirstOrDefault(z => z.MainIndex == main_index && z.SubIndex == sub_index);
if (tile != null)
break;
}
if (tile == null)
throw new ApplicationException("Could not locate tile!");
FrameSize = new Size(tile.Width, Math.Abs(tile.Height));
TotalFrames = 1;
frame = 0;
IntPtr pixels;
int pitch;
texture = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING, FrameSize.Width, FrameSize.Height);
SDL.SDL_SetTextureBlendMode(texture, SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
if (texture == IntPtr.Zero)
throw new ApplicationException($"Unaple to initialize texture: {SDL.SDL_GetError()}");
SDL.SDL_LockTexture(texture, IntPtr.Zero, out pixels, out pitch);
try
{
UInt32* data = (UInt32*)pixels;
for (var i = 0; i < FrameSize.Width * FrameSize.Height; i++)
data[i] = 0x0;
foreach(var block in tile.Blocks)
{
for (int yy = 0; yy < 32; yy++)
{
for (int xx = 0; xx < 32; xx++)
{
var index = block.PositionX + xx + ((block.PositionY + yy) * (pitch / 4));
if (index > (FrameSize.Width * FrameSize.Height))
continue;
if (index < 0)
continue;
var color = palette.Colors[block.PixelData[xx + (yy * 32)]];
if ((color & 0xFFFFFF) > 0)
data[index] = color;
}
}
}
}
finally
{
SDL.SDL_UnlockTexture(texture);
}
}
internal Point GetRenderPoint()
{
return source == null