mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-01-13 04:46:38 -05:00
Rendering optimizations
This commit is contained in:
parent
3a0cbe4b8e
commit
0803e5c223
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user