diff --git a/FModel/Constants.cs b/FModel/Constants.cs index 0b6d0157..e2667514 100644 --- a/FModel/Constants.cs +++ b/FModel/Constants.cs @@ -10,7 +10,7 @@ public static class Constants public static readonly FGuid ZERO_GUID = new(0U); public const float SCALE_DOWN_RATIO = 0.01F; - public const uint SAMPLES_COUNT = 4; + public const int SAMPLES_COUNT = 4; public const string WHITE = "#DAE5F2"; public const string GRAY = "#BBBBBB"; diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj index 91524b53..1d5c1898 100644 --- a/FModel/FModel.csproj +++ b/FModel/FModel.csproj @@ -103,10 +103,6 @@ - - Always - True - @@ -141,14 +137,10 @@ + - - - - - diff --git a/FModel/Views/Snooper/BufferObject.cs b/FModel/Views/Snooper/BufferObject.cs index 51847103..2d413596 100644 --- a/FModel/Views/Snooper/BufferObject.cs +++ b/FModel/Views/Snooper/BufferObject.cs @@ -1,56 +1,48 @@ using System; -using Silk.NET.OpenGL; +using OpenTK.Graphics.OpenGL4; namespace FModel.Views.Snooper; public class BufferObject : IDisposable where TDataType : unmanaged { - private uint _handle; - private BufferTargetARB _bufferType; - private GL _gl; + private readonly int _handle; + private readonly BufferTarget _bufferTarget; - public BufferObject(GL gl, BufferTargetARB bufferType) + private BufferObject(BufferTarget bufferTarget) { - _gl = gl; - _bufferType = bufferType; + _bufferTarget = bufferTarget; + _handle = GL.GenBuffer(); - _handle = _gl.GenBuffer(); Bind(); } - public unsafe BufferObject(GL gl, Span data, BufferTargetARB bufferType) : this(gl, bufferType) + public unsafe BufferObject(TDataType[] data, BufferTarget bufferTarget) : this(bufferTarget) { - fixed (void* d = data) - { - _gl.BufferData(bufferType, (nuint) (data.Length * sizeof(TDataType)), d, BufferUsageARB.StaticDraw); - } + GL.BufferData(bufferTarget, data.Length * sizeof(TDataType), data, BufferUsageHint.StaticDraw); } public unsafe void Update(int offset, TDataType data) { - _gl.BufferSubData(_bufferType, offset * sizeof(TDataType), (nuint) sizeof(TDataType), data); + GL.BufferSubData(_bufferTarget, (IntPtr) (offset * sizeof(TDataType)), sizeof(TDataType), ref data); } - public unsafe void Update(Span data) + public unsafe void Update(TDataType[] data) { - fixed (void* d = data) - { - _gl.BufferSubData(_bufferType, 0, (nuint) (data.Length * sizeof(TDataType)), d); - } + GL.BufferSubData(_bufferTarget, IntPtr.Zero, data.Length * sizeof(TDataType), data); } public void Bind() { - _gl.BindBuffer(_bufferType, _handle); + GL.BindBuffer(_bufferTarget, _handle); } public void Unbind() { - _gl.BindBuffer(_bufferType, 0); + GL.BindBuffer(_bufferTarget, 0); } public void Dispose() { - _gl.DeleteBuffer(_handle); + GL.DeleteBuffer(_handle); } } diff --git a/FModel/Views/Snooper/Cube.cs b/FModel/Views/Snooper/Cube.cs index 62975102..d2b2632d 100644 --- a/FModel/Views/Snooper/Cube.cs +++ b/FModel/Views/Snooper/Cube.cs @@ -63,7 +63,7 @@ public Cube(UObject owner, string name, string type, UMaterialInterface unrealMa }; Sections = new Section[1]; - Sections[0] = new Section(0, (uint) Indices.Length, 0, unrealMaterial); + Sections[0] = new Section(0, Indices.Length, 0, unrealMaterial); AddInstance(Transform.Identity); } diff --git a/FModel/Views/Snooper/FWindow.cs b/FModel/Views/Snooper/FWindow.cs new file mode 100644 index 00000000..259f9137 --- /dev/null +++ b/FModel/Views/Snooper/FWindow.cs @@ -0,0 +1,381 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using CUE4Parse.UE4.Assets.Exports; +using CUE4Parse.UE4.Assets.Exports.Material; +using CUE4Parse.UE4.Assets.Exports.SkeletalMesh; +using CUE4Parse.UE4.Assets.Exports.StaticMesh; +using CUE4Parse.UE4.Assets.Exports.Texture; +using CUE4Parse.UE4.Objects.Core.Math; +using CUE4Parse.UE4.Objects.Core.Misc; +using CUE4Parse.UE4.Objects.Engine; +using CUE4Parse.UE4.Objects.UObject; +using CUE4Parse_Conversion.Meshes; +using OpenTK.Graphics.OpenGL4; +using OpenTK.Mathematics; +using OpenTK.Windowing.Common; +using OpenTK.Windowing.Desktop; +using OpenTK.Windowing.GraphicsLibraryFramework; + +namespace FModel.Views.Snooper; + +public class FWindow : GameWindow +{ + private SnimGui _imGui; + private Camera _camera; + private IMouse _mouse; + private Image _icon; + private Options _options; + + private readonly FramebufferObject _framebuffer; + private readonly Skybox _skybox; + private readonly Grid _grid; + + private Shader _shader; + private Shader _outline; + private Vector3 _diffuseLight; + private Vector3 _specularLight; + private readonly Dictionary _models; + + private float _previousSpeed; + + public FWindow(GameWindowSettings gameWindowSettings, NativeWindowSettings nativeWindowSettings) : base(gameWindowSettings, nativeWindowSettings) + { + _options = new Options(); + _framebuffer = new FramebufferObject(Size); + _skybox = new Skybox(); + _grid = new Grid(); + _models = new Dictionary(); + } + + public void Run(CancellationToken cancellationToken, UObject export) + { + switch (export) + { + case UStaticMesh st: + { + var guid = st.LightingGuid; + if (!_models.TryGetValue(guid, out _) && st.TryConvert(out var mesh)) + { + _models[guid] = new Model(export, st.Name, st.ExportType, mesh.LODs[0], mesh.LODs[0].Verts); + SetupCamera(mesh.BoundingBox *= Constants.SCALE_DOWN_RATIO); + _options.SelectModel(guid); + } + break; + } + case USkeletalMesh sk: + { + var guid = Guid.NewGuid(); + if (!_models.TryGetValue(guid, out _) && sk.TryConvert(out var mesh)) + { + _models[guid] = new Model(export, sk.Name, sk.ExportType, mesh.LODs[0], mesh.LODs[0].Verts, sk.MorphTargets, mesh.RefSkeleton); + SetupCamera(mesh.BoundingBox *= Constants.SCALE_DOWN_RATIO); + _options.SelectModel(guid); + } + break; + } + case UMaterialInstance mi: + { + var guid = Guid.NewGuid(); + if (!_models.TryGetValue(guid, out _)) + { + _models[guid] = new Cube(export, mi.Name, mi.ExportType, mi); + SetupCamera(new FBox(new FVector(-.65f), new FVector(.65f))); + } + break; + } + case UWorld wd: + { + var persistentLevel = wd.PersistentLevel.Load(); + var length = persistentLevel.Actors.Length; + for (var i = 0; i < length; i++) + { + cancellationToken.ThrowIfCancellationRequested(); + if (persistentLevel.Actors[i].Load() is not { } actor || actor.ExportType == "LODActor" || + !actor.TryGetValue(out FPackageIndex staticMeshComponent, "StaticMeshComponent") || + staticMeshComponent.Load() is not { } staticMeshComp) continue; + + if (!staticMeshComp.TryGetValue(out FPackageIndex staticMesh, "StaticMesh") && actor.Class is UBlueprintGeneratedClass) + foreach (var actorExp in actor.Class.Owner.GetExports()) + if (actorExp.TryGetValue(out staticMesh, "StaticMesh")) + break; + if (staticMesh?.Load() is not UStaticMesh m) + continue; + + Services.ApplicationService.ApplicationView.Status.UpdateStatusLabel($"Actor {i}/{length}"); + + var guid = m.LightingGuid; + var transform = new Transform + { + Position = staticMeshComp.GetOrDefault("RelativeLocation", FVector.ZeroVector) * Constants.SCALE_DOWN_RATIO, + Rotation = staticMeshComp.GetOrDefault("RelativeRotation", FRotator.ZeroRotator), + Scale = staticMeshComp.GetOrDefault("RelativeScale3D", FVector.OneVector) + }; + transform.Rotation.Yaw = -transform.Rotation.Yaw; + + if (_models.TryGetValue(guid, out var model)) + { + model.AddInstance(transform); + } + else if (m.TryConvert(out var mesh)) + { + model = new Model(export, m.Name, m.ExportType, mesh.LODs[0], mesh.LODs[0].Verts, null, null, transform); + + if (actor.TryGetAllValues(out FPackageIndex[] textureData, "TextureData")) + { + for (int j = 0; j < textureData.Length; j++) + { + if (textureData[j].Load() is not { } textureDataIdx) + continue; + + if (textureDataIdx.TryGetValue(out FPackageIndex diffuse, "Diffuse") && + diffuse.Load() is UTexture2D diffuseTexture) + model.Sections[j].Parameters.Diffuse = diffuseTexture; + if (textureDataIdx.TryGetValue(out FPackageIndex normal, "Normal") && + normal.Load() is UTexture2D normalTexture) + model.Sections[j].Parameters.Normal = normalTexture; + if (textureDataIdx.TryGetValue(out FPackageIndex specular, "Specular") && + specular.Load() is UTexture2D specularTexture) + model.Sections[j].Parameters.Specular = specularTexture; + } + } + if (staticMeshComp.TryGetValue(out FPackageIndex[] overrideMaterials, "OverrideMaterials")) + { + var max = model.Sections.Length - 1; + for (var j = 0; j < overrideMaterials.Length; j++) + { + if (j > max) break; + if (overrideMaterials[j].Load() is not UMaterialInterface unrealMaterial) continue; + model.Sections[j].SwapMaterial(unrealMaterial); + } + } + + _models[guid] = model; + } + } + _camera = new Camera(new Vector3(0f, 5f, 5f), Vector3.Zero, 0.01f, 1000f, 5f); + break; + } + default: + throw new ArgumentOutOfRangeException(nameof(export)); + } + + DoLoop(); + } + + public void SwapMaterial(UMaterialInstance mi) + { + if (!_models.TryGetValue(_options.SelectedModel, out var model) || + !_options.TryGetSection(model, out var section)) return; + + section.SwapMaterial(mi); + _options.SwapMaterial(false); + DoLoop(); + } + + private void DoLoop() + { + if (_options.Append) _options.Append = false; + _window.Run(); + // if (_window.IsInitialized) + // { + // if (!_window.GLContext.IsCurrent) + // { + // _window.GLContext.MakeCurrent(); + // } + // + // _append = false; + // _window.IsVisible = true; + // var model = _models.Last(); + // model.Value.Setup(_gl); + // _imGui.Increment(model.Key); + // } + // else _window.Initialize(); + // + // while (!_window.IsClosing && _window.IsVisible) + // { + // _window.DoEvents(); + // if (!_window.IsClosing && _window.IsVisible) + // _window.DoUpdate(); + // if (_window.IsClosing || !_window.IsVisible) + // return; + // _window.DoRender(); + // } + // + // _window.DoEvents(); + // if (_window.IsClosing) _window.Reset(); + } + + private void SetupCamera(FBox box) + { + var far = box.Max.Max(); + var center = box.GetCenter(); + var position = new Vector3(0f, center.Z, box.Max.Y * 3); + var speed = far / 2f; + if (speed > _previousSpeed) + { + _camera = new Camera(position, center, 0.01f, far * 50f, speed); + _previousSpeed = _camera.Speed; + } + } + + protected override void OnLoad() + { + base.OnLoad(); + + _window.SetWindowIcon(ref _icon); + _window.Center(); + + var input = _window.CreateInput(); + _keyboard = input.Keyboards[0]; + _mouse = input.Mice[0]; + + _gl = GL.GetApi(_window); + _gl.Enable(EnableCap.Blend); + _gl.Enable(EnableCap.DepthTest); + _gl.Enable(EnableCap.Multisample); + _gl.StencilOp(StencilOp.Keep, StencilOp.Replace, StencilOp.Replace); + _gl.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); + + _imGui = new SnimGui(_gl, _window, input); + + _framebuffer.Setup(); + _skybox.Setup(); + _grid.Setup(); + + _shader = new Shader(); + _outline = new Shader("outline"); + _diffuseLight = new Vector3(0.75f); + _specularLight = new Vector3(0.5f); + foreach (var model in _models.Values) + { + model.Setup(); + } + } + + protected override void OnRenderFrame(FrameEventArgs args) + { + base.OnRenderFrame(args); + + _imGui.Update((float) args.Time); + + ClearWhatHasBeenDrawn(); // in main window + + _framebuffer.Bind(); // switch to dedicated window + ClearWhatHasBeenDrawn(); // in dedicated window + + _skybox.Bind(_camera); + _grid.Bind(_camera); + + var viewMatrix = _camera.GetViewMatrix(); + var projMatrix = _camera.GetProjectionMatrix(); + + _outline.Use(); + _outline.SetUniform("uView", viewMatrix); + _outline.SetUniform("uProjection", projMatrix); + _outline.SetUniform("viewPos", _camera.Position); + + _shader.Use(); + _shader.SetUniform("uView", viewMatrix); + _shader.SetUniform("uProjection", projMatrix); + _shader.SetUniform("viewPos", _camera.Position); + + _shader.SetUniform("material.diffuseMap", 0); + _shader.SetUniform("material.normalMap", 1); + _shader.SetUniform("material.specularMap", 2); + _shader.SetUniform("material.emissionMap", 3); + + _shader.SetUniform("light.position", _camera.Position); + _shader.SetUniform("light.diffuse", _diffuseLight); + _shader.SetUniform("light.specular", _specularLight); + + foreach (var model in _models.Values.Where(model => model.Show)) + { + model.Bind(_shader); + } + GL.Enable(EnableCap.StencilTest); // I don't get why this must be here but it works now so... + foreach (var model in _models.Values.Where(model => model.IsSelected && model.Show)) + { + model.Outline(_outline); + } + + _imGui.Construct(ref _options, _size, _framebuffer, _camera, _mouse, _models); + + _framebuffer.BindMsaa(); + _framebuffer.Bind(0); // switch back to main window + _framebuffer.BindStuff(); + + _imGui.Render(); // render ImGui in main window + + SwapBuffers(); + } + + private void ClearWhatHasBeenDrawn() + { + GL.ClearColor(1.0f, 0.102f, 0.129f, 1.0f); + GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit); + GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); + } + + protected override void OnUpdateFrame(FrameEventArgs e) + { + base.OnUpdateFrame(e); + if (!IsFocused || ImGui.GetIO().WantTextInput) + return; + + var multiplier = KeyboardState.IsKeyPressed(Keys.LeftShift) ? 2f : 1f; + var moveSpeed = _camera.Speed * multiplier * (float) e.Time; + if (KeyboardState.IsKeyPressed(Keys.W)) + _camera.Position += moveSpeed * _camera.Direction; + if (KeyboardState.IsKeyPressed(Keys.S)) + _camera.Position -= moveSpeed * _camera.Direction; + if (KeyboardState.IsKeyPressed(Keys.A)) + _camera.Position -= Vector3.Normalize(Vector3.Cross(_camera.Direction, _camera.Up)) * moveSpeed; + if (KeyboardState.IsKeyPressed(Keys.D)) + _camera.Position += Vector3.Normalize(Vector3.Cross(_camera.Direction, _camera.Up)) * moveSpeed; + if (KeyboardState.IsKeyPressed(Keys.E)) + _camera.Position += moveSpeed * _camera.Up; + if (KeyboardState.IsKeyPressed(Keys.Q)) + _camera.Position -= moveSpeed * _camera.Up; + if (KeyboardState.IsKeyPressed(Keys.X)) + _camera.ModifyZoom(-.5f); + if (KeyboardState.IsKeyPressed(Keys.C)) + _camera.ModifyZoom(+.5f); + + if (KeyboardState.IsKeyPressed(Keys.H)) + IsVisible = false; + if (KeyboardState.IsKeyPressed(Keys.Escape)) + Close(); + } + + private void OnClose() + { + _framebuffer.Dispose(); + _grid.Dispose(); + _skybox.Dispose(); + _shader.Dispose(); + _outline.Dispose(); + foreach (var model in _models.Values) + { + model.Dispose(); + } + if (!_options.Append) + { + _models.Clear(); + _options.Reset(); + _previousSpeed = 0f; + } + _imGui.Dispose(); + _window.Dispose(); + _gl.Dispose(); + } + + protected override void OnResize(ResizeEventArgs e) + { + base.OnResize(e); + + GL.Viewport(0, 0, Size.X, Size.Y); + _camera.AspectRatio = Size.X / (float)Size.Y; + } +} diff --git a/FModel/Views/Snooper/FramebufferObject.cs b/FModel/Views/Snooper/FramebufferObject.cs index 2994779c..6b1608b8 100644 --- a/FModel/Views/Snooper/FramebufferObject.cs +++ b/FModel/Views/Snooper/FramebufferObject.cs @@ -1,14 +1,13 @@ using System; -using Silk.NET.Maths; -using Silk.NET.OpenGL; +using OpenTK.Graphics.OpenGL4; +using OpenTK.Mathematics; namespace FModel.Views.Snooper; public class FramebufferObject : IDisposable { - private uint _framebufferHandle; - private uint _postProcessingHandle; - private GL _gl; + private int _framebufferHandle; + private int _postProcessingHandle; private readonly int _width; private readonly int _height; @@ -34,77 +33,75 @@ public class FramebufferObject : IDisposable -1.0f, 1.0f, 0.0f, 1.0f }; - public FramebufferObject(Vector2D size) + public FramebufferObject(Vector2i size) { _width = size.X; _height = size.Y; - _renderbuffer = new RenderbufferObject((uint) _width, (uint) _height); + _renderbuffer = new RenderbufferObject(_width, _height); } - public void Setup(GL gl) + public void Setup() { - _gl = gl; - - _framebufferHandle = _gl.GenFramebuffer(); + _framebufferHandle = GL.GenFramebuffer(); Bind(_framebufferHandle); - _framebufferTexture = new Texture(_gl, (uint) _width, (uint) _height); + _framebufferTexture = new Texture((uint) _width, (uint) _height); - _renderbuffer.Setup(gl); + _renderbuffer.Setup(); - _shader = new Shader(_gl, "framebuffer"); + _shader = new Shader("framebuffer"); _shader.Use(); _shader.SetUniform("screenTexture", 0); - _ebo = new BufferObject(_gl, Indices, BufferTargetARB.ElementArrayBuffer); - _vbo = new BufferObject(_gl, Vertices, BufferTargetARB.ArrayBuffer); - _vao = new VertexArrayObject(_gl, _vbo, _ebo); + _ebo = new BufferObject(Indices, BufferTarget.ElementArrayBuffer); + _vbo = new BufferObject(Vertices, BufferTarget.ArrayBuffer); + _vao = new VertexArrayObject(_vbo, _ebo); _vao.VertexAttributePointer(0, 2, VertexAttribPointerType.Float, 4, 0); // position _vao.VertexAttributePointer(1, 2, VertexAttribPointerType.Float, 4, 2); // uv - var status = _gl.CheckFramebufferStatus(FramebufferTarget.Framebuffer); - if (status != GLEnum.FramebufferComplete) + var status = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer); + if (status != FramebufferErrorCode.FramebufferComplete) { - throw new Exception($"Framebuffer failed to bind with error: {_gl.GetProgramInfoLog(_framebufferHandle)}"); + throw new Exception($"Framebuffer failed to bind with error: {GL.GetProgramInfoLog(_framebufferHandle)}"); } - _postProcessingHandle = _gl.GenFramebuffer(); + _postProcessingHandle = GL.GenFramebuffer(); Bind(_postProcessingHandle); - _postProcessingTexture = new Texture(_gl, _width, _height); + _postProcessingTexture = new Texture(_width, _height); - status = _gl.CheckFramebufferStatus(FramebufferTarget.Framebuffer); - if (status != GLEnum.FramebufferComplete) + status = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer); + if (status != FramebufferErrorCode.FramebufferComplete) { - throw new Exception($"Post-Processing framebuffer failed to bind with error: {_gl.GetProgramInfoLog(_postProcessingHandle)}"); + throw new Exception($"Post-Processing framebuffer failed to bind with error: {GL.GetProgramInfoLog(_postProcessingHandle)}"); } } public void Bind() => Bind(_framebufferHandle); - public void Bind(uint handle) + public void Bind(int handle) { - _gl.BindFramebuffer(FramebufferTarget.Framebuffer, handle); + GL.BindFramebuffer(FramebufferTarget.Framebuffer, handle); } public void BindMsaa() { - _gl.BindFramebuffer(FramebufferTarget.ReadFramebuffer, _framebufferHandle); - _gl.BindFramebuffer(FramebufferTarget.DrawFramebuffer, _postProcessingHandle); - _gl.BlitFramebuffer(0, 0, _width, _height, 0, 0, _width, _height, ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Nearest); + GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, _framebufferHandle); + GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, _postProcessingHandle); + GL.BlitFramebuffer(0, 0, _width, _height, 0, 0, _width, _height, ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Nearest); } public void BindStuff() { - _gl.Disable(EnableCap.DepthTest); + GL.Disable(EnableCap.DepthTest); _shader.Use(); _vao.Bind(); _postProcessingTexture.Bind(TextureUnit.Texture0); - _gl.DrawArrays(PrimitiveType.Triangles, 0, (uint) Indices.Length); - _gl.Enable(EnableCap.DepthTest); + GL.DrawArrays(PrimitiveType.Triangles, 0, Indices.Length); + GL.Enable(EnableCap.DepthTest); } public IntPtr GetPointer() => _postProcessingTexture.GetPointer(); @@ -116,7 +113,7 @@ public void Dispose() _framebufferTexture.Dispose(); _postProcessingTexture.Dispose(); _renderbuffer.Dispose(); - _gl.DeleteFramebuffer(_framebufferHandle); - _gl.DeleteFramebuffer(_postProcessingHandle); + GL.DeleteFramebuffer(_framebufferHandle); + GL.DeleteFramebuffer(_postProcessingHandle); } } diff --git a/FModel/Views/Snooper/Grid.cs b/FModel/Views/Snooper/Grid.cs index 93ccd331..718d5ded 100644 --- a/FModel/Views/Snooper/Grid.cs +++ b/FModel/Views/Snooper/Grid.cs @@ -1,12 +1,11 @@ using System; -using Silk.NET.OpenGL; +using OpenTK.Graphics.OpenGL4; namespace FModel.Views.Snooper; public class Grid : IDisposable { - private uint _handle; - private GL _gl; + private int _handle; private BufferObject _ebo; private BufferObject _vbo; @@ -26,24 +25,22 @@ public class Grid : IDisposable public Grid() {} - public void Setup(GL gl) + public void Setup() { - _gl = gl; + _handle = GL.CreateProgram(); - _handle = _gl.CreateProgram(); + _ebo = new BufferObject(Indices, BufferTarget.ElementArrayBuffer); + _vbo = new BufferObject(Vertices, BufferTarget.ArrayBuffer); + _vao = new VertexArrayObject(_vbo, _ebo); - _ebo = new BufferObject(_gl, Indices, BufferTargetARB.ElementArrayBuffer); - _vbo = new BufferObject(_gl, Vertices, BufferTargetARB.ArrayBuffer); - _vao = new VertexArrayObject(_gl, _vbo, _ebo); - - _shader = new Shader(_gl, "grid"); + _shader = new Shader("grid"); _vao.VertexAttributePointer(0, 3, VertexAttribPointerType.Float, 3, 0); // position } public void Bind(Camera camera) { - _gl.Disable(EnableCap.DepthTest); + GL.Disable(EnableCap.DepthTest); _vao.Bind(); _shader.Use(); @@ -53,8 +50,8 @@ public void Bind(Camera camera) _shader.SetUniform("uNear", camera.Near); _shader.SetUniform("uFar", camera.Far); - _gl.DrawArrays(PrimitiveType.Triangles, 0, (uint) Indices.Length); - _gl.Enable(EnableCap.DepthTest); + GL.DrawArrays(PrimitiveType.Triangles, 0, Indices.Length); + GL.Enable(EnableCap.DepthTest); } public void Dispose() @@ -63,6 +60,6 @@ public void Dispose() _vbo.Dispose(); _vao.Dispose(); _shader.Dispose(); - _gl.DeleteProgram(_handle); + GL.DeleteProgram(_handle); } } diff --git a/FModel/Views/Snooper/Model.cs b/FModel/Views/Snooper/Model.cs index 8b47a5f0..e0ff27bb 100644 --- a/FModel/Views/Snooper/Model.cs +++ b/FModel/Views/Snooper/Model.cs @@ -4,17 +4,15 @@ using System.Numerics; using CUE4Parse.UE4.Assets.Exports; using CUE4Parse.UE4.Assets.Exports.Animation; -using CUE4Parse.UE4.Objects.Engine; using CUE4Parse.UE4.Objects.UObject; using CUE4Parse_Conversion.Meshes.PSK; -using Silk.NET.OpenGL; +using OpenTK.Graphics.OpenGL4; namespace FModel.Views.Snooper; public class Model : IDisposable { - private uint _handle; - private GL _gl; + private int _handle; private BufferObject _ebo; private BufferObject _vbo; @@ -22,9 +20,9 @@ public class Model : IDisposable private BufferObject _matrixVbo; private VertexArrayObject _vao; - private uint _vertexSize = 9; // VertexIndex + Position + Normal + UV - private const uint _faceSize = 3; // just so we don't have to do .Length + private readonly int _vertexSize = 9; // VertexIndex + Position + Normal + UV private readonly uint[] _facesIndex = { 1, 0, 2 }; + private const int _faceSize = 3; // just so we don't have to do .Length public readonly UObject Owner; public readonly string Name; @@ -43,7 +41,6 @@ public class Model : IDisposable public bool Show; public bool IsSelected; - public bool IsSavable; public bool DisplayVertexColors; public bool DisplayBones; public float MorphTime; @@ -55,7 +52,6 @@ protected Model(UObject owner, string name, string type) Type = type; Transforms = new List(); Show = true; - IsSavable = owner is not UWorld; } public Model(UObject owner, string name, string type, CBaseMeshLod lod, CMeshVertex[] vertices, FPackageIndex[] morphTargets = null, List skeleton = null, Transform transform = null) @@ -76,7 +72,7 @@ public Model(UObject owner, string name, string type, CBaseMeshLod lod, CMeshVer for (var s = 0; s < sections.Length; s++) { var section = sections[s]; - Sections[s] = new Section(section.MaterialName, section.MaterialIndex, (uint) section.NumFaces * _faceSize, section.FirstIndex, section); + Sections[s] = new Section(section.MaterialName, section.MaterialIndex, section.NumFaces * _faceSize, section.FirstIndex, section); for (uint face = 0; face < section.NumFaces; face++) { foreach (var f in _facesIndex) @@ -155,15 +151,13 @@ public void UpdateMorph(int index) _morphVbo.Unbind(); } - public void Setup(GL gl) + public void Setup() { - _gl = gl; + _handle = GL.CreateProgram(); - _handle = _gl.CreateProgram(); - - _ebo = new BufferObject(_gl, Indices, BufferTargetARB.ElementArrayBuffer); - _vbo = new BufferObject(_gl, Vertices, BufferTargetARB.ArrayBuffer); - _vao = new VertexArrayObject(_gl, _vbo, _ebo); + _ebo = new BufferObject(Indices, BufferTarget.ElementArrayBuffer); + _vbo = new BufferObject(Vertices, BufferTarget.ArrayBuffer); + _vao = new VertexArrayObject(_vbo, _ebo); _vao.VertexAttributePointer(0, 1, VertexAttribPointerType.Int, _vertexSize, 0); // vertex index _vao.VertexAttributePointer(1, 3, VertexAttribPointerType.Float, _vertexSize, 1); // position @@ -178,7 +172,7 @@ public void Setup(GL gl) var instanceMatrix = new Matrix4x4[TransformsCount]; for (var i = 0; i < instanceMatrix.Length; i++) instanceMatrix[i] = Transforms[i].Matrix; - _matrixVbo = new BufferObject(_gl, instanceMatrix, BufferTargetARB.ArrayBuffer); + _matrixVbo = new BufferObject(instanceMatrix, BufferTarget.ArrayBuffer); _vao.BindInstancing(); // VertexAttributePointer 7, 8, 9, 10 } @@ -186,9 +180,9 @@ public void Setup(GL gl) { for (uint morph = 0; morph < Morphs.Length; morph++) { - Morphs[morph].Setup(gl); + Morphs[morph].Setup(); if (morph == 0) - _morphVbo = new BufferObject(_gl, Morphs[morph].Vertices, BufferTargetARB.ArrayBuffer); + _morphVbo = new BufferObject(Morphs[morph].Vertices, BufferTarget.ArrayBuffer); } _vao.Bind(); _vao.VertexAttributePointer(11, 3, VertexAttribPointerType.Float, 3, 0); // morph position @@ -197,7 +191,7 @@ public void Setup(GL gl) for (int section = 0; section < Sections.Length; section++) { - Sections[section].Setup(_gl); + Sections[section].Setup(); } } @@ -205,8 +199,8 @@ public void Bind(Shader shader) { if (IsSelected) { - _gl.Enable(EnableCap.StencilTest); - _gl.StencilFunc(StencilFunction.Always, 1, 0xFF); + GL.Enable(EnableCap.StencilTest); + GL.StencilFunc(StencilFunction.Always, 1, 0xFF); } _vao.Bind(); @@ -214,22 +208,22 @@ public void Bind(Shader shader) shader.SetUniform("display_vertex_colors", DisplayVertexColors); for (int section = 0; section < Sections.Length; section++) { - Sections[section].Bind(shader, (uint) TransformsCount); + Sections[section].Bind(shader, TransformsCount); } _vao.Unbind(); if (IsSelected) { - _gl.StencilFunc(StencilFunction.Always, 0, 0xFF); - _gl.Disable(EnableCap.StencilTest); + GL.StencilFunc(StencilFunction.Always, 0, 0xFF); + GL.Disable(EnableCap.StencilTest); } } public void Outline(Shader shader) { - _gl.StencilMask(0x00); - _gl.Disable(EnableCap.DepthTest); - _gl.StencilFunc(StencilFunction.Notequal, 1, 0xFF); + GL.StencilMask(0x00); + GL.Disable(EnableCap.DepthTest); + GL.StencilFunc(StencilFunction.Notequal, 1, 0xFF); _vao.Bind(); shader.Use(); @@ -237,13 +231,13 @@ public void Outline(Shader shader) for (int section = 0; section < Sections.Length; section++) { if (!Sections[section].Show) continue; - _gl.DrawArraysInstanced(PrimitiveType.Triangles, Sections[section].FirstFaceIndex, Sections[section].FacesCount, (uint) TransformsCount); + GL.DrawArraysInstanced(PrimitiveType.Triangles, Sections[section].FirstFaceIndex, Sections[section].FacesCount, TransformsCount); } _vao.Unbind(); - _gl.StencilFunc(StencilFunction.Always, 0, 0xFF); - _gl.Enable(EnableCap.DepthTest); - _gl.StencilMask(0xFF); + GL.StencilFunc(StencilFunction.Always, 0, 0xFF); + GL.Enable(EnableCap.DepthTest); + GL.StencilMask(0xFF); } public void Dispose() @@ -264,6 +258,6 @@ public void Dispose() { Sections[section].Dispose(); } - _gl.DeleteProgram(_handle); + GL.DeleteProgram(_handle); } } diff --git a/FModel/Views/Snooper/Morph.cs b/FModel/Views/Snooper/Morph.cs index 80488c9e..ea4b1aaa 100644 --- a/FModel/Views/Snooper/Morph.cs +++ b/FModel/Views/Snooper/Morph.cs @@ -1,21 +1,20 @@ using System; using CUE4Parse.UE4.Assets.Exports.Animation; using CUE4Parse.UE4.Objects.Core.Math; -using Silk.NET.OpenGL; +using OpenTK.Graphics.OpenGL4; namespace FModel.Views.Snooper; public class Morph : IDisposable { - private uint _handle; - private GL _gl; + private int _handle; - private uint _vertexSize = 3; // Position + private readonly int _vertexSize = 3; // Position public readonly string Name; public readonly float[] Vertices; - public Morph(float[] vertices, uint vertexSize, UMorphTarget morphTarget) + public Morph(float[] vertices, int vertexSize, UMorphTarget morphTarget) { Name = morphTarget.Name; Vertices = new float[vertices.Length / vertexSize * _vertexSize]; @@ -34,7 +33,7 @@ bool TryFindVertex(uint index, out FVector positionDelta) return false; } - for (uint i = 0; i < vertices.Length; i += vertexSize) + for (int i = 0; i < vertices.Length; i += vertexSize) { var count = 0; var baseIndex = i / vertexSize * _vertexSize; @@ -53,14 +52,13 @@ bool TryFindVertex(uint index, out FVector positionDelta) } } - public void Setup(GL gl) + public void Setup() { - _gl = gl; - _handle = _gl.CreateProgram(); + _handle = GL.CreateProgram(); } public void Dispose() { - _gl.DeleteProgram(_handle); + GL.DeleteProgram(_handle); } } diff --git a/FModel/Views/Snooper/RenderbufferObject.cs b/FModel/Views/Snooper/RenderbufferObject.cs index bc789e4e..30fac53b 100644 --- a/FModel/Views/Snooper/RenderbufferObject.cs +++ b/FModel/Views/Snooper/RenderbufferObject.cs @@ -1,34 +1,32 @@ using System; -using Silk.NET.OpenGL; +using OpenTK.Graphics.OpenGL4; namespace FModel.Views.Snooper; public class RenderbufferObject : IDisposable { - private uint _handle; - private GL _gl; + private int _handle; - private readonly uint _width; - private readonly uint _height; + private readonly int _width; + private readonly int _height; - public RenderbufferObject(uint width, uint height) + public RenderbufferObject(int width, int height) { _width = width; _height = height; } - public void Setup(GL gl) + public void Setup() { - _gl = gl; - _handle = _gl.GenRenderbuffer(); + _handle = GL.GenRenderbuffer(); - _gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, _handle); - _gl.RenderbufferStorageMultisample(RenderbufferTarget.Renderbuffer, Constants.SAMPLES_COUNT, InternalFormat.Depth24Stencil8, _width, _height); - _gl.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthStencilAttachment, RenderbufferTarget.Renderbuffer, _handle); + GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, _handle); + GL.RenderbufferStorageMultisample(RenderbufferTarget.Renderbuffer, Constants.SAMPLES_COUNT, RenderbufferStorage.Depth24Stencil8, _width, _height); + GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthStencilAttachment, RenderbufferTarget.Renderbuffer, _handle); } public void Dispose() { - _gl.DeleteRenderbuffer(_handle); + GL.DeleteRenderbuffer(_handle); } } diff --git a/FModel/Views/Snooper/Section.cs b/FModel/Views/Snooper/Section.cs index efd39cab..222d42f6 100644 --- a/FModel/Views/Snooper/Section.cs +++ b/FModel/Views/Snooper/Section.cs @@ -6,15 +6,14 @@ using CUE4Parse_Conversion.Textures; using FModel.Services; using FModel.Settings; -using Silk.NET.OpenGL; +using OpenTK.Graphics.OpenGL4; using SkiaSharp; namespace FModel.Views.Snooper; public class Section : IDisposable { - private uint _handle; - private GL _gl; + private int _handle; private Vector3 _ambientLight; @@ -22,7 +21,7 @@ public class Section : IDisposable public string Name; public readonly int Index; - public readonly uint FacesCount; + public readonly int FacesCount; public readonly int FirstFaceIndex; public readonly CMaterialParams Parameters; @@ -35,7 +34,7 @@ public class Section : IDisposable public bool HasSpecularMap; public bool HasDiffuseColor; - private Section(string name, int index, uint facesCount, int firstFaceIndex) + private Section(string name, int index, int facesCount, int firstFaceIndex) { Name = name; Index = index; @@ -52,7 +51,7 @@ private Section(string name, int index, uint facesCount, int firstFaceIndex) _game = ApplicationService.ApplicationView.CUE4Parse.Game; } - public Section(string name, int index, uint facesCount, int firstFaceIndex, CMeshSection section) : this(name, index, facesCount, firstFaceIndex) + public Section(string name, int index, int facesCount, int firstFaceIndex, CMeshSection section) : this(name, index, facesCount, firstFaceIndex) { if (section.Material != null && section.Material.TryLoad(out var material) && material is UMaterialInterface unrealMaterial) { @@ -60,7 +59,7 @@ public Section(string name, int index, uint facesCount, int firstFaceIndex, CMes } } - public Section(int index, uint facesCount, int firstFaceIndex, UMaterialInterface unrealMaterial) : this(string.Empty, index, facesCount, firstFaceIndex) + public Section(int index, int facesCount, int firstFaceIndex, UMaterialInterface unrealMaterial) : this(string.Empty, index, facesCount, firstFaceIndex) { SwapMaterial(unrealMaterial); } @@ -71,11 +70,9 @@ public void SwapMaterial(UMaterialInterface unrealMaterial) unrealMaterial.GetParams(Parameters); } - public void Setup(GL gl) + public void Setup() { - _gl = gl; - - _handle = _gl.CreateProgram(); + _handle = GL.CreateProgram(); if (Parameters.IsNull) { @@ -92,21 +89,21 @@ public void Setup(GL gl) { var mip = diffuse.GetFirstMip(); TextureDecoder.DecodeTexture(mip, diffuse.Format, diffuse.isNormalMap, platform, out var data, out var colorType); - Textures[0] = new Texture(_gl, data, (uint) mip.SizeX, (uint) mip.SizeY, colorType, diffuse); + Textures[0] = new Texture(data, (uint) mip.SizeX, (uint) mip.SizeY, colorType, diffuse); } if (Parameters.Normal is UTexture2D { IsVirtual: false } normal) { var mip = normal.GetFirstMip(); TextureDecoder.DecodeTexture(mip, normal.Format, normal.isNormalMap, platform, out var data, out var colorType); - Textures[1] = new Texture(_gl, data, (uint) mip.SizeX, (uint) mip.SizeY, colorType, normal); + Textures[1] = new Texture(data, (uint) mip.SizeX, (uint) mip.SizeY, colorType, normal); } if (Parameters.Specular is UTexture2D { IsVirtual: false } specular) { var mip = specular.GetFirstMip(); SwapSpecular(specular, mip, platform, out var data, out var colorType); - Textures[2] = new Texture(_gl, data, (uint) mip.SizeX, (uint) mip.SizeY, colorType, specular); + Textures[2] = new Texture(data, (uint) mip.SizeX, (uint) mip.SizeY, colorType, specular); } if (Parameters.HasTopEmissiveTexture && @@ -114,7 +111,7 @@ public void Setup(GL gl) { var mip = emissive.GetFirstMip(); TextureDecoder.DecodeTexture(mip, emissive.Format, emissive.isNormalMap, platform, out var data, out var colorType); - Textures[3] = new Texture(_gl, data, (uint) mip.SizeX, (uint) mip.SizeY, colorType, emissive); + Textures[3] = new Texture(data, (uint) mip.SizeX, (uint) mip.SizeY, colorType, emissive); if (Parameters.EmissiveColor is { A: > 0 } emissiveColor) { EmissionColor = new Vector4(emissiveColor.R, emissiveColor.G, emissiveColor.B, emissiveColor.A); @@ -232,7 +229,7 @@ private void SwapSpecular(UTexture2D specular, FTexture2DMipMap mip, ETexturePla Parameters.RoughnessValue = 0; } - public void Bind(Shader shader, uint instanceCount) + public void Bind(Shader shader, int instanceCount) { for (var i = 0; i < Textures.Length; i++) { @@ -251,8 +248,8 @@ public void Bind(Shader shader, uint instanceCount) shader.SetUniform("light.ambient", _ambientLight); - _gl.PolygonMode(MaterialFace.FrontAndBack, Wireframe ? PolygonMode.Line : PolygonMode.Fill); - if (Show) _gl.DrawArraysInstanced(PrimitiveType.Triangles, FirstFaceIndex, FacesCount, instanceCount); + GL.PolygonMode(MaterialFace.FrontAndBack, Wireframe ? PolygonMode.Line : PolygonMode.Fill); + if (Show) GL.DrawArraysInstanced(PrimitiveType.Triangles, FirstFaceIndex, FacesCount, instanceCount); } public void Dispose() @@ -261,6 +258,6 @@ public void Dispose() { Textures[i]?.Dispose(); } - _gl.DeleteProgram(_handle); + GL.DeleteProgram(_handle); } } diff --git a/FModel/Views/Snooper/Shader.cs b/FModel/Views/Snooper/Shader.cs index e67fb2ef..0aa07df8 100644 --- a/FModel/Views/Snooper/Shader.cs +++ b/FModel/Views/Snooper/Shader.cs @@ -3,114 +3,111 @@ using System.IO; using System.Numerics; using System.Reflection; -using Silk.NET.OpenGL; +using OpenTK.Graphics.OpenGL4; namespace FModel.Views.Snooper; public class Shader : IDisposable { - private readonly uint _handle; - private readonly GL _gl; + private readonly int _handle; private readonly Dictionary _uniformToLocation = new (); private readonly Dictionary _attribLocation = new (); - public Shader(GL gl) : this(gl, "default") {} + public Shader() : this("default") {} - public Shader(GL gl, string name) + public Shader(string name) { - _gl = gl; - - _handle = _gl.CreateProgram(); - - uint v = LoadShader(ShaderType.VertexShader, $"{name}.vert"); - uint f = LoadShader(ShaderType.FragmentShader, $"{name}.frag"); - _gl.AttachShader(_handle, v); - _gl.AttachShader(_handle, f); - _gl.LinkProgram(_handle); - _gl.GetProgram(_handle, GLEnum.LinkStatus, out var status); + _handle = GL.CreateProgram(); + + var v = LoadShader(ShaderType.VertexShader, $"{name}.vert"); + var f = LoadShader(ShaderType.FragmentShader, $"{name}.frag"); + GL.AttachShader(_handle, v); + GL.AttachShader(_handle, f); + GL.LinkProgram(_handle); + GL.GetProgram(_handle, GetProgramParameterName.LinkStatus, out var status); if (status == 0) { - throw new Exception($"Program failed to link with error: {_gl.GetProgramInfoLog(_handle)}"); + throw new Exception($"Program failed to link with error: {GL.GetProgramInfoLog(_handle)}"); } - _gl.DetachShader(_handle, v); - _gl.DetachShader(_handle, f); - _gl.DeleteShader(v); - _gl.DeleteShader(f); + GL.DetachShader(_handle, v); + GL.DetachShader(_handle, f); + GL.DeleteShader(v); + GL.DeleteShader(f); } public void Use() { - _gl.UseProgram(_handle); + GL.UseProgram(_handle); } public void SetUniform(string name, int value) { - int location = _gl.GetUniformLocation(_handle, name); + int location = GL.GetUniformLocation(_handle, name); if (location == -1) { throw new Exception($"{name} uniform not found on shader."); } - _gl.Uniform1(location, value); + GL.Uniform1(location, value); } public unsafe void SetUniform(string name, Matrix4x4 value) { //A new overload has been created for setting a uniform so we can use the transform in our shader. - int location = _gl.GetUniformLocation(_handle, name); + int location = GL.GetUniformLocation(_handle, name); if (location == -1) { throw new Exception($"{name} uniform not found on shader."); } - _gl.UniformMatrix4(location, 1, false, (float*) &value); + GL.UniformMatrix4(location, 1, false, (float*) &value); } public void SetUniform(string name, bool value) => SetUniform(name, Convert.ToUInt32(value)); public void SetUniform(string name, uint value) { - int location = _gl.GetUniformLocation(_handle, name); + int location = GL.GetUniformLocation(_handle, name); if (location == -1) { throw new Exception($"{name} uniform not found on shader."); } - _gl.Uniform1(location, value); + GL.Uniform1(location, value); } public void SetUniform(string name, float value) { - int location = _gl.GetUniformLocation(_handle, name); + int location = GL.GetUniformLocation(_handle, name); if (location == -1) { throw new Exception($"{name} uniform not found on shader."); } - _gl.Uniform1(location, value); + GL.Uniform1(location, value); } public void SetUniform(string name, Vector3 value) { - int location = _gl.GetUniformLocation(_handle, name); + int location = GL.GetUniformLocation(_handle, name); if (location == -1) { throw new Exception($"{name} uniform not found on shader."); } - _gl.Uniform3(location, value.X, value.Y, value.Z); + GL.Uniform3(location, value.X, value.Y, value.Z); } public void SetUniform(string name, Vector4 value) { - int location = _gl.GetUniformLocation(_handle, name); + int location = GL.GetUniformLocation(_handle, name); if (location == -1) { throw new Exception($"{name} uniform not found on shader."); } - _gl.Uniform4(location, value.X, value.Y, value.Z, value.W); + GL.Uniform4(location, value.X, value.Y, value.Z, value.W); } public int GetUniformLocation(string uniform) { if (!_uniformToLocation.TryGetValue(uniform, out int location)) { - location = _gl.GetUniformLocation(_handle, uniform); + location = GL.GetUniformLocation(_handle, uniform); _uniformToLocation.Add(uniform, location); if (location == -1) { @@ -124,7 +121,7 @@ public int GetAttribLocation(string attrib) { if (!_attribLocation.TryGetValue(attrib, out int location)) { - location = _gl.GetAttribLocation(_handle, attrib); + location = GL.GetAttribLocation(_handle, attrib); _attribLocation.Add(attrib, location); if (location == -1) { @@ -136,18 +133,18 @@ public int GetAttribLocation(string attrib) public void Dispose() { - _gl.DeleteProgram(_handle); + GL.DeleteProgram(_handle); } - private uint LoadShader(ShaderType type, string file) + private int LoadShader(ShaderType type, string file) { var executingAssembly = Assembly.GetExecutingAssembly(); using var stream = executingAssembly.GetManifestResourceStream($"{executingAssembly.GetName().Name}.Resources.{file}"); using var reader = new StreamReader(stream); - uint handle = _gl.CreateShader(type); - _gl.ShaderSource(handle, reader.ReadToEnd()); - _gl.CompileShader(handle); - string infoLog = _gl.GetShaderInfoLog(handle); + var handle = GL.CreateShader(type); + GL.ShaderSource(handle, reader.ReadToEnd()); + GL.CompileShader(handle); + string infoLog = GL.GetShaderInfoLog(handle); if (!string.IsNullOrWhiteSpace(infoLog)) { throw new Exception($"Error compiling shader of type {type}, failed with error {infoLog}"); diff --git a/FModel/Views/Snooper/Skybox.cs b/FModel/Views/Snooper/Skybox.cs index 65c992ff..481108bf 100644 --- a/FModel/Views/Snooper/Skybox.cs +++ b/FModel/Views/Snooper/Skybox.cs @@ -1,12 +1,11 @@ using System; -using Silk.NET.OpenGL; +using OpenTK.Graphics.OpenGL4; namespace FModel.Views.Snooper; public class Skybox : IDisposable { - private uint _handle; - private GL _gl; + private int _handle; private BufferObject _ebo; private BufferObject _vbo; @@ -65,25 +64,23 @@ public class Skybox : IDisposable public Skybox() {} - public void Setup(GL gl) + public void Setup() { - _gl = gl; + _handle = GL.CreateProgram(); - _handle = _gl.CreateProgram(); + _ebo = new BufferObject(Indices, BufferTarget.ElementArrayBuffer); + _vbo = new BufferObject(Vertices, BufferTarget.ArrayBuffer); + _vao = new VertexArrayObject(_vbo, _ebo); - _ebo = new BufferObject(_gl, Indices, BufferTargetARB.ElementArrayBuffer); - _vbo = new BufferObject(_gl, Vertices, BufferTargetARB.ArrayBuffer); - _vao = new VertexArrayObject(_gl, _vbo, _ebo); - - _cubeMap = new Texture(_gl, _textures); - _shader = new Shader(_gl, "skybox"); + _cubeMap = new Texture(_textures); + _shader = new Shader("skybox"); _vao.VertexAttributePointer(0, 3, VertexAttribPointerType.Float, 3, 0); // position } public void Bind(Camera camera) { - _gl.DepthFunc(DepthFunction.Lequal); + GL.DepthFunc(DepthFunction.Lequal); _vao.Bind(); @@ -99,9 +96,9 @@ public void Bind(Camera camera) _shader.SetUniform("cubemap", 0); - _gl.DrawArrays(PrimitiveType.Triangles, 0, 36); + GL.DrawArrays(PrimitiveType.Triangles, 0, 36); - _gl.DepthFunc(DepthFunction.Less); + GL.DepthFunc(DepthFunction.Less); } public void Dispose() @@ -110,6 +107,6 @@ public void Dispose() _vbo.Dispose(); _vao.Dispose(); _shader.Dispose(); - _gl.DeleteProgram(_handle); + GL.DeleteProgram(_handle); } } diff --git a/FModel/Views/Snooper/Snooper.cs b/FModel/Views/Snooper/Snooper.cs index d30b7142..44976058 100644 --- a/FModel/Views/Snooper/Snooper.cs +++ b/FModel/Views/Snooper/Snooper.cs @@ -1,55 +1,17 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using System.Runtime.InteropServices; +using System; using System.Threading; using System.Windows; using CUE4Parse.UE4.Assets.Exports; using CUE4Parse.UE4.Assets.Exports.Material; -using CUE4Parse.UE4.Assets.Exports.SkeletalMesh; -using CUE4Parse.UE4.Assets.Exports.StaticMesh; -using CUE4Parse.UE4.Assets.Exports.Texture; -using CUE4Parse.UE4.Objects.Core.Math; -using CUE4Parse.UE4.Objects.Core.Misc; -using CUE4Parse.UE4.Objects.Engine; -using CUE4Parse.UE4.Objects.UObject; -using CUE4Parse_Conversion.Meshes; -using ImGuiNET; -using Silk.NET.Core; -using Silk.NET.Input; -using Silk.NET.Maths; -using Silk.NET.OpenGL; -using Silk.NET.Windowing; -using SixLabors.ImageSharp.Advanced; -using SixLabors.ImageSharp.PixelFormats; -using Image = SixLabors.ImageSharp.Image; +using OpenTK.Mathematics; +using OpenTK.Windowing.Common; +using OpenTK.Windowing.Desktop; namespace FModel.Views.Snooper; public class Snooper { - private readonly IWindow _window; - private GL _gl; - private SnimGui _imGui; - private Camera _camera; - private IKeyboard _keyboard; - private IMouse _mouse; - private RawImage _icon; - private Options _options; - - private readonly FramebufferObject _framebuffer; - private readonly Skybox _skybox; - private readonly Grid _grid; - - private Shader _shader; - private Shader _outline; - private Vector3 _diffuseLight; - private Vector3 _specularLight; - private readonly Dictionary _models; - - private Vector2D _size; - private float _previousSpeed; + private readonly FWindow _window; public Snooper() { @@ -57,366 +19,23 @@ public Snooper() var x = SystemParameters.MaximizedPrimaryScreenWidth; var y = SystemParameters.MaximizedPrimaryScreenHeight; - var options = WindowOptions.Default; - options.Size = _size = new Vector2D(Convert.ToInt32(x * ratio), Convert.ToInt32(y * ratio)); + var options = NativeWindowSettings.Default; + options.Size = new Vector2i(Convert.ToInt32(x * ratio), Convert.ToInt32(y * ratio)); options.WindowBorder = WindowBorder.Fixed; + options.Location = new Vector2i(Convert.ToInt32(x / 2.0) / (options.Size.X / 2), Convert.ToInt32(y / 2.0) / (options.Size.Y / 2)); + options.NumberOfSamples = Constants.SAMPLES_COUNT; options.Title = "Snooper"; - _window = Silk.NET.Windowing.Window.Create(options); - - unsafe - { - var info = Application.GetResourceStream(new Uri("/FModel;component/Resources/materialicon.png", UriKind.Relative)); - using var image = Image.Load(info.Stream); - var memoryGroup = image.GetPixelMemoryGroup(); - Memory array = new byte[memoryGroup.TotalLength * sizeof(Rgba32)]; - var block = MemoryMarshal.Cast(array.Span); - foreach (var memory in memoryGroup) - { - memory.Span.CopyTo(block); - block = block.Slice(memory.Length); - } - _icon = new RawImage(image.Width, image.Height, array); - } - _window.Load += OnLoad; - _window.Update += OnUpdate; - _window.Render += OnRender; - _window.Closing += OnClose; - _window.FramebufferResize += delegate(Vector2D vector2D) - { - _gl.Viewport(vector2D); - _size = vector2D; - }; - - _options = new Options(); - _framebuffer = new FramebufferObject(_size); - _skybox = new Skybox(); - _grid = new Grid(); - _models = new Dictionary(); + _window = new FWindow(GameWindowSettings.Default, options); } public void Run(CancellationToken cancellationToken, UObject export) { - switch (export) - { - case UStaticMesh st: - { - var guid = st.LightingGuid; - if (!_models.TryGetValue(guid, out _) && st.TryConvert(out var mesh)) - { - _models[guid] = new Model(export, st.Name, st.ExportType, mesh.LODs[0], mesh.LODs[0].Verts); - SetupCamera(mesh.BoundingBox *= Constants.SCALE_DOWN_RATIO); - _options.SelectModel(guid); - } - break; - } - case USkeletalMesh sk: - { - var guid = Guid.NewGuid(); - if (!_models.TryGetValue(guid, out _) && sk.TryConvert(out var mesh)) - { - _models[guid] = new Model(export, sk.Name, sk.ExportType, mesh.LODs[0], mesh.LODs[0].Verts, sk.MorphTargets, mesh.RefSkeleton); - SetupCamera(mesh.BoundingBox *= Constants.SCALE_DOWN_RATIO); - _options.SelectModel(guid); - } - break; - } - case UMaterialInstance mi: - { - var guid = Guid.NewGuid(); - if (!_models.TryGetValue(guid, out _)) - { - _models[guid] = new Cube(export, mi.Name, mi.ExportType, mi); - SetupCamera(new FBox(new FVector(-.65f), new FVector(.65f))); - } - break; - } - case UWorld wd: - { - var persistentLevel = wd.PersistentLevel.Load(); - var length = persistentLevel.Actors.Length; - for (var i = 0; i < length; i++) - { - cancellationToken.ThrowIfCancellationRequested(); - if (persistentLevel.Actors[i].Load() is not { } actor || actor.ExportType == "LODActor" || - !actor.TryGetValue(out FPackageIndex staticMeshComponent, "StaticMeshComponent") || - staticMeshComponent.Load() is not { } staticMeshComp) continue; - - if (!staticMeshComp.TryGetValue(out FPackageIndex staticMesh, "StaticMesh") && actor.Class is UBlueprintGeneratedClass) - foreach (var actorExp in actor.Class.Owner.GetExports()) - if (actorExp.TryGetValue(out staticMesh, "StaticMesh")) - break; - if (staticMesh?.Load() is not UStaticMesh m) - continue; - - Services.ApplicationService.ApplicationView.Status.UpdateStatusLabel($"Actor {i}/{length}"); - - var guid = m.LightingGuid; - var transform = new Transform - { - Position = staticMeshComp.GetOrDefault("RelativeLocation", FVector.ZeroVector) * Constants.SCALE_DOWN_RATIO, - Rotation = staticMeshComp.GetOrDefault("RelativeRotation", FRotator.ZeroRotator), - Scale = staticMeshComp.GetOrDefault("RelativeScale3D", FVector.OneVector) - }; - transform.Rotation.Yaw = -transform.Rotation.Yaw; - - if (_models.TryGetValue(guid, out var model)) - { - model.AddInstance(transform); - } - else if (m.TryConvert(out var mesh)) - { - model = new Model(export, m.Name, m.ExportType, mesh.LODs[0], mesh.LODs[0].Verts, null, null, transform); - - if (actor.TryGetAllValues(out FPackageIndex[] textureData, "TextureData")) - { - for (int j = 0; j < textureData.Length; j++) - { - if (textureData[j].Load() is not { } textureDataIdx) - continue; - - if (textureDataIdx.TryGetValue(out FPackageIndex diffuse, "Diffuse") && - diffuse.Load() is UTexture2D diffuseTexture) - model.Sections[j].Parameters.Diffuse = diffuseTexture; - if (textureDataIdx.TryGetValue(out FPackageIndex normal, "Normal") && - normal.Load() is UTexture2D normalTexture) - model.Sections[j].Parameters.Normal = normalTexture; - if (textureDataIdx.TryGetValue(out FPackageIndex specular, "Specular") && - specular.Load() is UTexture2D specularTexture) - model.Sections[j].Parameters.Specular = specularTexture; - } - } - if (staticMeshComp.TryGetValue(out FPackageIndex[] overrideMaterials, "OverrideMaterials")) - { - var max = model.Sections.Length - 1; - for (var j = 0; j < overrideMaterials.Length; j++) - { - if (j > max) break; - if (overrideMaterials[j].Load() is not UMaterialInterface unrealMaterial) continue; - model.Sections[j].SwapMaterial(unrealMaterial); - } - } - - _models[guid] = model; - } - } - _camera = new Camera(new Vector3(0f, 5f, 5f), Vector3.Zero, 0.01f, 1000f, 5f); - break; - } - default: - throw new ArgumentOutOfRangeException(nameof(export)); - } - - DoLoop(); - } - - public void SwapMaterial(UMaterialInstance mi) - { - if (!_models.TryGetValue(_options.SelectedModel, out var model) || - !_options.TryGetSection(model, out var section)) return; - - section.SwapMaterial(mi); - _options.SwapMaterial(false); - DoLoop(); - } - - private void DoLoop() - { - if (_options.Append) _options.Append = false; _window.Run(); - // if (_window.IsInitialized) - // { - // if (!_window.GLContext.IsCurrent) - // { - // _window.GLContext.MakeCurrent(); - // } - // - // _append = false; - // _window.IsVisible = true; - // var model = _models.Last(); - // model.Value.Setup(_gl); - // _imGui.Increment(model.Key); - // } - // else _window.Initialize(); - // - // while (!_window.IsClosing && _window.IsVisible) - // { - // _window.DoEvents(); - // if (!_window.IsClosing && _window.IsVisible) - // _window.DoUpdate(); - // if (_window.IsClosing || !_window.IsVisible) - // return; - // _window.DoRender(); - // } - // - // _window.DoEvents(); - // if (_window.IsClosing) _window.Reset(); } - private void SetupCamera(FBox box) - { - var far = box.Max.Max(); - var center = box.GetCenter(); - var position = new Vector3(0f, center.Z, box.Max.Y * 3); - var speed = far / 2f; - if (speed > _previousSpeed) - { - _camera = new Camera(position, center, 0.01f, far * 50f, speed); - _previousSpeed = _camera.Speed; - } - } - - private void OnLoad() - { - _window.SetWindowIcon(ref _icon); - _window.Center(); - - var input = _window.CreateInput(); - _keyboard = input.Keyboards[0]; - _mouse = input.Mice[0]; - - _gl = GL.GetApi(_window); - _gl.Enable(EnableCap.Blend); - _gl.Enable(EnableCap.DepthTest); - _gl.Enable(EnableCap.Multisample); - _gl.StencilOp(StencilOp.Keep, StencilOp.Replace, StencilOp.Replace); - _gl.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); - - _imGui = new SnimGui(_gl, _window, input); - - _framebuffer.Setup(_gl); - _skybox.Setup(_gl); - _grid.Setup(_gl); - - _shader = new Shader(_gl); - _outline = new Shader(_gl, "outline"); - _diffuseLight = new Vector3(0.75f); - _specularLight = new Vector3(0.5f); - foreach (var model in _models.Values) - { - model.Setup(_gl); - } - } - - /// - /// friendly reminder this is called each frame - /// don't do crazy things inside - /// - private void OnRender(double deltaTime) - { - _imGui.Update((float) deltaTime); - - ClearWhatHasBeenDrawn(); // in main window - - _framebuffer.Bind(); // switch to dedicated window - ClearWhatHasBeenDrawn(); // in dedicated window - - _skybox.Bind(_camera); - _grid.Bind(_camera); - - var viewMatrix = _camera.GetViewMatrix(); - var projMatrix = _camera.GetProjectionMatrix(); - - _outline.Use(); - _outline.SetUniform("uView", viewMatrix); - _outline.SetUniform("uProjection", projMatrix); - _outline.SetUniform("viewPos", _camera.Position); - - _shader.Use(); - _shader.SetUniform("uView", viewMatrix); - _shader.SetUniform("uProjection", projMatrix); - _shader.SetUniform("viewPos", _camera.Position); - - _shader.SetUniform("material.diffuseMap", 0); - _shader.SetUniform("material.normalMap", 1); - _shader.SetUniform("material.specularMap", 2); - _shader.SetUniform("material.emissionMap", 3); - - _shader.SetUniform("light.position", _camera.Position); - _shader.SetUniform("light.diffuse", _diffuseLight); - _shader.SetUniform("light.specular", _specularLight); - - foreach (var model in _models.Values.Where(model => model.Show)) - { - model.Bind(_shader); - } - _gl.Enable(EnableCap.StencilTest); // I don't get why this must be here but it works now so... - foreach (var model in _models.Values.Where(model => model.IsSelected && model.Show)) - { - model.Outline(_outline); - } - - _imGui.Construct(ref _options, _size, _framebuffer, _camera, _mouse, _models); - - _framebuffer.BindMsaa(); - _framebuffer.Bind(0); // switch back to main window - _framebuffer.BindStuff(); - - _imGui.Render(); // render ImGui in main window - } - - private void ClearWhatHasBeenDrawn() - { - _gl.ClearColor(1.0f, 0.102f, 0.129f, 1.0f); - _gl.Clear((uint) ClearBufferMask.ColorBufferBit | (uint) ClearBufferMask.DepthBufferBit | (uint) ClearBufferMask.StencilBufferBit); - _gl.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); - } - - private void OnUpdate(double deltaTime) - { - if (ImGui.GetIO().WantTextInput) return; - var multiplier = _keyboard.IsKeyPressed(Key.ShiftLeft) ? 2f : 1f; - var moveSpeed = _camera.Speed * multiplier * (float) deltaTime; - if (_keyboard.IsKeyPressed(Key.W)) - _camera.Position += moveSpeed * _camera.Direction; - if (_keyboard.IsKeyPressed(Key.S)) - _camera.Position -= moveSpeed * _camera.Direction; - if (_keyboard.IsKeyPressed(Key.A)) - _camera.Position -= Vector3.Normalize(Vector3.Cross(_camera.Direction, _camera.Up)) * moveSpeed; - if (_keyboard.IsKeyPressed(Key.D)) - _camera.Position += Vector3.Normalize(Vector3.Cross(_camera.Direction, _camera.Up)) * moveSpeed; - if (_keyboard.IsKeyPressed(Key.E)) - _camera.Position += moveSpeed * _camera.Up; - if (_keyboard.IsKeyPressed(Key.Q)) - _camera.Position -= moveSpeed * _camera.Up; - if (_keyboard.IsKeyPressed(Key.X)) - _camera.ModifyZoom(-.5f); - if (_keyboard.IsKeyPressed(Key.C)) - _camera.ModifyZoom(+.5f); - - if (_keyboard.IsKeyPressed(Key.H)) - { - // because we lose GLContext when the window is invisible after a few seconds (it's apparently a bug) - // we can't use GLContext back on next load and so, for now, we basically have to reset the window - // if we can't use GLContext, we can't generate handles, can't interact with IsVisible, State, etc - // tldr we dispose everything but don't clear models, so the more you append, the longer it takes to load - _options.Append = true; - _window.Close(); - // _window.IsVisible = false; - } - if (_keyboard.IsKeyPressed(Key.Escape)) - _window.Close(); - } - - private void OnClose() + public void SwapMaterial(UMaterialInstance mi) { - _framebuffer.Dispose(); - _grid.Dispose(); - _skybox.Dispose(); - _shader.Dispose(); - _outline.Dispose(); - foreach (var model in _models.Values) - { - model.Dispose(); - } - if (!_options.Append) - { - _models.Clear(); - _options.Reset(); - _previousSpeed = 0f; - } - _imGui.Dispose(); - _window.Dispose(); - _gl.Dispose(); + _window.SwapMaterial(mi); } } diff --git a/FModel/Views/Snooper/Texture.cs b/FModel/Views/Snooper/Texture.cs index f2ca7f39..e87899e5 100644 --- a/FModel/Views/Snooper/Texture.cs +++ b/FModel/Views/Snooper/Texture.cs @@ -1,17 +1,14 @@ -using Silk.NET.OpenGL; -using System; +using System; using System.Windows; using CUE4Parse.UE4.Assets.Exports.Texture; -using SixLabors.ImageSharp; -using SixLabors.ImageSharp.PixelFormats; +using OpenTK.Graphics.OpenGL4; using SkiaSharp; namespace FModel.Views.Snooper; public class Texture : IDisposable { - private readonly uint _handle; - private readonly GL _gl; + private readonly int _handle; private readonly TextureType _type; public readonly string Type; @@ -20,52 +17,50 @@ public class Texture : IDisposable public readonly EPixelFormat Format; public readonly uint ImportedWidth; public readonly uint ImportedHeight; - public readonly uint Width; - public readonly uint Height; + public readonly int Width; + public readonly int Height; public string Label; - public Texture(GL gl, TextureType type) + public Texture(TextureType type) { - _gl = gl; - _handle = _gl.GenTexture(); + _handle = GL.GenTexture(); _type = type; - Label = "(?) Click to Copy Path"; } - public Texture(GL gl, uint width, uint height) : this(gl, TextureType.MsaaFramebuffer) + public Texture(uint width, uint height) : this(TextureType.MsaaFramebuffer) { Width = width; Height = height; Bind(TextureUnit.Texture0); - _gl.TexImage2DMultisample(TextureTarget.Texture2DMultisample, Constants.SAMPLES_COUNT, InternalFormat.Rgb, Width, Height, Silk.NET.OpenGL.Boolean.True); + GL.TexImage2DMultisample(TextureTargetMultisample.Texture2DMultisample, Constants.SAMPLES_COUNT, PixelInternalFormat.Rgb, Width, Height, true); - _gl.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureMinFilter, (int) GLEnum.Nearest); - _gl.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureMagFilter, (int) GLEnum.Nearest); - _gl.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureWrapS, (int) GLEnum.ClampToEdge); - _gl.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureWrapT, (int) GLEnum.ClampToEdge); + GL.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureMinFilter, (int) GLEnum.Nearest); + GL.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureMagFilter, (int) GLEnum.Nearest); + GL.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureWrapS, (int) GLEnum.ClampToEdge); + GL.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureWrapT, (int) GLEnum.ClampToEdge); - _gl.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2DMultisample, _handle, 0); + GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2DMultisample, _handle, 0); } - public unsafe Texture(GL gl, int width, int height) : this(gl, TextureType.Framebuffer) + public unsafe Texture(int width, int height) : this(TextureType.Framebuffer) { - Width = (uint) width; - Height = (uint) height; + Width = width; + Height = height; Bind(TextureUnit.Texture0); - _gl.TexImage2D(TextureTarget.Texture2D, 0, (int) InternalFormat.Rgb, Width, Height, 0, PixelFormat.Rgb, PixelType.UnsignedByte, null); + GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, Width, Height, 0, PixelFormat.Rgb, PixelType.UnsignedByte, null); - _gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) GLEnum.Linear); - _gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) GLEnum.Linear); - _gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) GLEnum.ClampToEdge); - _gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) GLEnum.ClampToEdge); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) GLEnum.Linear); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) GLEnum.Linear); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) GLEnum.ClampToEdge); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) GLEnum.ClampToEdge); - _gl.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, _handle, 0); + GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, _handle, 0); } - public unsafe Texture(GL gl, byte[] data, uint width, uint height, SKColorType colorType, UTexture2D texture2D) : this(gl, TextureType.Normal) + public unsafe Texture(byte[] data, uint width, uint height, SKColorType colorType, UTexture2D texture2D) : this(TextureType.Normal) { Type = texture2D.ExportType; Name = texture2D.Name; @@ -79,17 +74,17 @@ public unsafe Texture(GL gl, byte[] data, uint width, uint height, SKColorType c fixed (void* d = &data[0]) { - _gl.TexImage2D(TextureTarget.Texture2D, 0, (int) InternalFormat.Rgb, Width, Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, d); - _gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) GLEnum.LinearMipmapLinear); - _gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) GLEnum.Linear); - _gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBaseLevel, 0); - _gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMaxLevel, 8); + GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, Width, Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, d); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) GLEnum.LinearMipmapLinear); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) GLEnum.Linear); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBaseLevel, 0); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMaxLevel, 8); - _gl.GenerateMipmap(TextureTarget.Texture2D); + GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); } } - public unsafe Texture(GL gl, string[] textures) : this(gl, TextureType.Cubemap) + public unsafe Texture(string[] textures) : this(TextureType.Cubemap) { Bind(TextureUnit.Texture0); @@ -99,7 +94,7 @@ public unsafe Texture(GL gl, string[] textures) : this(gl, TextureType.Cubemap) using var img = Image.Load(info.Stream); Width = (uint) img.Width; // we don't care anyway Height = (uint) img.Height; // we don't care anyway - _gl.TexImage2D(TextureTarget.TextureCubeMapPositiveX + t, 0, InternalFormat.Rgba8, Width, Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, null); + GL.TexImage2D(TextureTarget.TextureCubeMapPositiveX + t, 0, PixelInternalFormat.Rgba8, Width, Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, null); img.ProcessPixelRows(accessor => { @@ -107,37 +102,37 @@ public unsafe Texture(GL gl, string[] textures) : this(gl, TextureType.Cubemap) { fixed (void* data = accessor.GetRowSpan(y)) { - gl.TexSubImage2D(TextureTarget.TextureCubeMapPositiveX + t, 0, 0, y, (uint) accessor.Width, 1, PixelFormat.Rgba, PixelType.UnsignedByte, data); + GL.TexSubImage2D(TextureTarget.TextureCubeMapPositiveX + t, 0, 0, y, (uint) accessor.Width, 1, PixelFormat.Rgba, PixelType.UnsignedByte, data); } } }); } - _gl.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter, (int) GLEnum.Linear); - _gl.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter, (int) GLEnum.Linear); - _gl.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapR, (int) GLEnum.ClampToEdge); - _gl.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS, (int) GLEnum.ClampToEdge); - _gl.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (int) GLEnum.ClampToEdge); + GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter, (int) GLEnum.Linear); + GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter, (int) GLEnum.Linear); + GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapR, (int) GLEnum.ClampToEdge); + GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS, (int) GLEnum.ClampToEdge); + GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (int) GLEnum.ClampToEdge); } - public unsafe Texture(GL gl, uint width, uint height, IntPtr data) : this(gl, TextureType.Normal) + public unsafe Texture(uint width, uint height, IntPtr data) : this(TextureType.Normal) { Width = width; Height = height; Bind(TextureTarget.Texture2D); - _gl.TexStorage2D(GLEnum.Texture2D, 1, SizedInternalFormat.Rgba8, Width, Height); - _gl.TexSubImage2D(GLEnum.Texture2D, 0, 0, 0, Width, Height, PixelFormat.Bgra, PixelType.UnsignedByte, (void*) data); + GL.TexStorage2D(TextureTarget2d.Texture2D, 1, SizedInternalFormat.Rgba8, Width, Height); + GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, Width, Height, PixelFormat.Bgra, PixelType.UnsignedByte, (void*) data); - _gl.TexParameterI(GLEnum.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); - _gl.TexParameterI(GLEnum.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); + GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); + GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); - _gl.TexParameterI(GLEnum.Texture2D, TextureParameterName.TextureMaxLevel, 1 - 1); + GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureMaxLevel, 1 - 1); } public void Bind(TextureUnit textureSlot) { - _gl.ActiveTexture(textureSlot); + GL.ActiveTexture(textureSlot); Bind(_type switch { TextureType.Cubemap => TextureTarget.TextureCubeMap, @@ -148,24 +143,24 @@ public void Bind(TextureUnit textureSlot) public void Bind(TextureTarget target) { - _gl.BindTexture(target, _handle); + GL.BindTexture(target, _handle); } - public void SetMinFilter(TextureMinFilter filter) + public void SetMinFilter(int filter) { - _gl.TexParameterI(GLEnum.Texture2D, TextureParameterName.TextureMinFilter, (int)filter); + GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, ref filter); } - public void SetMagFilter(TextureMagFilter filter) + public void SetMagFilter(int filter) { - _gl.TexParameterI(GLEnum.Texture2D, TextureParameterName.TextureMagFilter, (int)filter); + GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, ref filter); } public IntPtr GetPointer() => (IntPtr) _handle; public void Dispose() { - _gl.DeleteTexture(_handle); + GL.DeleteTexture(_handle); } } diff --git a/FModel/Views/Snooper/VertexArrayObject.cs b/FModel/Views/Snooper/VertexArrayObject.cs index c1d49a91..6f2dc2a6 100644 --- a/FModel/Views/Snooper/VertexArrayObject.cs +++ b/FModel/Views/Snooper/VertexArrayObject.cs @@ -1,72 +1,70 @@ using System; using System.Numerics; -using Silk.NET.OpenGL; +using OpenTK.Graphics.OpenGL4; namespace FModel.Views.Snooper; public class VertexArrayObject : IDisposable where TVertexType : unmanaged where TIndexType : unmanaged { - private readonly uint _handle; - private readonly GL _gl; + private readonly int _handle; - public VertexArrayObject(GL gl, BufferObject vbo, BufferObject ebo) + public VertexArrayObject(BufferObject vbo, BufferObject ebo) { - _gl = gl; + _handle = GL.GenVertexArray(); - _handle = _gl.GenVertexArray(); Bind(); vbo.Bind(); ebo.Bind(); } - public unsafe void VertexAttributePointer(uint index, int count, VertexAttribPointerType type, uint vertexSize, int offSet) + public unsafe void VertexAttributePointer(uint index, int count, VertexAttribPointerType type, int vertexSize, int offset) { switch (type) { case VertexAttribPointerType.Int: - _gl.VertexAttribIPointer(index, count, VertexAttribIType.Int, vertexSize * (uint) sizeof(TVertexType), (void*) (offSet * sizeof(TVertexType))); + GL.VertexAttribIPointer(index, count, VertexAttribIntegerType.Int, vertexSize * sizeof(TVertexType), (IntPtr) (offset * sizeof(TVertexType))); break; default: - _gl.VertexAttribPointer(index, count, type, false, vertexSize * (uint) sizeof(TVertexType), (void*) (offSet * sizeof(TVertexType))); + GL.VertexAttribPointer(index, count, type, false, vertexSize * sizeof(TVertexType), offset * sizeof(TVertexType)); break; } - _gl.EnableVertexAttribArray(index); + GL.EnableVertexAttribArray(index); } public void Bind() { - _gl.BindVertexArray(_handle); + GL.BindVertexArray(_handle); } public unsafe void BindInstancing() { Bind(); - var vec4Size = (uint) sizeof(Vector4); - _gl.EnableVertexAttribArray(7); - _gl.VertexAttribPointer(7, 4, VertexAttribPointerType.Float, false, 4 * vec4Size, (void*)0); - _gl.EnableVertexAttribArray(8); - _gl.VertexAttribPointer(8, 4, VertexAttribPointerType.Float, false, 4 * vec4Size, (void*)(1 * vec4Size)); - _gl.EnableVertexAttribArray(9); - _gl.VertexAttribPointer(9, 4, VertexAttribPointerType.Float, false, 4 * vec4Size, (void*)(2 * vec4Size)); - _gl.EnableVertexAttribArray(10); - _gl.VertexAttribPointer(10, 4, VertexAttribPointerType.Float, false, 4 * vec4Size, (void*)(3 * vec4Size)); + var size = sizeof(Vector4); + GL.EnableVertexAttribArray(7); + GL.VertexAttribPointer(7, 4, VertexAttribPointerType.Float, false, 4 * size, 0); + GL.EnableVertexAttribArray(8); + GL.VertexAttribPointer(8, 4, VertexAttribPointerType.Float, false, 4 * size, 1 * size); + GL.EnableVertexAttribArray(9); + GL.VertexAttribPointer(9, 4, VertexAttribPointerType.Float, false, 4 * size, 2 * size); + GL.EnableVertexAttribArray(10); + GL.VertexAttribPointer(10, 4, VertexAttribPointerType.Float, false, 4 * size, 3 * size); - _gl.VertexAttribDivisor(7, 1); - _gl.VertexAttribDivisor(8, 1); - _gl.VertexAttribDivisor(9, 1); - _gl.VertexAttribDivisor(10, 1); + GL.VertexAttribDivisor(7, 1); + GL.VertexAttribDivisor(8, 1); + GL.VertexAttribDivisor(9, 1); + GL.VertexAttribDivisor(10, 1); Unbind(); } public void Unbind() { - _gl.BindVertexArray(0); + GL.BindVertexArray(0); } public void Dispose() { - _gl.DeleteVertexArray(_handle); + GL.DeleteVertexArray(_handle); } } diff --git a/FModel/glfw3.dll b/FModel/glfw3.dll deleted file mode 100644 index 733404cf..00000000 Binary files a/FModel/glfw3.dll and /dev/null differ