Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion TombEditor/Controls/Panel3D/Panel3D.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ public bool DisablePickingForHiddenRooms

// Legacy rendering state
private WadRenderer _wadRenderer;
private ImportedGeometryRenderer _importedGeometryRenderer;
private RasterizerState _rasterizerStateDepthBias;
private GraphicsDevice _legacyDevice;
private RasterizerState _rasterizerWireframe;
Expand Down Expand Up @@ -243,6 +244,7 @@ protected override void Dispose(bool disposing)
_rasterizerStateDepthBias?.Dispose();
_currentContextMenu?.Dispose();
_wadRenderer?.Dispose();
_importedGeometryRenderer?.Dispose();
}
base.Dispose(disposing);
}
Expand Down Expand Up @@ -362,6 +364,10 @@ obj is Editor.HideSelectionEvent ||
obj is Editor.LevelChangedEvent)
_wadRenderer?.GarbageCollect();

if (obj is Editor.LoadedImportedGeometriesChangedEvent ||
obj is Editor.LevelChangedEvent)
_importedGeometryRenderer?.GarbageCollect();

// Update cursor
if (obj is Editor.ActionChangedEvent)
{
Expand Down Expand Up @@ -517,4 +523,4 @@ protected override void OnDraw()
DrawScene();
}
}
}
}
4 changes: 2 additions & 2 deletions TombEditor/Controls/Panel3D/Panel3DDraw.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1721,7 +1721,7 @@ private void DrawImportedGeometry(List<ImportedGeometryInstance> importedGeometr
var groups = importedGeometryToDraw.GroupBy(g => g.Model.UniqueID);
foreach (var group in groups)
{
var model = group.First().Model.DirectXModel;
var model = _importedGeometryRenderer.GetModel(group.First().Model);
if (model == null || model.Meshes == null || model.Meshes.Count == 0)
continue;

Expand Down Expand Up @@ -1787,7 +1787,7 @@ private void DrawImportedGeometry(List<ImportedGeometryInstance> importedGeometr
if (texture != null && texture is ImportedGeometryTexture)
{
geometryEffect.Parameters["TextureEnabled"].SetValue(true);
geometryEffect.Parameters["Texture"].SetResource(((ImportedGeometryTexture)texture).DirectXTexture);
geometryEffect.Parameters["Texture"].SetResource(_importedGeometryRenderer.GetTexture((ImportedGeometryTexture)texture));
geometryEffect.Parameters["ReciprocalTextureSize"].SetValue(new Vector2(1.0f / texture.Image.Width, 1.0f / texture.Image.Height));
}
else
Expand Down
1 change: 1 addition & 0 deletions TombEditor/Controls/Panel3D/Panel3DInit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public override void InitializeRendering(RenderingDevice device, bool antialias,
};

_wadRenderer = new WadRenderer(_legacyDevice, true, true, atlasSize, maxAllocationSize, false);
_importedGeometryRenderer = new ImportedGeometryRenderer(_legacyDevice);
// Initialize vertex buffers
_ghostBlockVertexBuffer = SharpDX.Toolkit.Graphics.Buffer.Vertex.New<SolidVertex>(_legacyDevice, 84);
_boxVertexBuffer = new BoundingBox(new Vector3(-_littleCubeRadius), new Vector3(_littleCubeRadius)).GetVertexBuffer(_legacyDevice);
Expand Down
6 changes: 5 additions & 1 deletion TombLib/TombLib.Forms/Controls/OffscreenItemRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class OffscreenItemRenderer : IDisposable
private readonly Dx11RenderingDevice _device;
private readonly GraphicsDevice _legacyDevice;
private readonly WadRenderer _wadRenderer;
private readonly ImportedGeometryRenderer _importedGeometryRenderer;

private Texture2D _renderTarget;
private RenderTargetView _renderTargetView;
Expand All @@ -34,6 +35,7 @@ public OffscreenItemRenderer()
_device = (Dx11RenderingDevice)DeviceManager.DefaultDeviceManager.Device;
_legacyDevice = DeviceManager.DefaultDeviceManager.___LegacyDevice;
_wadRenderer = new WadRenderer(_legacyDevice, true, true, 1024, 512, false);
_importedGeometryRenderer = new ImportedGeometryRenderer(_legacyDevice);
}

public ImageC RenderThumbnail(IWadObject wadObject, TRVersion.Game version, Vector4 backColor, int size = 128)
Expand Down Expand Up @@ -66,7 +68,7 @@ public ImageC RenderThumbnail(IWadObject wadObject, TRVersion.Game version, Vect
var viewProjection = camera.GetViewProjectionMatrix(size, size);

// Render the object using shared helper.
WadObjectRenderHelper.RenderObject(wadObject, _wadRenderer, _legacyDevice, viewProjection, camera.GetPosition(), false);
WadObjectRenderHelper.RenderObject(wadObject, _wadRenderer, _importedGeometryRenderer, _legacyDevice, viewProjection, camera.GetPosition(), false);

// Read back pixels.
return ReadPixels(size);
Expand Down Expand Up @@ -188,12 +190,14 @@ private void DisposeRenderTargets()
public void GarbageCollect()
{
_wadRenderer?.GarbageCollect();
_importedGeometryRenderer?.GarbageCollect();
}

public void Dispose()
{
DisposeRenderTargets();
_wadRenderer?.Dispose();
_importedGeometryRenderer?.Dispose();
}
}
}
8 changes: 6 additions & 2 deletions TombLib/TombLib.Forms/Controls/PanelItemPreview.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public bool AnimatePreview
// Legacy rendering state
private GraphicsDevice _legacyDevice;
private WadRenderer _wadRenderer;
private ImportedGeometryRenderer _importedGeometryRenderer;

public PanelItemPreview()
{
Expand Down Expand Up @@ -135,6 +136,7 @@ public override void InitializeRendering(RenderingDevice device, bool antialias
// Reset scrollbar
_legacyDevice = DeviceManager.DefaultDeviceManager.___LegacyDevice;
_wadRenderer = new WadRenderer(DeviceManager.DefaultDeviceManager.___LegacyDevice, true, true, 1024, 512, false);
_importedGeometryRenderer = new ImportedGeometryRenderer(_legacyDevice);

ResetCamera();

Expand Down Expand Up @@ -167,6 +169,7 @@ public void ResetCamera()
public void GarbageCollect()
{
_wadRenderer?.GarbageCollect();
_importedGeometryRenderer?.GarbageCollect();
}

private bool ValidObject(IWadObject obj)
Expand Down Expand Up @@ -201,6 +204,7 @@ protected override void Dispose(bool disposing)
if (disposing)
{
_wadRenderer?.Dispose();
_importedGeometryRenderer?.Dispose();
_textureAllocator?.Dispose();
}
base.Dispose(disposing);
Expand Down Expand Up @@ -245,7 +249,7 @@ protected override void OnDraw()
}
else
{
WadObjectRenderHelper.RenderObject(CurrentObject, _wadRenderer, _legacyDevice, viewProjection, Camera.GetPosition(), DrawTransparency);
WadObjectRenderHelper.RenderObject(CurrentObject, _wadRenderer, _importedGeometryRenderer, _legacyDevice, viewProjection, Camera.GetPosition(), DrawTransparency);
}
}

Expand Down Expand Up @@ -328,4 +332,4 @@ protected override void OnMouseMove(MouseEventArgs e)
public abstract float NavigationSpeedMouseRotate { get; }
public abstract bool ReadOnly { get; }
}
}
}
10 changes: 5 additions & 5 deletions TombLib/TombLib.Forms/Controls/WadObjectRenderHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,15 @@ public static ArcBallCamera CreateCameraForObject(IWadObject wadObject, WadRende
-(float)Math.PI / 2, (float)Math.PI / 2, radius * 3, 50, 1000000, fieldOfView * (float)(Math.PI / 180));
}

