From 6f3ca13f567cc9977b9d56849a687d1cb6f706c8 Mon Sep 17 00:00:00 2001 From: Wayfarer Date: Fri, 24 Jan 2025 18:53:28 +0100 Subject: [PATCH] Some houseworking in the tests, Work on my renderer --- CommonLibraryTests/DataFormatterTests.cs | 6 +- CommonLibraryTests/MemoryVaultTests.cs | 30 +++++-- CommonLibraryTests/ProjectionCamera.cs | 39 -------- CommonLibraryTests/Projections.cs | 37 -------- CommonLibraryTests/RenderingTests.cs | 90 ------------------- RenderEngine/PixelData.cs | 11 +++ RenderEngine/ShaderResources.cs | 4 +- RenderEngine/TKRender.xaml.cs | 108 +++++++++++++++-------- 8 files changed, 112 insertions(+), 213 deletions(-) delete mode 100644 CommonLibraryTests/ProjectionCamera.cs delete mode 100644 CommonLibraryTests/RenderingTests.cs create mode 100644 RenderEngine/PixelData.cs diff --git a/CommonLibraryTests/DataFormatterTests.cs b/CommonLibraryTests/DataFormatterTests.cs index 287b0824..635c11ce 100644 --- a/CommonLibraryTests/DataFormatterTests.cs +++ b/CommonLibraryTests/DataFormatterTests.cs @@ -135,9 +135,9 @@ public void GetFileEncodingUtf8FileReturnsAnsi8Encoding() public void ReadCsvWithLayerKeywords_ReturnsCorrectLayers() { // Arrange - var filepath = "test.csv"; - var separator = ','; - var layerKeyword = "Layer_"; + const string filepath = "test.csv"; + const char separator = ','; + const string layerKeyword = "Layer_"; // Create test CSV content var csvContent = new List diff --git a/CommonLibraryTests/MemoryVaultTests.cs b/CommonLibraryTests/MemoryVaultTests.cs index 8d3f4548..6d46381d 100644 --- a/CommonLibraryTests/MemoryVaultTests.cs +++ b/CommonLibraryTests/MemoryVaultTests.cs @@ -13,6 +13,9 @@ namespace CommonLibraryTests { + /// + /// Some basic tests for Memory Vault + /// [TestClass] public class MemoryVaultTests { @@ -24,8 +27,11 @@ public void TestInitialize() _vault = MemoryVault.Instance; } + /// + /// Adds the data should return identifier. + /// [TestMethod] - public void AddData_ShouldReturnIdentifier() + public void AddDataShouldReturnIdentifier() { // Arrange var data = "TestData"; @@ -37,8 +43,11 @@ public void AddData_ShouldReturnIdentifier() Assert.AreNotEqual(-1, identifier); } + /// + /// Gets the data should return correct data. + /// [TestMethod] - public void GetData_ShouldReturnCorrectData() + public void GetDataShouldReturnCorrectData() { // Arrange var data = "TestData"; @@ -51,8 +60,11 @@ public void GetData_ShouldReturnCorrectData() Assert.AreEqual(data, retrievedData); } + /// + /// Removes the data should remove correct item. + /// [TestMethod] - public void RemoveData_ShouldRemoveCorrectItem() + public void RemoveDataShouldRemoveCorrectItem() { // Arrange var data = "TestData"; @@ -71,7 +83,7 @@ public void RemoveData_ShouldRemoveCorrectItem() /// Adds the metadata should store metadata correctly. /// [TestMethod] - public void AddMetadata_ShouldStoreMetadataCorrectly() + public void AddMetadataShouldStoreMetadataCorrectly() { // Arrange var data = "TestData"; @@ -91,8 +103,11 @@ public void AddMetadata_ShouldStoreMetadataCorrectly() Assert.AreEqual(metadata.Identifier, retrievedMetadata.Identifier); } + /// + /// Saves the should persist data. + /// [TestMethod] - public void Save_ShouldPersistData() + public void SaveShouldPersistData() { // Arrange var data = "TestData"; @@ -113,8 +128,11 @@ public void Save_ShouldPersistData() Assert.AreEqual(data, retrievedData); } + /// + /// Saves the should persist expired data correctly. + /// [TestMethod] - public void Save_ShouldPersistExpiredDataCorrectly() + public void SaveShouldPersistExpiredDataCorrectly() { // Arrange var data = "TestData"; diff --git a/CommonLibraryTests/ProjectionCamera.cs b/CommonLibraryTests/ProjectionCamera.cs deleted file mode 100644 index fc200c27..00000000 --- a/CommonLibraryTests/ProjectionCamera.cs +++ /dev/null @@ -1,39 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: CommonLibraryTests - * FILE: CommonLibraryTests/ProjectionCamera.cs - * PURPOSE: Tests for the Camera and the whole set - * PROGRAMER: Peter Geinitz (Wayfarer) - */ - -using Mathematics; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace CommonLibraryTests -{ - [TestClass] - public class ProjectionCamera - { - /// - /// Cameras this instance. - /// - [TestMethod] - public void Camera() - { - var objFile = ResourceObjects.GetCube(); - var triangles = PolyTriangle.CreateTri(objFile); - - var translation = new Vector3D { X = 0, Y = 0, Z = 5 }; - - var transform = Transform.GetInstance(translation, Vector3D.UnitVector, Vector3D.ZeroVector); - transform.CameraType = Cameras.Orbit; - transform.DisplayType = Display.Normal; - - var projection = new Projection(); - - _ = projection.Generate(triangles, transform); - - transform.LeftCamera(0.5); - } - } -} diff --git a/CommonLibraryTests/Projections.cs b/CommonLibraryTests/Projections.cs index 3e0fa25b..2b5594eb 100644 --- a/CommonLibraryTests/Projections.cs +++ b/CommonLibraryTests/Projections.cs @@ -242,43 +242,6 @@ public void ModelMatrix() Assert.IsTrue(check, "Vector not converted"); } - [TestMethod] - public void LeftRightBug() - { - var triangles = GenerateCube(); - - var transform = Transform.GetInstance(); - var transform1 = Transform.GetInstance(); - var transform2 = Transform.GetInstance(); - - var cache = new List(triangles); - - transform1.CameraType = transform2.CameraType = transform.CameraType = Cameras.Orbit; - - transform1.DisplayType = transform2.DisplayType = transform.DisplayType = Display.Normal; - - - transform1.LeftCamera(0.5); - transform2.RightCamera(0.5); - - var raster = new Projection { Debug = false }; - var reference = raster.Generate(cache, transform); - var left = raster.Generate(cache, transform1); - var right = raster.Generate(cache, transform1); - - Trace.WriteLine("Details:"); - - for (var i = 0; i < reference.Count; i++) - { - Trace.WriteLine("Base:"); - Trace.WriteLine(reference[i].ToString()); - Trace.WriteLine("left:"); - Trace.WriteLine(left[i].ToString()); - Trace.WriteLine("Right:"); - Trace.WriteLine(right[i].ToString()); - } - } - /// /// Multiplies the matrix vector. /// diff --git a/CommonLibraryTests/RenderingTests.cs b/CommonLibraryTests/RenderingTests.cs deleted file mode 100644 index deb0a180..00000000 --- a/CommonLibraryTests/RenderingTests.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using Imaging; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace CommonLibraryTests -{ - [TestClass] - public class RenderingTests - { - /// - /// The codebase - /// - private static readonly string Codebase = Directory.GetCurrentDirectory(); - - /// - /// The executable folder - /// - private static readonly DirectoryInfo ExeFolder = new(Path.GetDirectoryName(Codebase) ?? string.Empty); - - /// - /// The project folder - /// - private static readonly DirectoryInfo ProjectFolder = ExeFolder.Parent?.Parent; - - - /// - /// The sample images folder - /// - private static readonly DirectoryInfo SampleImagesFolder = new(Path.Combine(ProjectFolder.FullName, "Images")); - - /// - /// Setups this instance. - /// - [TestInitialize] - public void Setup() - { - // Setup code if any, such as initializing resources - } - - /// - /// Cleanups this instance. - /// - [TestCleanup] - public void Cleanup() - { - // Cleanup code if needed - } - - /// - /// Test to compare the processing speed between DirectBitmap and SkiaSharp. - /// - [TestMethod] - public void CompareImageProcessingSpeed() - { - var imagePath = Path.Combine(SampleImagesFolder.FullName, "base.png"); - - // Measure processing time with DirectBitmap - var stopwatch = new Stopwatch(); - stopwatch.Start(); - ProcessWithDirectBitmap(imagePath); - stopwatch.Stop(); - var directBitmapTime = stopwatch.ElapsedMilliseconds; - - - // Log times for comparison - Console.WriteLine($"DirectBitmap processing time: {directBitmapTime} ms"); - } - - private void ProcessWithDirectBitmap(string imagePath) - { - var btm = new Bitmap(imagePath); - // Load the image using DirectBitmap (replace with your method) - var directBitmap = new DirectBitmap(btm); - - // Example operation: convert to grayscale - for (var x = 0; x < directBitmap.Width; x++) - { - for (var y = 0; y < directBitmap.Height; y++) - { - var color = directBitmap.GetPixel(x, y); - var grayValue = (int)((color.R * 0.3) + (color.G * 0.59) + (color.B * 0.11)); - directBitmap.SetPixel(x, y, Color.FromArgb(grayValue, grayValue, grayValue)); - } - } - } - } -} diff --git a/RenderEngine/PixelData.cs b/RenderEngine/PixelData.cs new file mode 100644 index 00000000..536d3a04 --- /dev/null +++ b/RenderEngine/PixelData.cs @@ -0,0 +1,11 @@ +using OpenTK.Mathematics; + +namespace RenderEngine +{ + public struct PixelData + { + public int X; + public int Y; + public Vector3 Color; + } +} diff --git a/RenderEngine/ShaderResources.cs b/RenderEngine/ShaderResources.cs index 83ac3e5c..3f0d42ca 100644 --- a/RenderEngine/ShaderResources.cs +++ b/RenderEngine/ShaderResources.cs @@ -1,11 +1,11 @@ -using System; +// ReSharper disable UnusedType.Global namespace RenderEngine { /// /// A static class containing different shader programs (vertex and fragment shaders) for various rendering effects. /// - public static class ShaderResource + internal static class ShaderResource { /// /// Solid Color Shader diff --git a/RenderEngine/TKRender.xaml.cs b/RenderEngine/TKRender.xaml.cs index 7ac9cceb..590fed9b 100644 --- a/RenderEngine/TKRender.xaml.cs +++ b/RenderEngine/TKRender.xaml.cs @@ -1,4 +1,15 @@ -using System; +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: RenderEngine + * FILE: RenderEngine/TkRender.cs + * PURPOSE: Render Control with OpenTK, aka OpenGL + * PROGRAMER: Peter Geinitz (Wayfarer) + */ + + +// ReSharper disable UnusedType.Global + +using System; using System.Windows; using System.Windows.Forms; using System.Windows.Forms.Integration; @@ -105,72 +116,76 @@ void main() GL.EnableVertexAttribArray(1); } - public void RenderColumns(ColumnData[] columns, int screenWidth, int screenHeight) + private float[] GenerateVertexData(T[] data, int screenWidth, int screenHeight, Func getVertexAttributes) { - GL.Clear(ClearBufferMask.ColorBufferBit); + var vertexData = new float[data.Length * 6 * 5]; // 6 vertices * 5 attributes (x, y, r, g, b) - // Generate vertex data - var vertexData = new float[columns.Length * 5 * 6]; - for (var i = 0; i < columns.Length; i++) + for (var i = 0; i < data.Length; i++) { - var column = columns[i]; - - var columnHeight = column.Height / screenHeight; + var attributes = getVertexAttributes(data[i]); var xLeft = (i / (float)screenWidth * 2.0f) - 1.0f; var xRight = ((i + 1) / (float)screenWidth * 2.0f) - 1.0f; + var columnHeight = attributes[0]; // In case of columns, this would be height, for example var yTop = columnHeight - 1.0f; var yBottom = -1.0f; var offset = i * 30; // 6 vertices * 5 attributes (x, y, r, g, b) - // Vertex 1 + // Using helper to set vertices vertexData[offset + 0] = xLeft; vertexData[offset + 1] = yTop; - vertexData[offset + 2] = column.Color.X; - vertexData[offset + 3] = column.Color.Y; - vertexData[offset + 4] = column.Color.Z; + vertexData[offset + 2] = attributes[1]; // r + vertexData[offset + 3] = attributes[2]; // g + vertexData[offset + 4] = attributes[3]; // b - // Vertex 2 vertexData[offset + 5] = xRight; vertexData[offset + 6] = yTop; - vertexData[offset + 7] = column.Color.X; - vertexData[offset + 8] = column.Color.Y; - vertexData[offset + 9] = column.Color.Z; + vertexData[offset + 7] = attributes[1]; + vertexData[offset + 8] = attributes[2]; + vertexData[offset + 9] = attributes[3]; - // Vertex 3 vertexData[offset + 10] = xRight; vertexData[offset + 11] = yBottom; - vertexData[offset + 12] = column.Color.X; - vertexData[offset + 13] = column.Color.Y; - vertexData[offset + 14] = column.Color.Z; + vertexData[offset + 12] = attributes[1]; + vertexData[offset + 13] = attributes[2]; + vertexData[offset + 14] = attributes[3]; - // Vertex 4 vertexData[offset + 15] = xLeft; vertexData[offset + 16] = yTop; - vertexData[offset + 17] = column.Color.X; - vertexData[offset + 18] = column.Color.Y; - vertexData[offset + 19] = column.Color.Z; + vertexData[offset + 17] = attributes[1]; + vertexData[offset + 18] = attributes[2]; + vertexData[offset + 19] = attributes[3]; - // Vertex 5 vertexData[offset + 20] = xRight; vertexData[offset + 21] = yBottom; - vertexData[offset + 22] = column.Color.X; - vertexData[offset + 23] = column.Color.Y; - vertexData[offset + 24] = column.Color.Z; + vertexData[offset + 22] = attributes[1]; + vertexData[offset + 23] = attributes[2]; + vertexData[offset + 24] = attributes[3]; - // Vertex 6 vertexData[offset + 25] = xLeft; vertexData[offset + 26] = yBottom; - vertexData[offset + 27] = column.Color.X; - vertexData[offset + 28] = column.Color.Y; - vertexData[offset + 29] = column.Color.Z; + vertexData[offset + 27] = attributes[1]; + vertexData[offset + 28] = attributes[2]; + vertexData[offset + 29] = attributes[3]; } + return vertexData; + } + + public void RenderColumns(ColumnData[] columns, int screenWidth, int screenHeight) + { + GL.Clear(ClearBufferMask.ColorBufferBit); + + // Generate vertex data using the helper method + var vertexData = GenerateVertexData(columns, screenWidth, screenHeight, column => + { + return new float[] { column.Height / screenHeight, column.Color.X, column.Color.Y, column.Color.Z }; + }); + // Upload vertex data to GPU GL.BindBuffer(BufferTarget.ArrayBuffer, _vbo); - GL.BufferData(BufferTarget.ArrayBuffer, vertexData.Length * sizeof(float), vertexData, - BufferUsageHint.DynamicDraw); + GL.BufferData(BufferTarget.ArrayBuffer, vertexData.Length * sizeof(float), vertexData, BufferUsageHint.DynamicDraw); // Render GL.UseProgram(_shaderProgram); @@ -178,6 +193,28 @@ public void RenderColumns(ColumnData[] columns, int screenWidth, int screenHeigh GL.DrawArrays(PrimitiveType.Triangles, 0, columns.Length * 6); } + public void RenderPixels(PixelData[] pixels, int screenWidth, int screenHeight) + { + GL.Clear(ClearBufferMask.ColorBufferBit); + + // Generate vertex data using the helper method + var vertexData = GenerateVertexData(pixels, screenWidth, screenHeight, pixel => + { + var pixelWidth = 2.0f / screenWidth; + var pixelHeight = 2.0f / screenHeight; + return new float[] { pixelWidth, pixel.Color.X, pixel.Color.Y, pixel.Color.Z }; + }); + + // Upload vertex data to GPU + GL.BindBuffer(BufferTarget.ArrayBuffer, _vbo); + GL.BufferData(BufferTarget.ArrayBuffer, vertexData.Length * sizeof(float), vertexData, BufferUsageHint.DynamicDraw); + + // Render + GL.UseProgram(_shaderProgram); + GL.BindVertexArray(_vao); + GL.DrawArrays(PrimitiveType.Triangles, 0, pixels.Length * 6); + } + private int CompileShader(ShaderType type, string source) { var shader = GL.CreateShader(type); @@ -215,7 +252,6 @@ private void GlControl_Paint(object sender, PaintEventArgs e) private void GlControl_Resize(object sender, EventArgs e) { - var aspectRatio = (float)_glControl.Width / _glControl.Height; GL.Viewport(0, 0, _glControl.Width, _glControl.Height); } }