public static void RenderObject(IWadObject wadObject, WadRenderer wadRenderer,
public static void RenderObject(IWadObject wadObject, WadRenderer wadRenderer, ImportedGeometryRenderer importedGeometryRenderer,
GraphicsDevice legacyDevice, Matrix4x4 viewProjection, Vector3 cameraPosition, bool drawTransparency)
{
if (wadObject is WadMoveable moveable)
RenderMoveable(moveable, wadRenderer, legacyDevice, viewProjection, cameraPosition, drawTransparency);
else if (wadObject is WadStatic staticObj)
RenderStatic(staticObj, wadRenderer, legacyDevice, viewProjection, cameraPosition, drawTransparency);
else if (wadObject is ImportedGeometry impGeo)
RenderImportedGeometry(impGeo, legacyDevice, viewProjection, cameraPosition, drawTransparency);
RenderImportedGeometry(impGeo, importedGeometryRenderer, legacyDevice, viewProjection, cameraPosition, drawTransparency);
}

public static void RenderMoveable(WadMoveable moveable, WadRenderer wadRenderer,
Expand Down Expand Up @@ -206,10 +206,10 @@ public static void RenderStatic(WadStatic staticObj, WadRenderer wadRenderer,
}
}

public static void RenderImportedGeometry(ImportedGeometry geo,
public static void RenderImportedGeometry(ImportedGeometry geo, ImportedGeometryRenderer importedGeometryRenderer,
GraphicsDevice legacyDevice, Matrix4x4 viewProjection, Vector3 cameraPosition, bool drawTransparency)
{
var model = geo.DirectXModel;
var model = importedGeometryRenderer.GetModel(geo);
if (model == null || model.Meshes == null || model.Meshes.Count == 0)
return;

Expand Down Expand Up @@ -240,7 +240,7 @@ public static void RenderImportedGeometry(ImportedGeometry geo,
if (texture != null && texture is ImportedGeometryTexture)
{
effect.Parameters["TextureEnabled"].SetValue(true);
effect.Parameters["Texture"].SetResource(((ImportedGeometryTexture)texture).DirectXTexture);
effect.Parameters["Texture"].SetResource(importedGeometryRenderer.GetTexture((ImportedGeometryTexture)texture));
effect.Parameters["ReciprocalTextureSize"].SetValue(new Vector2(1.0f / texture.Image.Width, 1.0f / texture.Image.Height));
}
else
Expand Down
1 change: 0 additions & 1 deletion TombLib/TombLib.Rendering/Graphics/DeviceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ public DeviceManager()
// Recreate legacy environment
{
___LegacyDevice = GraphicsDevice.New(((Rendering.DirectX11.Dx11RenderingDevice)Device).Device);
LevelData.ImportedGeometry.Device = ___LegacyDevice;

// Load legacy effects
string dir = Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().Location) + "\\Rendering\\Legacy";
Expand Down
83 changes: 83 additions & 0 deletions TombLib/TombLib.Test/ImportedGeometryTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System;
using System.IO;
using System.Numerics;
using TombLib.Graphics;
using TombLib.LevelData;
using TombLib.Utils;

namespace TombLib.Test;

[TestClass]
public class ImportedGeometryTests
{
[TestMethod]
public void UpdateBuffers_UpdatesBoundingBoxesAndVersion()
{
var model = new ImportedGeometry.Model(1.0f);
var material = new Material("TestMaterial");
model.Materials.Add(material);

var mesh = new ImportedGeometryMesh("TestMesh");
mesh.Vertices.Add(CreateVertex(new Vector3(0.0f, 0.0f, 0.0f)));
mesh.Vertices.Add(CreateVertex(new Vector3(1024.0f, 0.0f, 0.0f)));
mesh.Vertices.Add(CreateVertex(new Vector3(0.0f, 1024.0f, 0.0f)));

var submesh = new Submesh(material);
submesh.Indices.AddRange(new[] { 0, 1, 2 });
mesh.Submeshes.Add(material, submesh);
model.Meshes.Add(mesh);

model.UpdateBuffers();
var firstVersion = model.Version;

Assert.AreEqual(new Vector3(0.0f, 0.0f, 0.0f), mesh.BoundingBox.Minimum);
Assert.AreEqual(new Vector3(1024.0f, 1024.0f, 0.0f), mesh.BoundingBox.Maximum);
Assert.AreEqual(mesh.BoundingBox.Minimum, model.BoundingBox.Minimum);
Assert.AreEqual(mesh.BoundingBox.Maximum, model.BoundingBox.Maximum);
CollectionAssert.AreEqual(new[] { 0, 1, 2 }, mesh.Indices);

mesh.Vertices[0] = CreateVertex(new Vector3(-1024.0f, 0.0f, 0.0f));
model.UpdateBuffers();

Assert.IsTrue(model.Version > firstVersion);
Assert.AreEqual(new Vector3(-1024.0f, 0.0f, 0.0f), model.BoundingBox.Minimum);
Assert.AreEqual(new Vector3(1024.0f, 1024.0f, 0.0f), model.BoundingBox.Maximum);
}

[TestMethod]
public void Assign_UpdatesTextureVersion()
{
var fileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".png");
ImageC.CreateNew(2, 2).SaveToFile(fileName);

try
{
var original = new ImportedGeometryTexture(fileName);
var reloaded = new ImportedGeometryTexture(fileName);
var originalVersion = original.Version;

original.Assign(reloaded);

Assert.IsTrue(original.Version > originalVersion);
Assert.AreEqual(reloaded.AbsolutePath, original.AbsolutePath);
Assert.AreEqual(reloaded.Image.Width, original.Image.Width);
Assert.AreEqual(reloaded.Image.Height, original.Image.Height);
}
finally
{
if (File.Exists(fileName))
File.Delete(fileName);
}
}

private static ImportedGeometryVertex CreateVertex(Vector3 position)
{
return new ImportedGeometryVertex
{
Position = position,
UV = Vector2.Zero,
Color = Vector3.One,
Normal = Vector3.UnitY
};
}
}
Loading