diff --git a/Examples/Complete/ComputeFractal/Core/ComputeFractal.cs b/Examples/Complete/ComputeFractal/Core/ComputeFractal.cs index 9fdfe08fb..44df7f515 100644 --- a/Examples/Complete/ComputeFractal/Core/ComputeFractal.cs +++ b/Examples/Complete/ComputeFractal/Core/ComputeFractal.cs @@ -104,7 +104,7 @@ public override void RenderAFrame() RWTexture.AsImage = true; RC.SetEffect(_computeShader); - RC.DispatchCompute(-1, RWTexture.Width / 16, RWTexture.Width / 16, 1); + RC.DispatchCompute(-1, (uint)(RWTexture.Width / 16), (uint)(RWTexture.Width / 16), 1); RC.MemoryBarrier(); RWTexture.AsImage = false; diff --git a/Examples/Complete/PointCloudPotree2/ImGui/PointCloudControlCore.cs b/Examples/Complete/PointCloudPotree2/ImGui/PointCloudControlCore.cs index 437ce9a1c..fb8faea5a 100644 --- a/Examples/Complete/PointCloudPotree2/ImGui/PointCloudControlCore.cs +++ b/Examples/Complete/PointCloudPotree2/ImGui/PointCloudControlCore.cs @@ -143,12 +143,7 @@ protected override ITextureHandle RenderAFrame() { ReadyToLoadNewFile = true; - return new Engine.Imp.Graphics.Desktop.TextureHandle - { - DepthRenderBufferHandle = -1, - FrameBufferHandle = -1, - TexHandle = -1 - }; + return new Engine.Imp.Graphics.Desktop.TextureHandle(); } if (PtRenderingParams.Instance.EdlStrength != 0f) diff --git a/src/Engine/Common/AttributeLocations.cs b/src/Engine/Common/AttributeLocations.cs index 8ae9bdd22..77ec729a6 100644 --- a/src/Engine/Common/AttributeLocations.cs +++ b/src/Engine/Common/AttributeLocations.cs @@ -8,56 +8,56 @@ public static class AttributeLocations /// /// The vertex attribute location index. /// - public static readonly int VertexAttribLocation = 0; + public static readonly uint VertexAttribLocation = 0; /// /// The color attribute location index. /// - public static readonly int ColorAttribLocation = 1; + public static readonly uint ColorAttribLocation = 1; /// /// The color attribute location index. /// - public static readonly int Color1AttribLocation = 2; + public static readonly uint Color1AttribLocation = 2; /// /// The color attribute location index. /// - public static readonly int Color2AttribLocation = 3; + public static readonly uint Color2AttribLocation = 3; /// /// The normal attribute location index. /// - public static readonly int NormalAttribLocation = 4; + public static readonly uint NormalAttribLocation = 4; /// /// The uv attribute location index. /// - public static readonly int UvAttribLocation = 5; + public static readonly uint UvAttribLocation = 5; /// /// The tangent attribute location index. /// - public static readonly int TangentAttribLocation = 6; + public static readonly uint TangentAttribLocation = 6; /// /// The bitangent attribute location index. /// - public static readonly int BitangentAttribLocation = 7; + public static readonly uint BitangentAttribLocation = 7; /// /// The bone weight attribute location index. /// - public static readonly int BoneWeightAttribLocation = 8; + public static readonly uint BoneWeightAttribLocation = 8; /// /// The bone index attribute location index. /// - public static readonly int BoneIndexAttribLocation = 9; + public static readonly uint BoneIndexAttribLocation = 9; /// /// The Fusee platform id attribute location index. /// - public static readonly int FuseePlatformIdLocation = 10; + public static readonly uint FuseePlatformIdLocation = 10; } } \ No newline at end of file diff --git a/src/Engine/Common/IRenderContextImp.cs b/src/Engine/Common/IRenderContextImp.cs index 3105f554e..8cb6cc834 100644 --- a/src/Engine/Common/IRenderContextImp.cs +++ b/src/Engine/Common/IRenderContextImp.cs @@ -647,7 +647,7 @@ public interface IRenderContextImp /// The number of work groups to be launched in the X dimension. /// The number of work groups to be launched in the Y dimension. /// he number of work groups to be launched in the Z dimension. - void DispatchCompute(int kernelIndex, int threadGroupsX, int threadGroupsY, int threadGroupsZ); + void DispatchCompute(int kernelIndex, uint threadGroupsX, uint threadGroupsY, uint threadGroupsZ); /// /// Defines a barrier ordering memory transactions. At the moment it will insert all supported barriers. @@ -655,14 +655,6 @@ public interface IRenderContextImp /// void MemoryBarrier(); - /// - /// Draws a Debug Line in 3D Space by using a start and end point (float3). - /// - /// The start point of the DebugLine. - /// The endpoint of the DebugLine. - /// The color of the DebugLine. - void DebugLine(float3 start, float3 end, float4 color); - /// /// Gets the content of the buffer. /// diff --git a/src/Engine/Common/IStorageBuffer.cs b/src/Engine/Common/IStorageBuffer.cs index 8a04d6fd7..e2316202a 100644 --- a/src/Engine/Common/IStorageBuffer.cs +++ b/src/Engine/Common/IStorageBuffer.cs @@ -26,6 +26,6 @@ public interface IStorageBuffer : IDisposable /// The binding index point the SSBO will be bound to. /// Caution: the binding point should not be hard coded in the shader code! /// - int BindingIndex { get; set; } + uint BindingIndex { get; set; } } } \ No newline at end of file diff --git a/src/Engine/Core/Effects/StorageBuffer.cs b/src/Engine/Core/Effects/StorageBuffer.cs index 23d39b192..929b0d4e8 100644 --- a/src/Engine/Core/Effects/StorageBuffer.cs +++ b/src/Engine/Core/Effects/StorageBuffer.cs @@ -13,7 +13,7 @@ public class StorageBuffer : IStorageBuffer where T : struct /// The binding index point the SSBO will be bound to. /// Caution: the binding point should not be hard coded in the shader code! /// - public int BindingIndex { get; set; } + public uint BindingIndex { get; set; } /// /// Return the number of buffer elements. @@ -56,7 +56,7 @@ public IBufferHandle BufferHandle /// The (fixed) count of buffer elements. /// The size (byte) of one buffer element. /// Int that needs to be unique throughout the shader. - public StorageBuffer(RenderCanvas rc, int count, int tSize, int blockBindingIndex) + public StorageBuffer(RenderCanvas rc, int count, int tSize, uint blockBindingIndex) { _count = count; _tSize = tSize; diff --git a/src/Engine/Core/RenderContext.cs b/src/Engine/Core/RenderContext.cs index 8fe554139..76d0d6770 100644 --- a/src/Engine/Core/RenderContext.cs +++ b/src/Engine/Core/RenderContext.cs @@ -1767,30 +1767,24 @@ public void MemoryBarrier() /// The number of work groups to be launched in the X dimension. /// The number of work groups to be launched in the Y dimension. /// he number of work groups to be launched in the Z dimension. - public void DispatchCompute(int kernelIndex, int threadGroupsX, int threadGroupsY, int threadGroupsZ) + public void DispatchCompute(int kernelIndex, uint threadGroupsX, uint threadGroupsY, uint threadGroupsZ) { if (_currentEffect == null) throw new NullReferenceException("No Compute Shader bound."); if (_currentEffect.GetType() != typeof(ComputeShader)) throw new NullReferenceException("Bound Effect isn't a Compute Shader."); - try - { - var cFx = GetCompiledFxForRenderMethod(true); - SetCompiledFx(cFx.GpuHandle); - SetRenderStateSet(_currentEffect.RendererStates); - SetGlobalParamsInCurrentFx(cFx); - UpdateAllActiveFxParams(cFx); - - _rci.DispatchCompute(kernelIndex, threadGroupsX, threadGroupsY, threadGroupsZ); - - // After rendering always cleanup pending meshes, textures and shader effects - _meshManager.Cleanup(); - _textureManager.Cleanup(); - _effectManager.Cleanup(); - } - catch (Exception ex) - { - throw new Exception("Error while rendering pass ", ex); - } + + var cFx = GetCompiledFxForRenderMethod(true); + SetCompiledFx(cFx.GpuHandle); + SetRenderStateSet(_currentEffect.RendererStates); + SetGlobalParamsInCurrentFx(cFx); + UpdateAllActiveFxParams(cFx); + + _rci.DispatchCompute(kernelIndex, threadGroupsX, threadGroupsY, threadGroupsZ); + + // After rendering always cleanup pending meshes, textures and shader effects + _meshManager.Cleanup(); + _textureManager.Cleanup(); + _effectManager.Cleanup(); } /// diff --git a/src/Engine/Imp/Graphics/Android/BufferHandle.cs b/src/Engine/Imp/Graphics/Android/BufferHandle.cs new file mode 100644 index 000000000..da9a5f5e6 --- /dev/null +++ b/src/Engine/Imp/Graphics/Android/BufferHandle.cs @@ -0,0 +1,28 @@ +using Fusee.Engine.Common; + +namespace Fusee.Engine.Imp.Graphics.Android +{ + /// + /// RenderBuffer for OpenGL, an integer value is used as a handle + /// + internal class RenderBufferHandle : IBufferHandle + { + internal int Handle = -1; + } + + /// + /// FrameBuffer for OpenGL, an integer value is used as a handle + /// + internal class FrameBufferHandle : IBufferHandle + { + internal int Handle = -1; + } + + /// + /// StorageBuffer for OpenGL, an integer value is used as a handle + /// + class StorageBufferHandle : IBufferHandle + { + internal int Handle = -1; + } +} \ No newline at end of file diff --git a/src/Engine/Imp/Graphics/Shared/MeshImp.cs b/src/Engine/Imp/Graphics/Android/MeshImp.cs similarity index 95% rename from src/Engine/Imp/Graphics/Shared/MeshImp.cs rename to src/Engine/Imp/Graphics/Android/MeshImp.cs index e92ad0f56..2864ebb17 100644 --- a/src/Engine/Imp/Graphics/Shared/MeshImp.cs +++ b/src/Engine/Imp/Graphics/Android/MeshImp.cs @@ -1,21 +1,7 @@ using Fusee.Engine.Common; -#if PLATFORM_DESKTOP - -namespace Fusee.Engine.Imp.Graphics.Desktop -#elif PLATFORM_ANDROID - namespace Fusee.Engine.Imp.Graphics.Android -#endif { - /// - /// Contains a handle for any type of attribute buffer stored on GPU memory such as vertices, normals, uvs etc. - /// - public class AttributeImp : IAttribImp - { - internal int AttributeBufferObject; - } - /// /// This is the implementation of the interface. /// It is used to check the status of the informations of a mesh and flush informations if required. diff --git a/src/Engine/Imp/Graphics/Android/RenderContextImp.cs b/src/Engine/Imp/Graphics/Android/RenderContextImp.cs index 72c7ffc6e..763fee9e5 100644 --- a/src/Engine/Imp/Graphics/Android/RenderContextImp.cs +++ b/src/Engine/Imp/Graphics/Android/RenderContextImp.cs @@ -640,16 +640,16 @@ public IShaderHandle CreateShaderProgram(string vs, string ps, string gs = null) GL.AttachShader(program, vertexObject); // enable GLSL (ES) shaders to use fuVertex, fuColor and fuNormal attributes - GL.BindAttribLocation(program, AttributeLocations.VertexAttribLocation, UniformNameDeclarations.Vertex); - GL.BindAttribLocation(program, AttributeLocations.ColorAttribLocation, UniformNameDeclarations.VertexColor); - GL.BindAttribLocation(program, AttributeLocations.Color1AttribLocation, UniformNameDeclarations.VertexColor1); - GL.BindAttribLocation(program, AttributeLocations.Color2AttribLocation, UniformNameDeclarations.VertexColor2); - GL.BindAttribLocation(program, AttributeLocations.UvAttribLocation, UniformNameDeclarations.TextureCoordinates); - GL.BindAttribLocation(program, AttributeLocations.NormalAttribLocation, UniformNameDeclarations.Normal); - GL.BindAttribLocation(program, AttributeLocations.TangentAttribLocation, UniformNameDeclarations.Tangent); - GL.BindAttribLocation(program, AttributeLocations.BoneIndexAttribLocation, UniformNameDeclarations.BoneIndex); - GL.BindAttribLocation(program, AttributeLocations.BoneWeightAttribLocation, UniformNameDeclarations.BoneWeight); - GL.BindAttribLocation(program, AttributeLocations.BitangentAttribLocation, UniformNameDeclarations.Bitangent); + GL.BindAttribLocation(program, (int)AttributeLocations.VertexAttribLocation, UniformNameDeclarations.Vertex); + GL.BindAttribLocation(program, (int)AttributeLocations.ColorAttribLocation, UniformNameDeclarations.VertexColor); + GL.BindAttribLocation(program, (int)AttributeLocations.Color1AttribLocation, UniformNameDeclarations.VertexColor1); + GL.BindAttribLocation(program, (int)AttributeLocations.Color2AttribLocation, UniformNameDeclarations.VertexColor2); + GL.BindAttribLocation(program, (int)AttributeLocations.UvAttribLocation, UniformNameDeclarations.TextureCoordinates); + GL.BindAttribLocation(program, (int)AttributeLocations.NormalAttribLocation, UniformNameDeclarations.Normal); + GL.BindAttribLocation(program, (int)AttributeLocations.TangentAttribLocation, UniformNameDeclarations.Tangent); + GL.BindAttribLocation(program, (int)AttributeLocations.BoneIndexAttribLocation, UniformNameDeclarations.BoneIndex); + GL.BindAttribLocation(program, (int)AttributeLocations.BoneWeightAttribLocation, UniformNameDeclarations.BoneWeight); + GL.BindAttribLocation(program, (int)AttributeLocations.BitangentAttribLocation, UniformNameDeclarations.Bitangent); GL.LinkProgram(program); return new ShaderHandleImp { Handle = program }; @@ -1688,7 +1688,7 @@ public void MemoryBarrier() /// The number of work groups to be launched in the X dimension. /// The number of work groups to be launched in the Y dimension. /// he number of work groups to be launched in the Z dimension. - public void DispatchCompute(int kernelIndex, int threadGroupsX, int threadGroupsY, int threadGroupsZ) + public void DispatchCompute(int kernelIndex, uint threadGroupsX, uint threadGroupsY, uint threadGroupsZ) { GL.DispatchCompute(threadGroupsX, threadGroupsY, threadGroupsZ); } diff --git a/src/Engine/Imp/Graphics/Shared/ShaderHandleImp.cs b/src/Engine/Imp/Graphics/Android/ShaderHandleImp.cs similarity index 75% rename from src/Engine/Imp/Graphics/Shared/ShaderHandleImp.cs rename to src/Engine/Imp/Graphics/Android/ShaderHandleImp.cs index da2a64344..3f3b11220 100644 --- a/src/Engine/Imp/Graphics/Shared/ShaderHandleImp.cs +++ b/src/Engine/Imp/Graphics/Android/ShaderHandleImp.cs @@ -1,10 +1,6 @@ using Fusee.Engine.Common; -#if PLATFORM_DESKTOP -namespace Fusee.Engine.Imp.Graphics.Desktop -#elif PLATFORM_ANDROID namespace Fusee.Engine.Imp.Graphics.Android -#endif { /// /// Implementation of for usage with OpenTK framework. diff --git a/src/Engine/Imp/Graphics/Shared/TextureHandle.cs b/src/Engine/Imp/Graphics/Android/TextureHandle.cs similarity index 66% rename from src/Engine/Imp/Graphics/Shared/TextureHandle.cs rename to src/Engine/Imp/Graphics/Android/TextureHandle.cs index db794b984..5620701c0 100644 --- a/src/Engine/Imp/Graphics/Shared/TextureHandle.cs +++ b/src/Engine/Imp/Graphics/Android/TextureHandle.cs @@ -1,13 +1,9 @@ using Fusee.Engine.Common; -#if PLATFORM_DESKTOP -namespace Fusee.Engine.Imp.Graphics.Desktop -#elif PLATFORM_ANDROID namespace Fusee.Engine.Imp.Graphics.Android -#endif { /// - /// Texture Implementation for OpenTK, an integer value is used as a handle + /// Texture Implementation for OpenGL, an integer value is used as a handle /// public class TextureHandle : ITextureHandle { diff --git a/src/Engine/Imp/Graphics/Blazor/RenderContextImp.cs b/src/Engine/Imp/Graphics/Blazor/RenderContextImp.cs index de6662338..7b2bbdd67 100644 --- a/src/Engine/Imp/Graphics/Blazor/RenderContextImp.cs +++ b/src/Engine/Imp/Graphics/Blazor/RenderContextImp.cs @@ -2650,7 +2650,7 @@ public void ConnectBufferToShaderStorage(IShaderHandle currentProgram, IStorageB /// /// /// - public void DispatchCompute(int kernelIndex, int threadGroupsX, int threadGroupsY, int threadGroupsZ) + public void DispatchCompute(int kernelIndex, uint threadGroupsX, uint threadGroupsY, uint threadGroupsZ) { throw new NotImplementedException(); } diff --git a/src/Engine/Imp/Graphics/Blazor/ShaderHandleImp.cs b/src/Engine/Imp/Graphics/Blazor/ShaderHandleImp.cs new file mode 100644 index 000000000..232a42e5d --- /dev/null +++ b/src/Engine/Imp/Graphics/Blazor/ShaderHandleImp.cs @@ -0,0 +1,13 @@ +using Fusee.Engine.Common; + +namespace Fusee.Engine.Imp.Graphics.Blazor +{ + /// + /// Implementation of the + /// This object is passed to WebGL and represents a shader program + /// + public class ShaderHandleImp : IShaderHandle + { + internal WebGLProgram Handle; + } +} \ No newline at end of file diff --git a/src/Engine/Imp/Graphics/Blazor/ShaderParam.cs b/src/Engine/Imp/Graphics/Blazor/ShaderParam.cs index b7e6b8edf..0869290d2 100644 --- a/src/Engine/Imp/Graphics/Blazor/ShaderParam.cs +++ b/src/Engine/Imp/Graphics/Blazor/ShaderParam.cs @@ -10,13 +10,4 @@ public class ShaderParam : IShaderParam { internal WebGLUniformLocation handle; } - - /// - /// Implementation of the - /// This object is passed to WebGL and represents a shader program - /// - public class ShaderHandleImp : IShaderHandle - { - internal WebGLProgram Handle; - } } \ No newline at end of file diff --git a/src/Engine/Imp/Graphics/Desktop/AttributeImp.cs b/src/Engine/Imp/Graphics/Desktop/AttributeImp.cs new file mode 100644 index 000000000..3a1c3d4d7 --- /dev/null +++ b/src/Engine/Imp/Graphics/Desktop/AttributeImp.cs @@ -0,0 +1,13 @@ +using Fusee.Engine.Common; +using OpenTK.Graphics; + +namespace Fusee.Engine.Imp.Graphics.Desktop +{ + /// + /// Contains a handle for any type of attribute buffer stored on GPU memory such as vertices, normals, uvs etc. + /// + public class AttributeImp : IAttribImp + { + internal BufferHandle AttributeBufferObject; + } +} \ No newline at end of file diff --git a/src/Engine/Imp/Graphics/Shared/BufferHandle.cs b/src/Engine/Imp/Graphics/Desktop/BufferHandle.cs similarity index 70% rename from src/Engine/Imp/Graphics/Shared/BufferHandle.cs rename to src/Engine/Imp/Graphics/Desktop/BufferHandle.cs index 9e54e63ed..4bcd3deb0 100644 --- a/src/Engine/Imp/Graphics/Shared/BufferHandle.cs +++ b/src/Engine/Imp/Graphics/Desktop/BufferHandle.cs @@ -1,17 +1,14 @@ using Fusee.Engine.Common; +using OpenTK.Graphics; -#if PLATFORM_DESKTOP namespace Fusee.Engine.Imp.Graphics.Desktop -#elif PLATFORM_ANDROID -namespace Fusee.Engine.Imp.Graphics.Android -#endif { /// /// RenderBuffer for OpenTK, an integer value is used as a handle /// public class RenderBufferHandle : IBufferHandle { - internal int Handle = -1; + internal RenderbufferHandle Handle = new(-1); } /// @@ -19,11 +16,11 @@ public class RenderBufferHandle : IBufferHandle /// class FrameBufferHandle : IBufferHandle { - internal int Handle = -1; + internal FramebufferHandle Handle = new(-1); } class StorageBufferHandle : IBufferHandle { - internal int Handle = -1; + internal BufferHandle Handle = new(-1); } } \ No newline at end of file diff --git a/src/Engine/Imp/Graphics/Desktop/Fusee.Engine.Imp.Graphics.Desktop.csproj b/src/Engine/Imp/Graphics/Desktop/Fusee.Engine.Imp.Graphics.Desktop.csproj index 74bfaf60e..fd8f8f2d6 100644 --- a/src/Engine/Imp/Graphics/Desktop/Fusee.Engine.Imp.Graphics.Desktop.csproj +++ b/src/Engine/Imp/Graphics/Desktop/Fusee.Engine.Imp.Graphics.Desktop.csproj @@ -27,7 +27,10 @@ analyzers - + + + + diff --git a/src/Engine/Imp/Graphics/Desktop/MeshImp.cs b/src/Engine/Imp/Graphics/Desktop/MeshImp.cs new file mode 100644 index 000000000..437c5d9aa --- /dev/null +++ b/src/Engine/Imp/Graphics/Desktop/MeshImp.cs @@ -0,0 +1,220 @@ +using Fusee.Engine.Common; +using OpenTK.Graphics; + +namespace Fusee.Engine.Imp.Graphics.Desktop +{ + /// + /// This is the implementation of the interface. + /// It is used to check the status of the informations of a mesh and flush informations if required. + /// + public class MeshImp : IMeshImp + { + #region Internal Fields + + internal VertexArrayHandle VertexArrayObject; + internal BufferHandle VertexBufferObject; + internal BufferHandle NormalBufferObject; + internal BufferHandle ColorBufferObject; + internal BufferHandle ColorBufferObject1; + internal BufferHandle ColorBufferObject2; + internal BufferHandle UVBufferObject; + internal BufferHandle BoneIndexBufferObject; + internal BufferHandle BoneWeightBufferObject; + internal BufferHandle ElementBufferObject; + internal BufferHandle TangentBufferObject; + internal BufferHandle BitangentBufferObject; + internal int NElements; + + #endregion Internal Fields + + #region Public Fields & Members pairs + + /// + /// Invalidates the VertexArrayObject. + /// + public void InvalidateVertexArrayObject() + { + VertexArrayObject.Handle = 0; + } + + /// + /// Gets a value indicating whether [VertexArrayObject set]. + /// + /// + /// true if [VertexArrayObject set]; otherwise, false. + /// + public bool VertexArrayObjectSet { get { return VertexArrayObject.Handle != 0; } } + + /// + /// Invalidates the vertices. + /// + public void InvalidateVertices() + { + VertexBufferObject.Handle = 0; + } + /// + /// Gets a value indicating whether [vertices set]. + /// + /// + /// true if [vertices set]; otherwise, false. + /// + public bool VerticesSet { get { return VertexBufferObject.Handle != 0; } } + + /// + /// Invalidates the normals. + /// + public void InvalidateNormals() + { + NormalBufferObject.Handle = 0; + } + /// + /// Gets a value indicating whether [normals set]. + /// + /// + /// true if [normals set]; otherwise, false. + /// + public bool NormalsSet { get { return NormalBufferObject.Handle != 0; } } + + /// + /// Invalidates the colors, e.g. reset the ColorBufferObject of this instance by setting it to 0. + /// + public void InvalidateColors() + { + ColorBufferObject.Handle = 0; + } + + /// + /// Invalidates the colors, e.g. reset the ColorBufferObject of this instance by setting it to 0. + /// + public void InvalidateColors1() + { + ColorBufferObject1.Handle = 0; + } + + /// + /// Invalidates the colors, e.g. reset the ColorBufferObject of this instance by setting it to 0. + /// + public void InvalidateColors2() + { + ColorBufferObject2.Handle = 0; + } + + /// + /// Gets a value indicating whether [colors set]. + /// + /// + /// true if [colors set]; otherwise, false. + /// + public bool ColorsSet { get { return ColorBufferObject.Handle != 0; } } + + /// + /// Gets a value indicating whether [colors set]. + /// + /// + /// true if [colors set]; otherwise, false. + /// + public bool ColorsSet1 { get { return ColorBufferObject1.Handle != 0; } } + + /// + /// Gets a value indicating whether [colors set]. + /// + /// + /// true if [colors set]; otherwise, false. + /// + public bool ColorsSet2 { get { return ColorBufferObject2.Handle != 0; } } + + /// + /// Gets a value indicating whether [u vs set]. + /// + /// + /// true if [u vs set]; otherwise, false. + /// + public bool UVsSet { get { return UVBufferObject.Handle != 0; } } + + /// + /// Invalidates the UV's. + /// + public void InvalidateUVs() + { + UVBufferObject.Handle = 0; + } + + /// + /// Gets a value indicating whether [boneindices set]. + /// + /// + /// true if [boneindices set]; otherwise, false. + /// + public bool BoneIndicesSet { get { return BoneIndexBufferObject.Handle != 0; } } + /// + /// Returns wether the tangents have been set. + /// + public bool TangentsSet { get; } + /// + /// Returns wether be bitangents have been set. + /// + public bool BiTangentsSet { get; } + + /// + /// Invalidates the BoneIndices. + /// + public void InvalidateBoneIndices() + { + BoneIndexBufferObject.Handle = 0; + } + + /// + /// Invalidates the Tangents. + /// + public void InvalidateTangents() + { + TangentBufferObject.Handle = 0; + } + + /// + /// Invalidates the BiTangents. + /// + public void InvalidateBiTangents() + { + BitangentBufferObject.Handle = 0; + } + + /// + /// Gets a value indicating whether [boneweights set]. + /// + /// + /// true if [boneweights set]; otherwise, false. + /// + public bool BoneWeightsSet { get { return BoneWeightBufferObject.Handle != 0; } } + + /// + /// Invalidates the BoneWeight's. + /// + public void InvalidateBoneWeights() + { + BoneWeightBufferObject.Handle = 0; + } + /// + /// Invalidates the triangles. + /// + public void InvalidateTriangles() + { + ElementBufferObject.Handle = 0; + NElements = 0; + } + /// + /// Gets a value indicating whether [triangles set]. + /// + /// + /// true if [triangles set]; otherwise, false. + /// + public bool TrianglesSet { get { return ElementBufferObject.Handle != 0; } } + + /// + /// Type of data of this mesh (e.g. Triangles, Points, Lines, etc.) + /// + public PrimitiveType MeshType { get; set; } + + #endregion Public Fields & Members pairs + } +} \ No newline at end of file diff --git a/src/Engine/Imp/Graphics/Desktop/RenderCanvasImp.cs b/src/Engine/Imp/Graphics/Desktop/RenderCanvasImp.cs index 54bace4ce..848f55d4c 100644 --- a/src/Engine/Imp/Graphics/Desktop/RenderCanvasImp.cs +++ b/src/Engine/Imp/Graphics/Desktop/RenderCanvasImp.cs @@ -1,6 +1,7 @@ using Fusee.Base.Core; using Fusee.Engine.Common; using OpenTK.Graphics.OpenGL; +using OpenTK.Mathematics; using OpenTK.Windowing.Common.Input; using OpenTK.Windowing.Desktop; using OpenTK.Windowing.GraphicsLibraryFramework; @@ -212,7 +213,7 @@ public RenderCanvasImp() : this(null, false) public RenderCanvasImp(ImageData icon = null, bool isMultithreaded = false) { //TODO: Select correct monitor - MonitorInfo mon = Monitors.GetMonitors()[0]; + Monitors.TryGetMonitorInfo(0, out var mon); int width = 1280; int height = 720; @@ -308,7 +309,7 @@ private void ResizeWindow() else { //TODO: Select correct monitor - MonitorInfo mon = Monitors.GetMonitors()[0]; + Monitors.TryGetMonitorInfo(0, out var mon); var oneScreenWidth = mon.HorizontalResolution; var oneScreenHeight = mon.VerticalResolution; @@ -350,7 +351,7 @@ public void VideoWall(int monitorsHor = 1, int monitorsVert = 1, bool activate = /// Show the window border or not. public void SetWindowSize(int width, int height, int posx = -1, int posy = -1, bool borderHidden = false) { - MonitorInfo mon = Monitors.GetMonitors()[0]; + Monitors.TryGetMonitorInfo(0, out var mon); BaseWidth = width; BaseHeight = height; @@ -443,8 +444,14 @@ public SixLabors.ImageSharp.Image ShootCurrentFrame(int width, int height) DoResize(width, height); var mem = new byte[width * height * 4]; - GL.PixelStore(PixelStoreParameter.PackRowLength, 1); - GL.ReadPixels(0, 0, Width, Height, PixelFormat.Bgra, PixelType.UnsignedByte, mem); + + GL.PixelStorei(PixelStoreParameter.PackRowLength, 1); + + unsafe + { + using var dataMemHandle = mem.AsMemory().Pin(); + GL.ReadPixels(0, 0, Width, Height, PixelFormat.Bgra, PixelType.UnsignedByte, dataMemHandle.Pointer); + } var img = SixLabors.ImageSharp.Image.LoadPixelData(mem, Width, Height); @@ -589,7 +596,7 @@ internal class RenderCanvasGameWindow : GameWindow /// public bool Blending { - get => GL.IsEnabled(EnableCap.Blend); + get => Convert.ToBoolean(GL.IsEnabled(EnableCap.Blend)); set { if (value) @@ -640,7 +647,7 @@ protected override void OnLoad() throw new InvalidOperationException("You need at least OpenGL 2.0 to run this example. GLSL not supported."); } - GL.ClearColor(25, 25, 112, byte.MaxValue); + GL.ClearColor(new Color4(0.1f, 0.1f, 0.47f, 1)); GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.CullFace); diff --git a/src/Engine/Imp/Graphics/Desktop/RenderContextImp.cs b/src/Engine/Imp/Graphics/Desktop/RenderContextImp.cs index 2ef6ad42f..07e053592 100644 --- a/src/Engine/Imp/Graphics/Desktop/RenderContextImp.cs +++ b/src/Engine/Imp/Graphics/Desktop/RenderContextImp.cs @@ -5,7 +5,9 @@ using Fusee.Engine.Core.ShaderShards; using Fusee.Engine.Imp.Shared; using Fusee.Math.Core; +using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; +using OpenTK.Mathematics; using System; using System.Collections.Generic; using System.Linq; @@ -25,19 +27,19 @@ public class RenderContextImp : IRenderContextImp private int _textureCountPerShader; private readonly Dictionary _shaderParam2TexUnit; - private BlendEquationMode _blendEquationAlpha; - private BlendEquationMode _blendEquationRgb; - private BlendingFactorSrc _blendSrcRgb; - private BlendingFactorDest _blendDstRgb; - private BlendingFactorSrc _blendSrcAlpha; - private BlendingFactorDest _blendDstAlpha; + private BlendEquationModeEXT _blendEquationAlpha; + private BlendEquationModeEXT _blendEquationRgb; + private BlendingFactor _blendSrcRgb; + private BlendingFactor _blendDstRgb; + private BlendingFactor _blendSrcAlpha; + private BlendingFactor _blendDstAlpha; private bool _isCullEnabled; private bool _isPtRenderingEnabled; private bool _isLineSmoothEnabled; #if DEBUG - private static DebugProc _openGlDebugDelegate; + private static GLDebugProc _openGlDebugDelegate; #endif /// @@ -53,50 +55,60 @@ public RenderContextImp(IRenderCanvasImp renderCanvas) GL.Enable(EnableCap.DebugOutput); GL.Enable(EnableCap.DebugOutputSynchronous); - _openGlDebugDelegate = new DebugProc(OpenGLDebugCallback); + _openGlDebugDelegate = new GLDebugProc(OpenGLDebugCallback); GL.DebugMessageCallback(_openGlDebugDelegate, IntPtr.Zero); - GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DontCare, DebugSeverityControl.DebugSeverityNotification, 0, Array.Empty(), false); + + unsafe + { + GL.DebugMessageControl(DebugSource.DontCare, DebugType.DontCare, DebugSeverity.DebugSeverityNotification, 0, (uint*)IntPtr.Zero, Convert.ToByte(false)); + } #endif // Due to the right-handed nature of OpenGL and the left-handed design of FUSEE // the meaning of what's Front and Back of a face simply flips. - // TODO - implement this in render states!!! GL.CullFace(CullFaceMode.Back); //Needed for rendering more than one viewport. GL.Enable(EnableCap.ScissorTest); - GL.GetInteger(GetPName.BlendSrcAlpha, out int blendSrcAlpha); - GL.GetInteger(GetPName.BlendDstAlpha, out int blendDstAlpha); - GL.GetInteger(GetPName.BlendDstRgb, out int blendDstRgb); - GL.GetInteger(GetPName.BlendSrcRgb, out int blendSrcRgb); - GL.GetInteger(GetPName.BlendEquationAlpha, out int blendEqA); - GL.GetInteger(GetPName.BlendEquationRgb, out int blendEqRgb); - - _blendDstRgb = (BlendingFactorDest)blendDstRgb; - _blendSrcRgb = (BlendingFactorSrc)blendSrcRgb; - _blendSrcAlpha = (BlendingFactorSrc)blendSrcAlpha; - _blendDstAlpha = (BlendingFactorDest)blendDstAlpha; - _blendEquationAlpha = (BlendEquationMode)blendEqA; - _blendEquationRgb = (BlendEquationMode)blendEqRgb; + int blendSrcAlpha = 0; + int blendDstAlpha = 0; + int blendDstRgb = 0; + int blendSrcRgb = 0; + int blendEqA = 0; + int blendEqRgb = 0; + + GL.GetInteger(GetPName.BlendSrcAlpha, ref blendSrcAlpha); + GL.GetInteger(GetPName.BlendDstAlpha, ref blendDstAlpha); + GL.GetInteger(GetPName.BlendDstRgb, ref blendDstRgb); + GL.GetInteger(GetPName.BlendSrcRgb, ref blendSrcRgb); + GL.GetInteger(GetPName.BlendEquationAlpha, ref blendEqA); + GL.GetInteger(GetPName.BlendEquationRgb, ref blendEqRgb); + + _blendDstRgb = (BlendingFactor)blendDstRgb; + _blendSrcRgb = (BlendingFactor)blendSrcRgb; + _blendSrcAlpha = (BlendingFactor)blendSrcAlpha; + _blendDstAlpha = (BlendingFactor)blendDstAlpha; + _blendEquationAlpha = (BlendEquationModeEXT)blendEqA; + _blendEquationRgb = (BlendEquationModeEXT)blendEqRgb; Diagnostics.Debug(GL.GetString(StringName.Vendor) + " - " + GL.GetString(StringName.Renderer) + " - " + GL.GetString(StringName.Version)); #if DEBUG - var numExtensions = GL.GetInteger(GetPName.NumExtensions); - var extensions = new string[numExtensions]; + int numExtensions = 0; + GL.GetInteger(GetPName.NumExtensions, ref numExtensions); - for (int i = 0; i < numExtensions; i++) + var extensions = new string[numExtensions]; + for (uint i = 0; i < numExtensions; i++) { - extensions[i] = GL.GetString(StringNameIndexed.Extensions, i); + extensions[i] = GL.GetStringi(StringName.Extensions, i); } - Diagnostics.Verbose(string.Join(';', extensions)); #endif } #if DEBUG - private static void OpenGLDebugCallback(DebugSource source, DebugType type, int id, DebugSeverity severity, int length, IntPtr message, IntPtr userParam) + private static void OpenGLDebugCallback(DebugSource source, DebugType type, uint id, DebugSeverity severity, int length, IntPtr message, IntPtr userParam) { Diagnostics.Debug($"{System.Runtime.InteropServices.Marshal.PtrToStringAnsi(message, length)}\n\tid:{id} severity:{severity} type:{type} source:{source}\n"); } @@ -178,21 +190,21 @@ private OpenTK.Graphics.OpenGL.TextureWrapMode GetWrapMode(Common.TextureWrapMod }; } - private SizedInternalFormat GetSizedInteralFormat(ImagePixelFormat format) + private InternalFormat GetInteralFormat(ImagePixelFormat format) { return format.ColorFormat switch { - ColorFormat.RGBA => SizedInternalFormat.Rgba8, - ColorFormat.fRGBA16 => SizedInternalFormat.Rgba16f, - ColorFormat.fRGBA32 => SizedInternalFormat.Rgba32f, - ColorFormat.iRGBA32 => SizedInternalFormat.Rgba32i, + ColorFormat.RGBA => InternalFormat.Rgba, + ColorFormat.fRGBA16 => InternalFormat.Rgba16f, + ColorFormat.fRGBA32 => InternalFormat.Rgba32f, + ColorFormat.iRGBA32 => InternalFormat.Rgba32i, _ => throw new ArgumentOutOfRangeException("SizedInternalFormat not supported. Try to use a format with r,g,b and a components."), }; } private TexturePixelInfo GetTexturePixelInfo(ImagePixelFormat pixelFormat) { - PixelInternalFormat internalFormat; + InternalFormat internalFormat; PixelFormat format; PixelType pxType; @@ -204,13 +216,13 @@ private TexturePixelInfo GetTexturePixelInfo(ImagePixelFormat pixelFormat) switch (pixelFormat.ColorFormat) { case ColorFormat.RGBA: - internalFormat = PixelInternalFormat.Rgba; + internalFormat = InternalFormat.Rgba; format = PixelFormat.Rgba; pxType = PixelType.UnsignedByte; break; case ColorFormat.RGB: - internalFormat = PixelInternalFormat.Rgb; + internalFormat = InternalFormat.Rgb; format = PixelFormat.Rgb; pxType = PixelType.UnsignedByte; rowAlignment = 1; @@ -218,57 +230,57 @@ private TexturePixelInfo GetTexturePixelInfo(ImagePixelFormat pixelFormat) // TODO: Handle Alpha-only / Intensity-only and AlphaIntensity correctly. case ColorFormat.Intensity: - internalFormat = PixelInternalFormat.R8; + internalFormat = InternalFormat.R8; format = PixelFormat.Red; pxType = PixelType.UnsignedByte; rowAlignment = 1; break; case ColorFormat.Depth24: - internalFormat = PixelInternalFormat.DepthComponent24; + internalFormat = InternalFormat.DepthComponent24; format = PixelFormat.DepthComponent; pxType = PixelType.Float; break; case ColorFormat.Depth16: - internalFormat = PixelInternalFormat.DepthComponent16; + internalFormat = InternalFormat.DepthComponent16; format = PixelFormat.DepthComponent; pxType = PixelType.Float; break; case ColorFormat.uiRgb8: - internalFormat = PixelInternalFormat.Rgba8ui; + internalFormat = InternalFormat.Rgba8ui; format = PixelFormat.RgbaInteger; pxType = PixelType.UnsignedByte; rowAlignment = 1; break; case ColorFormat.fRGB32: - internalFormat = PixelInternalFormat.Rgb32f; + internalFormat = InternalFormat.Rgb32f; format = PixelFormat.Rgb; pxType = PixelType.Float; break; case ColorFormat.fRGB16: - internalFormat = PixelInternalFormat.Rgb16f; + internalFormat = InternalFormat.Rgb16f; format = PixelFormat.Rgb; pxType = PixelType.Float; break; case ColorFormat.fRGBA16: - internalFormat = PixelInternalFormat.Rgba16f; + internalFormat = InternalFormat.Rgba16f; format = PixelFormat.Rgba; pxType = PixelType.Float; break; case ColorFormat.fRGBA32: - internalFormat = PixelInternalFormat.Rgba32f; + internalFormat = InternalFormat.Rgba32f; format = PixelFormat.Rgba; pxType = PixelType.Float; break; case ColorFormat.iRGBA32: - internalFormat = PixelInternalFormat.Rgba32i; + internalFormat = InternalFormat.Rgba32i; format = PixelFormat.RgbaInteger; pxType = PixelType.Int; break; @@ -309,8 +321,8 @@ public ITextureHandle CreateTexture(IWritableTexture img) /// An ITextureHandle that can be used for texturing in the shader. In this implementation, the handle is an integer-value which is necessary for OpenTK. public ITextureHandle CreateTexture(IWritableArrayTexture img) { - int id = GL.GenTexture(); - GL.BindTexture(TextureTarget.Texture2DArray, id); + OpenTK.Graphics.TextureHandle handle = GL.GenTexture(); + GL.BindTexture(TextureTarget.Texture2dArray, handle); var glMinMagFilter = GetMinMagFilter(img.FilterMode); var minFilter = glMinMagFilter.Item1; @@ -318,19 +330,19 @@ public ITextureHandle CreateTexture(IWritableArrayTexture img) var glWrapMode = GetWrapMode(img.WrapMode); var pxInfo = GetTexturePixelInfo(img.PixelFormat); - GL.TexImage3D(TextureTarget.Texture2DArray, 0, pxInfo.InternalFormat, img.Width, img.Height, img.Layers, 0, pxInfo.Format, pxInfo.PxType, IntPtr.Zero); + GL.TexImage3D(TextureTarget.Texture2dArray, 0, (int)pxInfo.InternalFormat, img.Width, img.Height, img.Layers, 0, pxInfo.Format, pxInfo.PxType, IntPtr.Zero); if (img.DoGenerateMipMaps) - GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); + GL.GenerateMipmap(TextureTarget.Texture2d); - GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureCompareMode, (int)GetTexComapreMode(img.CompareMode)); - GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureCompareFunc, (int)GetDepthCompareFunc(img.CompareFunc)); - GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMinFilter, (int)minFilter); - GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMagFilter, (int)magFilter); - GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapS, (int)glWrapMode); - GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapT, (int)glWrapMode); + GL.TexParameteri(TextureTarget.Texture2dArray, TextureParameterName.TextureCompareMode, (int)GetTexComapreMode(img.CompareMode)); + GL.TexParameteri(TextureTarget.Texture2dArray, TextureParameterName.TextureCompareFunc, (int)GetDepthCompareFunc(img.CompareFunc)); + GL.TexParameteri(TextureTarget.Texture2dArray, TextureParameterName.TextureMinFilter, (int)minFilter); + GL.TexParameteri(TextureTarget.Texture2dArray, TextureParameterName.TextureMagFilter, (int)magFilter); + GL.TexParameteri(TextureTarget.Texture2dArray, TextureParameterName.TextureWrapS, (int)glWrapMode); + GL.TexParameteri(TextureTarget.Texture2dArray, TextureParameterName.TextureWrapT, (int)glWrapMode); - ITextureHandle texID = new TextureHandle { TexHandle = id }; + ITextureHandle texID = new TextureHandle { TexHandle = handle }; return texID; } @@ -342,8 +354,8 @@ public ITextureHandle CreateTexture(IWritableArrayTexture img) /// An ITextureHandle that can be used for texturing in the shader. In this implementation, the handle is an integer-value which is necessary for OpenTK. public ITextureHandle CreateTexture(IWritableCubeMap img) { - int id = GL.GenTexture(); - GL.BindTexture(TextureTarget.TextureCubeMap, id); + OpenTK.Graphics.TextureHandle handle = GL.GenTexture(); + GL.BindTexture(TextureTarget.TextureCubeMap, handle); var glMinMagFilter = GetMinMagFilter(img.FilterMode); var minFilter = glMinMagFilter.Item1; @@ -352,18 +364,18 @@ public ITextureHandle CreateTexture(IWritableCubeMap img) var glWrapMode = GetWrapMode(img.WrapMode); var pxInfo = GetTexturePixelInfo(img.PixelFormat); - for (int i = 0; i < 6; i++) - GL.TexImage2D(TextureTarget.TextureCubeMapPositiveX + i, 0, pxInfo.InternalFormat, img.Width, img.Height, 0, pxInfo.Format, pxInfo.PxType, IntPtr.Zero); + for (uint i = 0; i < 6; i++) + GL.TexImage2D(TextureTarget.TextureCubeMapPositiveX + i, 0, (int)pxInfo.InternalFormat, img.Width, img.Height, 0, pxInfo.Format, pxInfo.PxType, IntPtr.Zero); - GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureCompareMode, (int)GetTexComapreMode(img.CompareMode)); - GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureCompareFunc, (int)GetDepthCompareFunc(img.CompareFunc)); - GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter, (int)magFilter); - GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter, (int)minFilter); - GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS, (int)glWrapMode); - GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (int)glWrapMode); - GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapR, (int)glWrapMode); + GL.TexParameteri(TextureTarget.TextureCubeMap, TextureParameterName.TextureCompareMode, (int)GetTexComapreMode(img.CompareMode)); + GL.TexParameteri(TextureTarget.TextureCubeMap, TextureParameterName.TextureCompareFunc, (int)GetDepthCompareFunc(img.CompareFunc)); + GL.TexParameteri(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter, (int)magFilter); + GL.TexParameteri(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter, (int)minFilter); + GL.TexParameteri(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS, (int)glWrapMode); + GL.TexParameteri(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (int)glWrapMode); + GL.TexParameteri(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapR, (int)glWrapMode); - ITextureHandle texID = new TextureHandle { TexHandle = id }; + ITextureHandle texID = new TextureHandle { TexHandle = handle }; return texID; } @@ -375,8 +387,8 @@ public ITextureHandle CreateTexture(IWritableCubeMap img) /// An ITextureHandle that can be used for texturing in the shader. In this implementation, the handle is an integer-value which is necessary for OpenTK. public ITextureHandle CreateTexture(ITexture img) { - int id = GL.GenTexture(); - GL.BindTexture(TextureTarget.Texture2D, id); + OpenTK.Graphics.TextureHandle handle = GL.GenTexture(); + GL.BindTexture(TextureTarget.Texture2d, handle); var glMinMagFilter = GetMinMagFilter(img.FilterMode); var minFilter = glMinMagFilter.Item1; @@ -385,20 +397,22 @@ public ITextureHandle CreateTexture(ITexture img) var glWrapMode = GetWrapMode(img.WrapMode); var pxInfo = GetTexturePixelInfo(img.ImageData.PixelFormat); - - GL.PixelStore(PixelStoreParameter.UnpackAlignment, pxInfo.RowAlignment); - GL.TexImage2D(TextureTarget.Texture2D, 0, pxInfo.InternalFormat, img.ImageData.Width, img.ImageData.Height, 0, pxInfo.Format, pxInfo.PxType, img.ImageData.PixelData); + unsafe + { + using var pxDataMem = img.ImageData.PixelData.AsMemory().Pin(); + GL.TexImage2D(TextureTarget.Texture2d, 0, (int)pxInfo.InternalFormat, img.ImageData.Width, img.ImageData.Height, 0, pxInfo.Format, pxInfo.PxType, pxDataMem.Pointer); + } if (img.DoGenerateMipMaps) - GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); + GL.GenerateMipmap(TextureTarget.Texture2d); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)minFilter); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)magFilter); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)glWrapMode); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)glWrapMode); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapR, (int)glWrapMode); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMinFilter, (int)minFilter); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMagFilter, (int)magFilter); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureWrapS, (int)glWrapMode); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureWrapT, (int)glWrapMode); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureWrapR, (int)glWrapMode); - ITextureHandle texID = new TextureHandle { TexHandle = id }; + ITextureHandle texID = new TextureHandle { TexHandle = handle }; return texID; } @@ -410,8 +424,8 @@ public ITextureHandle CreateTexture(ITexture img) /// An ITextureHandle that can be used for texturing in the shader. In this implementation, the handle is an integer-value which is necessary for OpenTK. public ITextureHandle CreateTexture(WritableTexture tex) { - int id = GL.GenTexture(); - GL.BindTexture(TextureTarget.Texture2D, id); + OpenTK.Graphics.TextureHandle handle = GL.GenTexture(); + GL.BindTexture(TextureTarget.Texture2d, handle); var glMinMagFilter = GetMinMagFilter(tex.FilterMode); var minFilter = glMinMagFilter.Item1; @@ -419,19 +433,19 @@ public ITextureHandle CreateTexture(WritableTexture tex) var glWrapMode = GetWrapMode(tex.WrapMode); var pxInfo = GetTexturePixelInfo(tex.PixelFormat); - GL.TexImage2D(TextureTarget.Texture2D, 0, pxInfo.InternalFormat, tex.Width, tex.Height, 0, pxInfo.Format, pxInfo.PxType, IntPtr.Zero); + GL.TexImage2D(TextureTarget.Texture2d, 0, (int)pxInfo.InternalFormat, tex.Width, tex.Height, 0, pxInfo.Format, pxInfo.PxType, IntPtr.Zero); if (tex.DoGenerateMipMaps) - GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); + GL.GenerateMipmap(TextureTarget.Texture2d); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureCompareMode, (int)GetTexComapreMode(tex.CompareMode)); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureCompareFunc, (int)GetDepthCompareFunc(tex.CompareFunc)); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)minFilter); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)magFilter); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)glWrapMode); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)glWrapMode); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureCompareMode, (int)GetTexComapreMode(tex.CompareMode)); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureCompareFunc, (int)GetDepthCompareFunc(tex.CompareFunc)); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMinFilter, (int)minFilter); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMagFilter, (int)magFilter); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureWrapS, (int)glWrapMode); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureWrapT, (int)glWrapMode); - ITextureHandle texID = new TextureHandle { TexHandle = id }; + ITextureHandle texID = new TextureHandle { TexHandle = handle }; return texID; @@ -446,24 +460,24 @@ public ITextureHandle CreateTexture(WritableMultisampleTexture tex) { GL.Enable(EnableCap.Multisample); - int id = GL.GenTexture(); - GL.BindTexture(TextureTarget.Texture2DMultisample, id); + OpenTK.Graphics.TextureHandle handle = GL.GenTexture(); + GL.BindTexture(TextureTarget.Texture2dMultisample, handle); var glMinMagFilter = GetMinMagFilter(tex.FilterMode); var minFilter = glMinMagFilter.Item1; var magFilter = glMinMagFilter.Item2; var glWrapMode = GetWrapMode(tex.WrapMode); - GL.TexImage2DMultisample(TextureTargetMultisample.Texture2DMultisample, tex.MultisampleFactor, PixelInternalFormat.Rgba, tex.Width, tex.Height, true); + GL.TexImage2DMultisample(TextureTarget.Texture2dMultisample, tex.MultisampleFactor, InternalFormat.Rgba, tex.Width, tex.Height, true); - GL.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureCompareMode, (int)GetTexComapreMode(tex.CompareMode)); - GL.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureCompareFunc, (int)GetDepthCompareFunc(tex.CompareFunc)); - GL.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureMinFilter, (int)minFilter); - GL.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureMagFilter, (int)magFilter); - GL.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureWrapS, (int)glWrapMode); - GL.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureWrapT, (int)glWrapMode); + GL.TexParameteri(TextureTarget.Texture2dMultisample, TextureParameterName.TextureCompareMode, (int)GetTexComapreMode(tex.CompareMode)); + GL.TexParameteri(TextureTarget.Texture2dMultisample, TextureParameterName.TextureCompareFunc, (int)GetDepthCompareFunc(tex.CompareFunc)); + GL.TexParameteri(TextureTarget.Texture2dMultisample, TextureParameterName.TextureMinFilter, (int)minFilter); + GL.TexParameteri(TextureTarget.Texture2dMultisample, TextureParameterName.TextureMagFilter, (int)magFilter); + GL.TexParameteri(TextureTarget.Texture2dMultisample, TextureParameterName.TextureWrapS, (int)glWrapMode); + GL.TexParameteri(TextureTarget.Texture2dMultisample, TextureParameterName.TextureWrapT, (int)glWrapMode); - ITextureHandle texID = new TextureHandle { TexHandle = id }; + ITextureHandle texID = new TextureHandle { TexHandle = handle }; return texID; } @@ -499,14 +513,16 @@ public void UpdateTextureRegion(ITextureHandle tex, ITexture img, int startX, in } while (scanlines.MoveNext()); - GL.PixelStore(PixelStoreParameter.PackAlignment, pxInfo.RowAlignment); - GL.BindTexture(TextureTarget.Texture2D, ((TextureHandle)tex).TexHandle); - GL.TexSubImage2D(TextureTarget.Texture2D, 0, startX, startY, width, height, format, PixelType.UnsignedByte, bytes); + GL.BindTexture(TextureTarget.Texture2d, ((TextureHandle)tex).TexHandle); - //GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); + unsafe + { + using var byteMem = bytes.AsMemory().Pin(); + GL.TexSubImage2D(TextureTarget.Texture2d, 0, startX, startY, width, height, format, PixelType.UnsignedByte, byteMem.Pointer); + } - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); } /// @@ -516,10 +532,10 @@ public void UpdateTextureRegion(ITextureHandle tex, ITexture img, int startX, in /// The new filter mode. public void SetTextureFilterMode(ITextureHandle tex, TextureFilterMode filterMode) { - GL.BindTexture(TextureTarget.Texture2D, ((TextureHandle)tex).TexHandle); + GL.BindTexture(TextureTarget.Texture2d, ((TextureHandle)tex).TexHandle); var glMinMagFilter = GetMinMagFilter(filterMode); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)glMinMagFilter.Item1); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)glMinMagFilter.Item2); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMinFilter, (int)glMinMagFilter.Item1); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMagFilter, (int)glMinMagFilter.Item2); } /// @@ -529,11 +545,11 @@ public void SetTextureFilterMode(ITextureHandle tex, TextureFilterMode filterMod ///The new wrap mode. public void SetTextureWrapMode(ITextureHandle tex, Common.TextureWrapMode wrapMode) { - GL.BindTexture(TextureTarget.Texture2D, ((TextureHandle)tex).TexHandle); + GL.BindTexture(TextureTarget.Texture2d, ((TextureHandle)tex).TexHandle); var glWrapMode = GetWrapMode(wrapMode); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)glWrapMode); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)glWrapMode); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapR, (int)glWrapMode); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureWrapS, (int)glWrapMode); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureWrapT, (int)glWrapMode); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureWrapR, (int)glWrapMode); } /// @@ -546,12 +562,12 @@ public void DeleteFrameBuffer(IBufferHandle bh) } /// - /// Free all allocated gpu memory that belong to a render-buffer object. + /// Free all allocated gpu memory that belong to a render buffer object. /// /// The platform dependent abstraction of the gpu buffer handle. public void DeleteRenderBuffer(IBufferHandle bh) { - GL.DeleteFramebuffer(((RenderBufferHandle)bh).Handle); + GL.DeleteRenderbuffer(((RenderBufferHandle)bh).Handle); } /// @@ -562,17 +578,17 @@ public void RemoveTextureHandle(ITextureHandle textureHandle) { TextureHandle texHandle = (TextureHandle)textureHandle; - if (texHandle.FrameBufferHandle != -1) + if (texHandle.FrameBufferHandle.Handle != -1) { GL.DeleteFramebuffer(texHandle.FrameBufferHandle); } - if (texHandle.DepthRenderBufferHandle != -1) + if (texHandle.DepthRenderBufferHandle.Handle != -1) { GL.DeleteRenderbuffer(texHandle.DepthRenderBufferHandle); } - if (texHandle.TexHandle != -1) + if (texHandle.TexHandle.Handle != -1) { GL.DeleteTexture(texHandle.TexHandle); _textureCountPerShader--; @@ -593,7 +609,7 @@ public IShaderHandle CreateShaderProgramCompute(string cs) int statusCode = -1; // Compile compute shader - int computeObject = -1; + ShaderHandle computeObject = new(-1); if (!string.IsNullOrEmpty(cs)) { computeObject = GL.CreateShader(ShaderType.ComputeShader); @@ -601,13 +617,13 @@ public IShaderHandle CreateShaderProgramCompute(string cs) GL.ShaderSource(computeObject, cs); GL.CompileShader(computeObject); GL.GetShaderInfoLog(computeObject, out info); - GL.GetShader(computeObject, ShaderParameter.CompileStatus, out statusCode); + GL.GetShaderi(computeObject, ShaderParameterName.CompileStatus, ref statusCode); } if (statusCode != 1) throw new ApplicationException(info); - int program = GL.CreateProgram(); + ProgramHandle program = GL.CreateProgram(); GL.AttachShader(program, computeObject); GL.LinkProgram(program); //Must be called AFTER BindAttribLocation @@ -629,20 +645,21 @@ public IShaderHandle CreateShaderProgramCompute(string cs) /// public IShaderHandle CreateShaderProgram(string vs, string ps, string gs = null) { - int vertexObject = GL.CreateShader(ShaderType.VertexShader); - int fragmentObject = GL.CreateShader(ShaderType.FragmentShader); + ShaderHandle vertexObject = GL.CreateShader(ShaderType.VertexShader); + ShaderHandle fragmentObject = GL.CreateShader(ShaderType.FragmentShader); + int statusCode = -1; // Compile vertex shader GL.ShaderSource(vertexObject, vs); GL.CompileShader(vertexObject); GL.GetShaderInfoLog(vertexObject, out string info); - GL.GetShader(vertexObject, ShaderParameter.CompileStatus, out int statusCode); + GL.GetShaderi(vertexObject, ShaderParameterName.CompileStatus, ref statusCode); if (statusCode != 1) throw new ApplicationException(info); // Compile geometry shader - int geometryObject = -1; + ShaderHandle geometryObject = new(-1); if (!string.IsNullOrEmpty(gs)) { geometryObject = GL.CreateShader(ShaderType.GeometryShader); @@ -650,7 +667,7 @@ public IShaderHandle CreateShaderProgram(string vs, string ps, string gs = null) GL.ShaderSource(geometryObject, gs); GL.CompileShader(geometryObject); GL.GetShaderInfoLog(geometryObject, out info); - GL.GetShader(geometryObject, ShaderParameter.CompileStatus, out statusCode); + GL.GetShaderi(geometryObject, ShaderParameterName.CompileStatus, ref statusCode); } if (statusCode != 1) @@ -660,12 +677,12 @@ public IShaderHandle CreateShaderProgram(string vs, string ps, string gs = null) GL.ShaderSource(fragmentObject, ps); GL.CompileShader(fragmentObject); GL.GetShaderInfoLog(fragmentObject, out info); - GL.GetShader(fragmentObject, ShaderParameter.CompileStatus, out statusCode); + GL.GetShaderi(fragmentObject, ShaderParameterName.CompileStatus, ref statusCode); if (statusCode != 1) throw new ApplicationException(info); - int program = GL.CreateProgram(); + ProgramHandle program = GL.CreateProgram(); GL.AttachShader(program, fragmentObject); if (!string.IsNullOrEmpty(gs)) @@ -703,13 +720,11 @@ public IShaderHandle CreateShaderProgram(string vs, string ps, string gs = null) /// public void RemoveShader(IShaderHandle sp) { - var program = ((ShaderHandleImp)sp).Handle; - // wait for all threads to be finished GL.Finish(); GL.Flush(); - GL.DeleteProgram(program); + GL.DeleteProgram(((ShaderHandleImp)sp).Handle); } @@ -748,7 +763,8 @@ public IShaderParam GetShaderUniformParam(IShaderHandle shaderProgram, string pa /// A float number (default is 0). public float GetParamValue(IShaderHandle program, IShaderParam param) { - GL.GetUniform(((ShaderHandleImp)program).Handle, ((ShaderParam)param).handle, out float f); + float f = 0; + GL.GetUniformf(((ShaderHandleImp)program).Handle, ((ShaderParam)param).handle, ref f); return f; } @@ -760,17 +776,21 @@ public IList GetShaderStorageBufferList(IShaderHandle shaderPro { var paramList = new List(); var sProg = (ShaderHandleImp)shaderProgram; - GL.GetProgramInterface(sProg.Handle, ProgramInterface.ShaderStorageBlock, ProgramInterfaceParameter.MaxNameLength, out int ssboMaxLen); - GL.GetProgramInterface(sProg.Handle, ProgramInterface.ShaderStorageBlock, ProgramInterfaceParameter.ActiveResources, out int nParams); + int ssboMaxLen = 0; + int nParams = 0; - for (var i = 0; i < nParams; i++) + GL.GetProgramInterfacei(sProg.Handle, ProgramInterface.ShaderStorageBlock, ProgramInterfacePName.MaxNameLength, ref ssboMaxLen); + GL.GetProgramInterfacei(sProg.Handle, ProgramInterface.ShaderStorageBlock, ProgramInterfacePName.ActiveResources, ref nParams); + + for (uint i = 0; i < nParams; i++) { var paramInfo = new ShaderParamInfo(); - GL.GetProgramResourceName(sProg.Handle, ProgramInterface.ShaderStorageBlock, i, ssboMaxLen, out _, out string name); + int length = 0; + GL.GetProgramResourceName(sProg.Handle, ProgramInterface.ShaderStorageBlock, i, ssboMaxLen, ref length, out string name); paramInfo.Name = name; - int h = GL.GetProgramResourceIndex(sProg.Handle, ProgramInterface.ShaderStorageBlock, name); - paramInfo.Handle = (h == -1) ? null : new ShaderParam { handle = h }; + uint h = GL.GetProgramResourceIndex(sProg.Handle, ProgramInterface.ShaderStorageBlock, name); + paramInfo.Handle = (h == default(uint)) ? null : new ShaderParam { handle = (int)h }; paramList.Add(paramInfo); } @@ -788,31 +808,39 @@ public IList GetActiveUniformsList(IShaderHandle shaderProgram) var sProg = (ShaderHandleImp)shaderProgram; var paramList = new List(); - GL.GetProgram(sProg.Handle, GetProgramParameterName.ActiveUniforms, out int nParams); + int nParams = 0; + GL.GetProgrami(sProg.Handle, ProgramPropertyARB.ActiveUniforms, ref nParams); for (var i = 0; i < nParams; i++) { var paramInfo = new ShaderParamInfo(); - paramInfo.Name = GL.GetActiveUniform(sProg.Handle, i, out paramInfo.Size, out ActiveUniformType uType); - paramInfo.Handle = GetShaderUniformParam(sProg, paramInfo.Name); + UniformType uType = UniformType.Bool; + + int length = 0; + int size = 0; + //TODO: (int)ProgramInterfacePName.MaxNameLength may not be the correct value here + GL.GetActiveUniform(sProg.Handle, (uint)i, (int)ProgramInterfacePName.MaxNameLength, ref length, ref size, ref uType, out var name); - //Diagnostics.Log($"Active Uniforms: {paramInfo.Name}"); + paramInfo.Name = name; + paramInfo.Handle = GetShaderUniformParam(sProg, paramInfo.Name); + paramInfo.Size = size; - paramInfo.Type = uType switch + //TODO: remove cast to uint when UniformType.Image2d = 36941 is available + paramInfo.Type = (uint)uType switch { - ActiveUniformType.Int => typeof(int), - ActiveUniformType.Bool => typeof(bool), - ActiveUniformType.Float => typeof(float), - ActiveUniformType.Double => typeof(double), - ActiveUniformType.IntVec2 => typeof(float2), - ActiveUniformType.FloatVec2 => typeof(float2), - ActiveUniformType.FloatVec3 => typeof(float3), - ActiveUniformType.FloatVec4 => typeof(float4), - ActiveUniformType.FloatMat4 => typeof(float4x4), - ActiveUniformType.Sampler2D or ActiveUniformType.UnsignedIntSampler2D or ActiveUniformType.IntSampler2D or ActiveUniformType.Sampler2DShadow or ActiveUniformType.Image2D => typeof(ITextureBase), - ActiveUniformType.SamplerCube or ActiveUniformType.SamplerCubeShadow => typeof(IWritableCubeMap), - ActiveUniformType.Sampler2DArray or ActiveUniformType.Sampler2DArrayShadow => typeof(IWritableArrayTexture), - _ => throw new ArgumentOutOfRangeException($"ActiveUniformType {uType} unknown."), + (uint)UniformType.Int => typeof(int), + (uint)UniformType.Bool => typeof(bool), + (uint)UniformType.Float => typeof(float), + (uint)UniformType.Double => typeof(double), + (uint)UniformType.IntVec2 => typeof(float2), + (uint)UniformType.FloatVec2 => typeof(float2), + (uint)UniformType.FloatVec3 => typeof(float3), + (uint)UniformType.FloatVec4 => typeof(float4), + (uint)UniformType.FloatMat4 => typeof(float4x4), + (uint)UniformType.Sampler2d or (uint)UniformType.UnsignedIntSampler2d or (uint)UniformType.IntSampler2d or (uint)UniformType.Sampler2dShadow /*or UniformType.Image2d*/or 36941 => typeof(ITextureBase), + (uint)UniformType.SamplerCube or (uint)UniformType.SamplerCubeShadow => typeof(IWritableCubeMap), + (uint)UniformType.Sampler2dArray or (uint)UniformType.Sampler2dArrayShadow => typeof(IWritableArrayTexture), + _ => throw new ArgumentOutOfRangeException($"UniformType {uType} unknown."), }; paramList.Add(paramInfo); } @@ -835,7 +863,7 @@ public void SetLineWidth(float width) /// The value. public void SetShaderParam(IShaderParam param, float val) { - GL.Uniform1(((ShaderParam)param).handle, val); + GL.Uniform1f((int)((ShaderParam)param).handle, val); } /// @@ -845,7 +873,7 @@ public void SetShaderParam(IShaderParam param, float val) /// The value. public void SetShaderParam(IShaderParam param, double val) { - GL.Uniform1(((ShaderParam)param).handle, val); + GL.Uniform1d((int)((ShaderParam)param).handle, val); } /// @@ -855,7 +883,7 @@ public void SetShaderParam(IShaderParam param, double val) /// The value. public void SetShaderParam(IShaderParam param, float2 val) { - GL.Uniform2(((ShaderParam)param).handle, val.x, val.y); + GL.Uniform2f(((ShaderParam)param).handle, val.x, val.y); } /// @@ -865,8 +893,10 @@ public void SetShaderParam(IShaderParam param, float2 val) /// The value. public unsafe void SetShaderParam(IShaderParam param, float2[] val) { - fixed (float2* pFlt = &val[0]) - GL.Uniform2(((ShaderParam)param).handle, val.Length, (float*)pFlt); + using var float2Mem = val.AsMemory().Pin(); + var vec2Span = new Span(float2Mem.Pointer, val.Length); + + GL.Uniform2f(((ShaderParam)param).handle, val.Length, vec2Span); } /// @@ -876,18 +906,19 @@ public unsafe void SetShaderParam(IShaderParam param, float2[] val) /// The value. public void SetShaderParam(IShaderParam param, float3 val) { - GL.Uniform3(((ShaderParam)param).handle, val.x, val.y, val.z); + GL.Uniform3f(((ShaderParam)param).handle, val.x, val.y, val.z); } /// - /// Sets a array shader parameter. + /// Sets a array shader parameter. /// /// The parameter. /// The value. public unsafe void SetShaderParam(IShaderParam param, float3[] val) { - fixed (float3* pFlt = &val[0]) - GL.Uniform3(((ShaderParam)param).handle, val.Length, (float*)pFlt); + using var float3Mem = val.AsMemory().Pin(); + var vec3Span = new Span(float3Mem.Pointer, val.Length); + GL.Uniform3f(((ShaderParam)param).handle, val.Length, vec3Span); } /// @@ -897,7 +928,7 @@ public unsafe void SetShaderParam(IShaderParam param, float3[] val) /// The value. public void SetShaderParam(IShaderParam param, float4 val) { - GL.Uniform4(((ShaderParam)param).handle, val.x, val.y, val.z, val.w); + GL.Uniform4f(((ShaderParam)param).handle, val.x, val.y, val.z, val.w); } /// @@ -905,17 +936,12 @@ public void SetShaderParam(IShaderParam param, float4 val) /// /// The parameter. /// The value. - public void SetShaderParam(IShaderParam param, float4x4 val) + public unsafe void SetShaderParam(IShaderParam param, float4x4 val) { - unsafe - { - var mF = (float*)(&val); - // Row order notation - // GL.UniformMatrix4(((ShaderParam) param).handle, 1, false, mF); + using var float4x4Mem = val.ToArray().AsMemory().Pin(); + var mat4Span = new Span(float4x4Mem.Pointer, 16); - // Column order notation - GL.UniformMatrix4(((ShaderParam)param).handle, 1, true, mF); - } + GL.UniformMatrix4f(((ShaderParam)param).handle, 1, true, mat4Span); } /// @@ -925,8 +951,9 @@ public void SetShaderParam(IShaderParam param, float4x4 val) /// The value. public unsafe void SetShaderParam(IShaderParam param, float4[] val) { - fixed (float4* pFlt = &val[0]) - GL.Uniform4(((ShaderParam)param).handle, val.Length, (float*)pFlt); + using var float4Mem = val.AsMemory().Pin(); + var vec4Span = new Span(float4Mem.Pointer, val.Length); + GL.Uniform4f(((ShaderParam)param).handle, val.Length, vec4Span); } /// @@ -936,18 +963,10 @@ public unsafe void SetShaderParam(IShaderParam param, float4[] val) /// The value. public unsafe void SetShaderParam(IShaderParam param, float4x4[] val) { - var tmpArray = new float4[val.Length * 4]; + using var mem = val.AsMemory().Pin(); + var matArraySpan = new Span(mem.Pointer, val.Length); - for (var i = 0; i < val.Length; i++) - { - tmpArray[i * 4] = val[i].Column1; - tmpArray[i * 4 + 1] = val[i].Column2; - tmpArray[i * 4 + 2] = val[i].Column3; - tmpArray[i * 4 + 3] = val[i].Column4; - } - - fixed (float4* pMtx = &tmpArray[0]) - GL.UniformMatrix4(((ShaderParam)param).handle, val.Length, false, (float*)pMtx); + GL.UniformMatrix4f(((ShaderParam)param).handle, val.Length, true, matArraySpan); } /// @@ -957,10 +976,10 @@ public unsafe void SetShaderParam(IShaderParam param, float4x4[] val) /// The value. public void SetShaderParam(IShaderParam param, int val) { - GL.Uniform1(((ShaderParam)param).handle, val); + GL.Uniform1i(((ShaderParam)param).handle, val); } - private void BindImage(TextureType texTarget, ITextureHandle texId, int texUint, TextureAccess access, SizedInternalFormat format) + private void BindImage(TextureType texTarget, ITextureHandle texId, uint texUint, BufferAccessARB access, InternalFormat format) { switch (texTarget) { @@ -977,22 +996,22 @@ private void BindTextureByTarget(ITextureHandle texId, TextureType texTarget) switch (texTarget) { case TextureType.Texture1D: - GL.BindTexture(TextureTarget.Texture1D, ((TextureHandle)texId).TexHandle); + GL.BindTexture(TextureTarget.Texture1d, ((TextureHandle)texId).TexHandle); break; case TextureType.Texture2D: - GL.BindTexture(TextureTarget.Texture2D, ((TextureHandle)texId).TexHandle); + GL.BindTexture(TextureTarget.Texture2d, ((TextureHandle)texId).TexHandle); break; case TextureType.Texture3D: - GL.BindTexture(TextureTarget.Texture3D, ((TextureHandle)texId).TexHandle); + GL.BindTexture(TextureTarget.Texture3d, ((TextureHandle)texId).TexHandle); break; case TextureType.TextureCubeMap: GL.BindTexture(TextureTarget.TextureCubeMap, ((TextureHandle)texId).TexHandle); break; case TextureType.ArrayTexture: - GL.BindTexture(TextureTarget.Texture2DArray, ((TextureHandle)texId).TexHandle); + GL.BindTexture(TextureTarget.Texture2dArray, ((TextureHandle)texId).TexHandle); break; case TextureType.TextureMultisample: - GL.BindTexture(TextureTarget.Texture2DMultisample, ((TextureHandle)texId).TexHandle); + GL.BindTexture(TextureTarget.Texture2dMultisample, ((TextureHandle)texId).TexHandle); break; case TextureType.Image2D: default: @@ -1017,24 +1036,22 @@ public void SetActiveAndBindTexture(IShaderParam param, ITextureHandle texId, Te _shaderParam2TexUnit[iParam] = texUnit; } - GL.ActiveTexture(TextureUnit.Texture0 + texUnit); + GL.ActiveTexture(TextureUnit.Texture0 + (uint)texUnit); BindTextureByTarget(texId, texTarget); } - private void SetActiveAndBindImage(IShaderParam param, ITextureHandle texId, TextureType texTarget, ImagePixelFormat format, TextureAccess access, out int texUnit) + private void SetActiveAndBindImage(IShaderParam param, ITextureHandle texId, TextureType texTarget, ImagePixelFormat format, BufferAccessARB access, out int texUnit) { int iParam = ((ShaderParam)param).handle; if (!_shaderParam2TexUnit.TryGetValue(iParam, out texUnit)) { _textureCountPerShader++; - texUnit = _textureCountPerShader; + texUnit = (int)_textureCountPerShader; _shaderParam2TexUnit[iParam] = texUnit; } - var sizedIntFormat = GetSizedInteralFormat(format); - - GL.ActiveTexture(TextureUnit.Texture0 + texUnit); - BindImage(texTarget, texId, texUnit, access, sizedIntFormat); + GL.ActiveTexture(TextureUnit.Texture0 + (uint)texUnit); + BindImage(texTarget, texId, (uint)texUnit, access, GetInteralFormat(format)); } /// @@ -1054,7 +1071,7 @@ public void SetActiveAndBindTexture(IShaderParam param, ITextureHandle texId, Te _shaderParam2TexUnit[iParam] = texUnit; } - GL.ActiveTexture(TextureUnit.Texture0 + texUnit); + GL.ActiveTexture(TextureUnit.Texture0 + (uint)texUnit); BindTextureByTarget(texId, texTarget); } @@ -1081,7 +1098,7 @@ public void SetActiveAndBindTextureArray(IShaderParam param, ITextureHandle[] te { texUnitArray[i] = firstTexUnit + i; - GL.ActiveTexture(TextureUnit.Texture0 + firstTexUnit + i); + GL.ActiveTexture(TextureUnit.Texture0 + (uint)firstTexUnit + (uint)i); BindTextureByTarget(texIds[i], texTarget); } } @@ -1110,7 +1127,7 @@ public void SetActiveAndBindTextureArray(IShaderParam param, ITextureHandle[] te { texUnitArray[i] = firstTexUnit + i; - GL.ActiveTexture(TextureUnit.Texture0 + firstTexUnit + i); + GL.ActiveTexture(TextureUnit.Texture0 + (uint)firstTexUnit + (uint)i); BindTextureByTarget(texIds[i], texTarget); } } @@ -1124,8 +1141,8 @@ public void SetActiveAndBindTextureArray(IShaderParam param, ITextureHandle[] te /// The internal sized format of the texture. public void SetShaderParamImage(IShaderParam param, ITextureHandle texId, TextureType texTarget, ImagePixelFormat format) { - SetActiveAndBindImage(param, texId, texTarget, format, TextureAccess.ReadWrite, out int texUnit); - GL.Uniform1(((ShaderParam)param).handle, texUnit); + SetActiveAndBindImage(param, texId, texTarget, format, BufferAccessARB.ReadWrite, out int texUnit); + GL.Uniform1i(((ShaderParam)param).handle, texUnit); } /// @@ -1137,7 +1154,7 @@ public void SetShaderParamImage(IShaderParam param, ITextureHandle texId, Textur public void SetShaderParamTexture(IShaderParam param, ITextureHandle texId, TextureType texTarget) { SetActiveAndBindTexture(param, texId, texTarget, out int texUnit); - GL.Uniform1(((ShaderParam)param).handle, texUnit); + GL.Uniform1i(((ShaderParam)param).handle, texUnit); } /// @@ -1146,14 +1163,11 @@ public void SetShaderParamTexture(IShaderParam param, ITextureHandle texId, Text /// Shader Parameter used for texture binding /// An array of ITextureHandles probably returned from CreateTexture method /// The texture type, describing to which texture target the texture gets bound to. - public unsafe void SetShaderParamTextureArray(IShaderParam param, ITextureHandle[] texIds, TextureType texTarget) + public void SetShaderParamTextureArray(IShaderParam param, ITextureHandle[] texIds, TextureType texTarget) { SetActiveAndBindTextureArray(param, texIds, texTarget, out int[] texUnitArray); - - fixed (int* pFlt = &texUnitArray[0]) - GL.Uniform1(((ShaderParam)param).handle, texUnitArray.Length, pFlt); + GL.Uniform1i(((ShaderParam)param).handle, texUnitArray.Length, new Span(texUnitArray)); } - #endregion #region Clear @@ -1177,8 +1191,13 @@ public float4 ClearColor { get { - GL.GetFloat(GetPName.ColorClearValue, out OpenTK.Mathematics.Vector4 ret); - return new float4(ret.X, ret.Y, ret.Z, ret.W); + float[] col = new float[4]; + unsafe + { + fixed (float* pFlt = &col[0]) + GL.GetFloatv(GetPName.ColorClearValue, pFlt); + } + return new float4(col[0], col[1], col[2], col[3]); } set => GL.ClearColor(value.x, value.y, value.z, value.w); } @@ -1193,7 +1212,8 @@ public float ClearDepth { get { - GL.GetFloat(GetPName.DepthClearValue, out float ret); + float ret = 0; + GL.GetFloat(GetPName.DepthClearValue, ref ret); return ret; } set => GL.ClearDepth(value); @@ -1253,12 +1273,16 @@ public IAttribImp CreateAttributeBuffer(float3[] attributes, string attributeNam } int vertsBytes = attributes.Length * 3 * sizeof(float); - GL.GenBuffers(1, out int handle); + var handle = GL.GenBuffer(); - GL.BindBuffer(BufferTarget.ArrayBuffer, handle); + unsafe + { + using var data = attributes.AsMemory().Pin(); + GL.BufferData(BufferTargetARB.ArrayBuffer, vertsBytes, data.Pointer, BufferUsageARB.StaticDraw); + } - GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertsBytes), attributes, BufferUsageHint.StaticDraw); - GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out int vboBytes); + int vboBytes = 0; + GL.GetBufferParameteri(BufferTargetARB.ArrayBuffer, BufferPNameARB.BufferSize, ref vboBytes); if (vboBytes != vertsBytes) throw new ApplicationException(string.Format( "Problem uploading attribute buffer to VBO ('{2}'). Tried to upload {0} bytes, uploaded {1}.", @@ -1276,11 +1300,11 @@ public void DeleteAttributeBuffer(IAttribImp attribHandle) { if (attribHandle != null) { - int handle = ((AttributeImp)attribHandle).AttributeBufferObject; - if (handle != 0) + var handle = ((AttributeImp)attribHandle).AttributeBufferObject; + if (handle.Handle != 0) { - GL.DeleteBuffer(handle); - ((AttributeImp)attribHandle).AttributeBufferObject = 0; + GL.DeleteBuffer(in handle); + ((AttributeImp)attribHandle).AttributeBufferObject.Handle = 0; } } } @@ -1291,7 +1315,7 @@ public void DeleteAttributeBuffer(IAttribImp attribHandle) /// The instance. public void SetVertexArrayObject(IMeshImp mr) { - if (((MeshImp)mr).VertexArrayObject == 0) + if (((MeshImp)mr).VertexArrayObject.Handle == 0) ((MeshImp)mr).VertexArrayObject = GL.GenVertexArray(); GL.BindVertexArray(((MeshImp)mr).VertexArrayObject); @@ -1312,15 +1336,17 @@ public void SetVertices(IMeshImp mr, float3[] vertices) } int vertsBytes = vertices.Length * 3 * sizeof(float); - if (((MeshImp)mr).VertexBufferObject == 0) + if (((MeshImp)mr).VertexBufferObject.Handle == 0) + ((MeshImp)mr).VertexBufferObject = GL.GenBuffer(); + + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).VertexBufferObject); + unsafe { - GL.GenBuffers(1, out int bufferObj); - ((MeshImp)mr).VertexBufferObject = bufferObj; + using var dataMemHandle = vertices.AsMemory().Pin(); + GL.BufferData(BufferTargetARB.ArrayBuffer, vertsBytes, dataMemHandle.Pointer, BufferUsageARB.StaticDraw); } - - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).VertexBufferObject); - GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertsBytes), vertices, BufferUsageHint.StaticDraw); - GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out int vboBytes); + int vboBytes = 0; + GL.GetBufferParameteri(BufferTargetARB.ArrayBuffer, BufferPNameARB.BufferSize, ref vboBytes); if (vboBytes != vertsBytes) throw new ApplicationException(string.Format("Problem uploading vertex buffer to VBO (vertices). Tried to upload {0} bytes, uploaded {1}.", vertsBytes, vboBytes)); } @@ -1340,15 +1366,17 @@ public void SetTangents(IMeshImp mr, float4[] tangents) } int tangentBytes = tangents.Length * 4 * sizeof(float); - if (((MeshImp)mr).TangentBufferObject == 0) + if (((MeshImp)mr).TangentBufferObject.Handle == 0) + ((MeshImp)mr).TangentBufferObject = GL.GenBuffer(); + + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).TangentBufferObject); + unsafe { - GL.GenBuffers(1, out int bufferObj); - ((MeshImp)mr).TangentBufferObject = bufferObj; + using var dataMemHandle = tangents.AsMemory().Pin(); + GL.BufferData(BufferTargetARB.ArrayBuffer, tangentBytes, dataMemHandle.Pointer, BufferUsageARB.StaticDraw); } - - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).TangentBufferObject); - GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(tangentBytes), tangents, BufferUsageHint.StaticDraw); - GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out int vboBytes); + int vboBytes = 0; + GL.GetBufferParameteri(BufferTargetARB.ArrayBuffer, BufferPNameARB.BufferSize, ref vboBytes); if (vboBytes != tangentBytes) throw new ApplicationException(string.Format("Problem uploading vertex buffer to VBO (tangents). Tried to upload {0} bytes, uploaded {1}.", tangentBytes, vboBytes)); } @@ -1368,15 +1396,17 @@ public void SetBiTangents(IMeshImp mr, float3[] bitangents) } int bitangentBytes = bitangents.Length * 3 * sizeof(float); - if (((MeshImp)mr).BitangentBufferObject == 0) + if (((MeshImp)mr).BitangentBufferObject.Handle == 0) + ((MeshImp)mr).BitangentBufferObject = GL.GenBuffer(); + + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).BitangentBufferObject); + unsafe { - GL.GenBuffers(1, out int bufferObj); - ((MeshImp)mr).BitangentBufferObject = bufferObj; + using var dataMemHandle = bitangents.AsMemory().Pin(); + GL.BufferData(BufferTargetARB.ArrayBuffer, bitangentBytes, dataMemHandle.Pointer, BufferUsageARB.StaticDraw); } - - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).BitangentBufferObject); - GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(bitangentBytes), bitangents, BufferUsageHint.StaticDraw); - GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out int vboBytes); + int vboBytes = 0; + GL.GetBufferParameteri(BufferTargetARB.ArrayBuffer, BufferPNameARB.BufferSize, ref vboBytes); if (vboBytes != bitangentBytes) throw new ApplicationException(string.Format("Problem uploading vertex buffer to VBO (bitangents). Tried to upload {0} bytes, uploaded {1}.", bitangentBytes, vboBytes)); } @@ -1396,15 +1426,17 @@ public void SetNormals(IMeshImp mr, float3[] normals) } int normsBytes = normals.Length * 3 * sizeof(float); - if (((MeshImp)mr).NormalBufferObject == 0) + if (((MeshImp)mr).NormalBufferObject.Handle == 0) + ((MeshImp)mr).NormalBufferObject = GL.GenBuffer(); + + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).NormalBufferObject); + unsafe { - GL.GenBuffers(1, out int bufferObj); - ((MeshImp)mr).NormalBufferObject = bufferObj; + using var dataMemHandle = normals.AsMemory().Pin(); + GL.BufferData(BufferTargetARB.ArrayBuffer, normsBytes, dataMemHandle.Pointer, BufferUsageARB.StaticDraw); } - - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).NormalBufferObject); - GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(normsBytes), normals, BufferUsageHint.StaticDraw); - GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out int vboBytes); + int vboBytes = 0; + GL.GetBufferParameteri(BufferTargetARB.ArrayBuffer, BufferPNameARB.BufferSize, ref vboBytes); if (vboBytes != normsBytes) throw new ApplicationException(string.Format("Problem uploading normal buffer to VBO (normals). Tried to upload {0} bytes, uploaded {1}.", normsBytes, vboBytes)); } @@ -1424,15 +1456,17 @@ public void SetBoneIndices(IMeshImp mr, float4[] boneIndices) } int indicesBytes = boneIndices.Length * 4 * sizeof(float); - if (((MeshImp)mr).BoneIndexBufferObject == 0) + if (((MeshImp)mr).BoneIndexBufferObject.Handle == 0) + ((MeshImp)mr).BoneIndexBufferObject = GL.GenBuffer(); + + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).BoneIndexBufferObject); + unsafe { - GL.GenBuffers(1, out int bufferObj); - ((MeshImp)mr).BoneIndexBufferObject = bufferObj; + using var dataMemHandle = boneIndices.AsMemory().Pin(); + GL.BufferData(BufferTargetARB.ArrayBuffer, indicesBytes, dataMemHandle.Pointer, BufferUsageARB.StaticDraw); } - - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).BoneIndexBufferObject); - GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(indicesBytes), boneIndices, BufferUsageHint.StaticDraw); - GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out int vboBytes); + int vboBytes = 0; + GL.GetBufferParameteri(BufferTargetARB.ArrayBuffer, BufferPNameARB.BufferSize, ref vboBytes); if (vboBytes != indicesBytes) throw new ApplicationException(string.Format("Problem uploading bone indices buffer to VBO (bone indices). Tried to upload {0} bytes, uploaded {1}.", indicesBytes, vboBytes)); } @@ -1452,15 +1486,17 @@ public void SetBoneWeights(IMeshImp mr, float4[] boneWeights) } int weightsBytes = boneWeights.Length * 4 * sizeof(float); - if (((MeshImp)mr).BoneWeightBufferObject == 0) + if (((MeshImp)mr).BoneWeightBufferObject.Handle == 0) + ((MeshImp)mr).BoneWeightBufferObject = GL.GenBuffer(); + + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).BoneWeightBufferObject); + unsafe { - GL.GenBuffers(1, out int bufferObj); - ((MeshImp)mr).BoneWeightBufferObject = bufferObj; + using var dataMemHandle = boneWeights.AsMemory().Pin(); + GL.BufferData(BufferTargetARB.ArrayBuffer, weightsBytes, dataMemHandle.Pointer, BufferUsageARB.StaticDraw); } - - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).BoneWeightBufferObject); - GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(weightsBytes), boneWeights, BufferUsageHint.StaticDraw); - GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out int vboBytes); + int vboBytes = 0; + GL.GetBufferParameteri(BufferTargetARB.ArrayBuffer, BufferPNameARB.BufferSize, ref vboBytes); if (vboBytes != weightsBytes) throw new ApplicationException(string.Format("Problem uploading bone weights buffer to VBO (bone weights). Tried to upload {0} bytes, uploaded {1}.", weightsBytes, vboBytes)); } @@ -1480,15 +1516,17 @@ public void SetUVs(IMeshImp mr, float2[] uvs) } int uvsBytes = uvs.Length * 2 * sizeof(float); - if (((MeshImp)mr).UVBufferObject == 0) + if (((MeshImp)mr).UVBufferObject.Handle == 0) + ((MeshImp)mr).UVBufferObject = GL.GenBuffer(); + + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).UVBufferObject); + unsafe { - GL.GenBuffers(1, out int bufferObj); - ((MeshImp)mr).UVBufferObject = bufferObj; + using var dataMemHandle = uvs.AsMemory().Pin(); + GL.BufferData(BufferTargetARB.ArrayBuffer, uvsBytes, dataMemHandle.Pointer, BufferUsageARB.StaticDraw); } - - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).UVBufferObject); - GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(uvsBytes), uvs, BufferUsageHint.StaticDraw); - GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out int vboBytes); + int vboBytes = 0; + GL.GetBufferParameteri(BufferTargetARB.ArrayBuffer, BufferPNameARB.BufferSize, ref vboBytes); if (vboBytes != uvsBytes) throw new ApplicationException(string.Format("Problem uploading uv buffer to VBO (uvs). Tried to upload {0} bytes, uploaded {1}.", uvsBytes, vboBytes)); } @@ -1508,15 +1546,17 @@ public void SetColors(IMeshImp mr, uint[] colors) } int colsBytes = colors.Length * sizeof(uint); - if (((MeshImp)mr).ColorBufferObject == 0) + if (((MeshImp)mr).ColorBufferObject.Handle == 0) + ((MeshImp)mr).ColorBufferObject = GL.GenBuffer(); + + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).ColorBufferObject); + unsafe { - GL.GenBuffers(1, out int bufferObj); - ((MeshImp)mr).ColorBufferObject = bufferObj; + using var dataMemHandle = colors.AsMemory().Pin(); + GL.BufferData(BufferTargetARB.ArrayBuffer, colsBytes, dataMemHandle.Pointer, BufferUsageARB.StaticDraw); } - - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).ColorBufferObject); - GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(colsBytes), colors, BufferUsageHint.StaticDraw); - GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out int vboBytes); + int vboBytes = 0; + GL.GetBufferParameteri(BufferTargetARB.ArrayBuffer, BufferPNameARB.BufferSize, ref vboBytes); if (vboBytes != colsBytes) throw new ApplicationException(string.Format("Problem uploading color buffer to VBO (colors). Tried to upload {0} bytes, uploaded {1}.", colsBytes, vboBytes)); } @@ -1536,15 +1576,17 @@ public void SetColors1(IMeshImp mr, uint[] colors) } int colsBytes = colors.Length * sizeof(uint); - if (((MeshImp)mr).ColorBufferObject1 == 0) + if (((MeshImp)mr).ColorBufferObject1.Handle == 0) + ((MeshImp)mr).ColorBufferObject1 = GL.GenBuffer(); + + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).ColorBufferObject1); + unsafe { - GL.GenBuffers(1, out int bufferObj); - ((MeshImp)mr).ColorBufferObject1 = bufferObj; + using var dataMemHandle = colors.AsMemory().Pin(); + GL.BufferData(BufferTargetARB.ArrayBuffer, colsBytes, dataMemHandle.Pointer, BufferUsageARB.StaticDraw); } - - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).ColorBufferObject1); - GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(colsBytes), colors, BufferUsageHint.StaticDraw); - GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out int vboBytes); + int vboBytes = 0; + GL.GetBufferParameteri(BufferTargetARB.ArrayBuffer, BufferPNameARB.BufferSize, ref vboBytes); if (vboBytes != colsBytes) throw new ApplicationException(string.Format("Problem uploading color buffer to VBO (colors). Tried to upload {0} bytes, uploaded {1}.", colsBytes, vboBytes)); } @@ -1564,15 +1606,19 @@ public void SetColors2(IMeshImp mr, uint[] colors) } int colsBytes = colors.Length * sizeof(uint); - if (((MeshImp)mr).ColorBufferObject2 == 0) + if (((MeshImp)mr).ColorBufferObject2.Handle == 0) + ((MeshImp)mr).ColorBufferObject2 = GL.GenBuffer(); + + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).ColorBufferObject2); + + unsafe { - GL.GenBuffers(1, out int bufferObj); - ((MeshImp)mr).ColorBufferObject2 = bufferObj; + using var dataMemHandle = colors.AsMemory().Pin(); + GL.BufferData(BufferTargetARB.ArrayBuffer, colsBytes, dataMemHandle.Pointer, BufferUsageARB.StaticDraw); } - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).ColorBufferObject2); - GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(colsBytes), colors, BufferUsageHint.StaticDraw); - GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out int vboBytes); + int vboBytes = 0; + GL.GetBufferParameteri(BufferTargetARB.ArrayBuffer, BufferPNameARB.BufferSize, ref vboBytes); if (vboBytes != colsBytes) throw new ApplicationException(string.Format("Problem uploading color buffer to VBO (colors). Tried to upload {0} bytes, uploaded {1}.", colsBytes, vboBytes)); } @@ -1593,15 +1639,18 @@ public void SetTriangles(IMeshImp mr, ushort[] triangleIndices) ((MeshImp)mr).NElements = triangleIndices.Length; int trisBytes = triangleIndices.Length * sizeof(short); - if (((MeshImp)mr).ElementBufferObject == 0) + if (((MeshImp)mr).ElementBufferObject.Handle == 0) + ((MeshImp)mr).ElementBufferObject = GL.GenBuffer(); + // Upload the index buffer (elements inside the vertex buffer, not color indices as per the IndexPointer function!) + GL.BindBuffer(BufferTargetARB.ElementArrayBuffer, ((MeshImp)mr).ElementBufferObject); + unsafe { - GL.GenBuffers(1, out int bufferObj); - ((MeshImp)mr).ElementBufferObject = bufferObj; + using var dataMemHandle = triangleIndices.AsMemory().Pin(); + GL.BufferData(BufferTargetARB.ElementArrayBuffer, trisBytes, dataMemHandle.Pointer, BufferUsageARB.StaticDraw); } - // Upload the index buffer (elements inside the vertex buffer, not color indices as per the IndexPointer function!) - GL.BindBuffer(BufferTarget.ElementArrayBuffer, ((MeshImp)mr).ElementBufferObject); - GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(trisBytes), triangleIndices, BufferUsageHint.StaticDraw); - GL.GetBufferParameter(BufferTarget.ElementArrayBuffer, BufferParameterName.BufferSize, out int vboBytes); + + int vboBytes = 0; + GL.GetBufferParameteri(BufferTargetARB.ElementArrayBuffer, BufferPNameARB.BufferSize, ref vboBytes); if (vboBytes != trisBytes) throw new ApplicationException(string.Format("Problem uploading vertex buffer to VBO (offsets). Tried to upload {0} bytes, uploaded {1}.", trisBytes, vboBytes)); } @@ -1643,8 +1692,7 @@ public void RemoveColors(IMeshImp mr) /// The mesh which buffer respectively GPU memory should be deleted. public void RemoveColors1(IMeshImp mr) { - int bufferObj = ((MeshImp)mr).ColorBufferObject1; - GL.DeleteBuffers(1, ref bufferObj); + GL.DeleteBuffer(((MeshImp)mr).ColorBufferObject1); ((MeshImp)mr).InvalidateColors1(); } @@ -1654,8 +1702,7 @@ public void RemoveColors1(IMeshImp mr) /// The mesh which buffer respectively GPU memory should be deleted. public void RemoveColors2(IMeshImp mr) { - int bufferObj = ((MeshImp)mr).ColorBufferObject2; - GL.DeleteBuffers(1, ref bufferObj); + GL.DeleteBuffer(((MeshImp)mr).ColorBufferObject2); ((MeshImp)mr).InvalidateColors2(); } @@ -1724,7 +1771,7 @@ public void RemoveBiTangents(IMeshImp mr) /// public void MemoryBarrier() { - GL.MemoryBarrier(MemoryBarrierFlags.AllBarrierBits); + GL.MemoryBarrier(MemoryBarrierMask.AllBarrierBits); } /// @@ -1734,7 +1781,7 @@ public void MemoryBarrier() /// The number of work groups to be launched in the X dimension. /// The number of work groups to be launched in the Y dimension. /// he number of work groups to be launched in the Z dimension. - public void DispatchCompute(int kernelIndex, int threadGroupsX, int threadGroupsY, int threadGroupsZ) + public void DispatchCompute(int kernelIndex, uint threadGroupsX, uint threadGroupsY, uint threadGroupsZ) { GL.DispatchCompute(threadGroupsX, threadGroupsY, threadGroupsZ); } @@ -1747,69 +1794,69 @@ public void Render(IMeshImp mr) { GL.BindVertexArray(((MeshImp)mr).VertexArrayObject); - if (((MeshImp)mr).VertexBufferObject != 0) + if (((MeshImp)mr).VertexBufferObject.Handle != 0) { GL.EnableVertexAttribArray(AttributeLocations.VertexAttribLocation); - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).VertexBufferObject); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).VertexBufferObject); GL.VertexAttribPointer(AttributeLocations.VertexAttribLocation, 3, VertexAttribPointerType.Float, false, 0, IntPtr.Zero); } - if (((MeshImp)mr).ColorBufferObject != 0) + if (((MeshImp)mr).ColorBufferObject.Handle != 0) { GL.EnableVertexAttribArray(AttributeLocations.ColorAttribLocation); - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).ColorBufferObject); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).ColorBufferObject); GL.VertexAttribPointer(AttributeLocations.ColorAttribLocation, 4, VertexAttribPointerType.UnsignedByte, true, 0, IntPtr.Zero); } - if (((MeshImp)mr).ColorBufferObject1 != 0) + if (((MeshImp)mr).ColorBufferObject1.Handle != 0) { GL.EnableVertexAttribArray(AttributeLocations.Color1AttribLocation); - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).ColorBufferObject1); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).ColorBufferObject1); GL.VertexAttribPointer(AttributeLocations.Color1AttribLocation, 4, VertexAttribPointerType.UnsignedByte, true, 0, IntPtr.Zero); } - if (((MeshImp)mr).ColorBufferObject2 != 0) + if (((MeshImp)mr).ColorBufferObject2.Handle != 0) { GL.EnableVertexAttribArray(AttributeLocations.Color2AttribLocation); - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).ColorBufferObject2); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).ColorBufferObject2); GL.VertexAttribPointer(AttributeLocations.Color2AttribLocation, 4, VertexAttribPointerType.UnsignedByte, true, 0, IntPtr.Zero); } - if (((MeshImp)mr).UVBufferObject != 0) + if (((MeshImp)mr).UVBufferObject.Handle != 0) { GL.EnableVertexAttribArray(AttributeLocations.UvAttribLocation); - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).UVBufferObject); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).UVBufferObject); GL.VertexAttribPointer(AttributeLocations.UvAttribLocation, 2, VertexAttribPointerType.Float, false, 0, IntPtr.Zero); } - if (((MeshImp)mr).NormalBufferObject != 0) + if (((MeshImp)mr).NormalBufferObject.Handle != 0) { GL.EnableVertexAttribArray(AttributeLocations.NormalAttribLocation); - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).NormalBufferObject); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).NormalBufferObject); GL.VertexAttribPointer(AttributeLocations.NormalAttribLocation, 3, VertexAttribPointerType.Float, false, 0, IntPtr.Zero); } - if (((MeshImp)mr).TangentBufferObject != 0) + if (((MeshImp)mr).TangentBufferObject.Handle != 0) { GL.EnableVertexAttribArray(AttributeLocations.TangentAttribLocation); - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).TangentBufferObject); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).TangentBufferObject); GL.VertexAttribPointer(AttributeLocations.TangentAttribLocation, 3, VertexAttribPointerType.Float, false, 0, IntPtr.Zero); } - if (((MeshImp)mr).BitangentBufferObject != 0) + if (((MeshImp)mr).BitangentBufferObject.Handle != 0) { GL.EnableVertexAttribArray(AttributeLocations.BitangentAttribLocation); - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).BitangentBufferObject); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).BitangentBufferObject); GL.VertexAttribPointer(AttributeLocations.BitangentAttribLocation, 3, VertexAttribPointerType.Float, false, 0, IntPtr.Zero); } - if (((MeshImp)mr).BoneIndexBufferObject != 0) + if (((MeshImp)mr).BoneIndexBufferObject.Handle != 0) { GL.EnableVertexAttribArray(AttributeLocations.BoneIndexAttribLocation); - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).BoneIndexBufferObject); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).BoneIndexBufferObject); GL.VertexAttribPointer(AttributeLocations.BoneIndexAttribLocation, 4, VertexAttribPointerType.Float, false, 0, IntPtr.Zero); } - if (((MeshImp)mr).BoneWeightBufferObject != 0) + if (((MeshImp)mr).BoneWeightBufferObject.Handle != 0) { GL.EnableVertexAttribArray(AttributeLocations.BoneWeightAttribLocation); - GL.BindBuffer(BufferTarget.ArrayBuffer, ((MeshImp)mr).BoneWeightBufferObject); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, ((MeshImp)mr).BoneWeightBufferObject); GL.VertexAttribPointer(AttributeLocations.BoneWeightAttribLocation, 4, VertexAttribPointerType.Float, false, 0, IntPtr.Zero); } - if (((MeshImp)mr).ElementBufferObject != 0) + if (((MeshImp)mr).ElementBufferObject.Handle != 0) { - GL.BindBuffer(BufferTarget.ElementArrayBuffer, ((MeshImp)mr).ElementBufferObject); + GL.BindBuffer(BufferTargetARB.ElementArrayBuffer, ((MeshImp)mr).ElementBufferObject); switch (((MeshImp)mr).MeshType) { @@ -1824,7 +1871,7 @@ public void Render(IMeshImp mr) _isPtRenderingEnabled = true; GL.Enable(EnableCap.ProgramPointSize); //GL.Enable(EnableCap.PointSprite); - GL.Enable(EnableCap.VertexProgramPointSize); + //GL.Enable(EnableCap.VertexProgramPointSize); } GL.DrawElements(OpenTK.Graphics.OpenGL.PrimitiveType.Points, ((MeshImp)mr).NElements, DrawElementsType.UnsignedShort, IntPtr.Zero); break; @@ -1867,20 +1914,20 @@ public void Render(IMeshImp mr) } } - if (((MeshImp)mr).VertexBufferObject != 0) + if (((MeshImp)mr).VertexBufferObject.Handle != 0) GL.DisableVertexAttribArray(AttributeLocations.VertexAttribLocation); - if (((MeshImp)mr).ColorBufferObject != 0) + if (((MeshImp)mr).ColorBufferObject.Handle != 0) GL.DisableVertexAttribArray(AttributeLocations.ColorAttribLocation); - if (((MeshImp)mr).NormalBufferObject != 0) + if (((MeshImp)mr).NormalBufferObject.Handle != 0) GL.DisableVertexAttribArray(AttributeLocations.NormalAttribLocation); - if (((MeshImp)mr).UVBufferObject != 0) + if (((MeshImp)mr).UVBufferObject.Handle != 0) GL.DisableVertexAttribArray(AttributeLocations.UvAttribLocation); - if (((MeshImp)mr).TangentBufferObject != 0) + if (((MeshImp)mr).TangentBufferObject.Handle != 0) GL.DisableVertexAttribArray(AttributeLocations.TangentAttribLocation); - if (((MeshImp)mr).BitangentBufferObject != 0) + if (((MeshImp)mr).BitangentBufferObject.Handle != 0) GL.DisableVertexAttribArray(AttributeLocations.TangentAttribLocation); - GL.BindVertexArray(0); + GL.BindVertexArray(new VertexArrayHandle(0)); } /// @@ -1890,8 +1937,8 @@ public void Render(IMeshImp mr) /// The texture identifier. public void GetBufferContent(Common.Rectangle quad, ITextureHandle texId) { - GL.BindTexture(TextureTarget.Texture2D, ((TextureHandle)texId).TexHandle); - GL.CopyTexImage2D(TextureTarget.Texture2D, 0, InternalFormat.Rgba, quad.Left, quad.Top, quad.Width, quad.Height, 0); + GL.BindTexture(TextureTarget.Texture2d, ((TextureHandle)texId).TexHandle); + GL.CopyTexImage2D(TextureTarget.Texture2d, 0, InternalFormat.Rgba, quad.Left, quad.Top, quad.Width, quad.Height, 0); } /// @@ -1903,28 +1950,28 @@ public IMeshImp CreateMeshImp() return new MeshImp(); } - internal static BlendEquationMode BlendOperationToOgl(BlendOperation bo) + internal static BlendEquationModeEXT BlendOperationToOgl(BlendOperation bo) { return bo switch { - BlendOperation.Add => BlendEquationMode.FuncAdd, - BlendOperation.Subtract => BlendEquationMode.FuncSubtract, - BlendOperation.ReverseSubtract => BlendEquationMode.FuncReverseSubtract, - BlendOperation.Minimum => BlendEquationMode.Min, - BlendOperation.Maximum => BlendEquationMode.Max, + BlendOperation.Add => BlendEquationModeEXT.FuncAdd, + BlendOperation.Subtract => BlendEquationModeEXT.FuncSubtract, + BlendOperation.ReverseSubtract => BlendEquationModeEXT.FuncReverseSubtract, + BlendOperation.Minimum => BlendEquationModeEXT.Min, + BlendOperation.Maximum => BlendEquationModeEXT.Max, _ => throw new ArgumentOutOfRangeException($"Invalid argument: {bo}"), }; } - internal static BlendOperation BlendOperationFromOgl(BlendEquationMode bom) + internal static BlendOperation BlendOperationFromOgl(BlendEquationModeEXT bom) { return bom switch { - BlendEquationMode.FuncAdd => BlendOperation.Add, - BlendEquationMode.Min => BlendOperation.Minimum, - BlendEquationMode.Max => BlendOperation.Maximum, - BlendEquationMode.FuncSubtract => BlendOperation.Subtract, - BlendEquationMode.FuncReverseSubtract => BlendOperation.ReverseSubtract, + BlendEquationModeEXT.FuncAdd => BlendOperation.Add, + BlendEquationModeEXT.Min => BlendOperation.Minimum, + BlendEquationModeEXT.Max => BlendOperation.Maximum, + BlendEquationModeEXT.FuncSubtract => BlendOperation.Subtract, + BlendEquationModeEXT.FuncReverseSubtract => BlendOperation.ReverseSubtract, _ => throw new ArgumentOutOfRangeException($"Invalid argument: {bom}"), }; } @@ -1933,18 +1980,18 @@ internal static int BlendToOgl(Blend blend, bool isForBlendFactorAlpha = false) { return blend switch { - Blend.Zero => (int)BlendingFactorSrc.Zero, - Blend.One => (int)BlendingFactorSrc.One, - Blend.SourceColor => (int)BlendingFactorDest.SrcColor, - Blend.InverseSourceColor => (int)BlendingFactorDest.OneMinusSrcColor, - Blend.SourceAlpha => (int)BlendingFactorSrc.SrcAlpha, - Blend.InverseSourceAlpha => (int)BlendingFactorSrc.OneMinusSrcAlpha, - Blend.DestinationAlpha => (int)BlendingFactorSrc.DstAlpha, - Blend.InverseDestinationAlpha => (int)BlendingFactorSrc.OneMinusDstAlpha, - Blend.DestinationColor => (int)BlendingFactorSrc.DstColor, - Blend.InverseDestinationColor => (int)BlendingFactorSrc.OneMinusDstColor, - Blend.BlendFactor => (int)((isForBlendFactorAlpha) ? BlendingFactorSrc.ConstantAlpha : BlendingFactorSrc.ConstantColor), - Blend.InverseBlendFactor => (int)((isForBlendFactorAlpha) ? BlendingFactorSrc.OneMinusConstantAlpha : BlendingFactorSrc.OneMinusConstantColor), + Blend.Zero => (int)BlendingFactor.Zero, + Blend.One => (int)BlendingFactor.One, + Blend.SourceColor => (int)BlendingFactor.SrcColor, + Blend.InverseSourceColor => (int)BlendingFactor.OneMinusSrcColor, + Blend.SourceAlpha => (int)BlendingFactor.SrcAlpha, + Blend.InverseSourceAlpha => (int)BlendingFactor.OneMinusSrcAlpha, + Blend.DestinationAlpha => (int)BlendingFactor.DstAlpha, + Blend.InverseDestinationAlpha => (int)BlendingFactor.OneMinusDstAlpha, + Blend.DestinationColor => (int)BlendingFactor.DstColor, + Blend.InverseDestinationColor => (int)BlendingFactor.OneMinusDstColor, + Blend.BlendFactor => (int)((isForBlendFactorAlpha) ? BlendingFactor.ConstantAlpha : BlendingFactor.ConstantColor), + Blend.InverseBlendFactor => (int)((isForBlendFactorAlpha) ? BlendingFactor.OneMinusConstantAlpha : BlendingFactor.OneMinusConstantColor), // Ignored... // case Blend.SourceAlphaSaturated: // break; @@ -1964,18 +2011,18 @@ internal static Blend BlendFromOgl(int bf) { return bf switch { - (int)BlendingFactorSrc.Zero => Blend.Zero, - (int)BlendingFactorSrc.One => Blend.One, - (int)BlendingFactorDest.SrcColor => Blend.SourceColor, - (int)BlendingFactorDest.OneMinusSrcColor => Blend.InverseSourceColor, - (int)BlendingFactorSrc.SrcAlpha => Blend.SourceAlpha, - (int)BlendingFactorSrc.OneMinusSrcAlpha => Blend.InverseSourceAlpha, - (int)BlendingFactorSrc.DstAlpha => Blend.DestinationAlpha, - (int)BlendingFactorSrc.OneMinusDstAlpha => Blend.InverseDestinationAlpha, - (int)BlendingFactorSrc.DstColor => Blend.DestinationColor, - (int)BlendingFactorSrc.OneMinusDstColor => Blend.InverseDestinationColor, - (int)BlendingFactorSrc.ConstantAlpha or (int)BlendingFactorSrc.ConstantColor => Blend.BlendFactor, - (int)BlendingFactorSrc.OneMinusConstantAlpha or (int)BlendingFactorSrc.OneMinusConstantColor => Blend.InverseBlendFactor, + (int)BlendingFactor.Zero => Blend.Zero, + (int)BlendingFactor.One => Blend.One, + (int)BlendingFactor.SrcColor => Blend.SourceColor, + (int)BlendingFactor.OneMinusSrcColor => Blend.InverseSourceColor, + (int)BlendingFactor.SrcAlpha => Blend.SourceAlpha, + (int)BlendingFactor.OneMinusSrcAlpha => Blend.InverseSourceAlpha, + (int)BlendingFactor.DstAlpha => Blend.DestinationAlpha, + (int)BlendingFactor.OneMinusDstAlpha => Blend.InverseDestinationAlpha, + (int)BlendingFactor.DstColor => Blend.DestinationColor, + (int)BlendingFactor.OneMinusDstColor => Blend.InverseDestinationColor, + (int)BlendingFactor.ConstantAlpha or (int)BlendingFactor.ConstantColor => Blend.BlendFactor, + (int)BlendingFactor.OneMinusConstantAlpha or (int)BlendingFactor.OneMinusConstantColor => Blend.InverseBlendFactor, _ => throw new ArgumentOutOfRangeException("blend"), }; } @@ -2082,30 +2129,31 @@ public void SetRenderState(RenderState renderState, uint value) break; case RenderState.SourceBlend: { - _blendSrcRgb = (BlendingFactorSrc)BlendToOgl((Blend)value); + _blendSrcRgb = (BlendingFactor)BlendToOgl((Blend)value); GL.BlendFuncSeparate(_blendSrcRgb, _blendDstRgb, _blendSrcAlpha, _blendDstAlpha); } break; case RenderState.DestinationBlend: { - _blendDstRgb = (BlendingFactorDest)BlendToOgl((Blend)value); + _blendDstRgb = (BlendingFactor)BlendToOgl((Blend)value); GL.BlendFuncSeparate(_blendSrcRgb, _blendDstRgb, _blendSrcAlpha, _blendDstAlpha); } break; case RenderState.SourceBlendAlpha: { - _blendSrcAlpha = (BlendingFactorSrc)BlendToOgl((Blend)value); + _blendSrcAlpha = (BlendingFactor)BlendToOgl((Blend)value); GL.BlendFuncSeparate(_blendSrcRgb, _blendDstRgb, _blendSrcAlpha, _blendDstAlpha); } break; case RenderState.DestinationBlendAlpha: { - _blendDstAlpha = (BlendingFactorDest)BlendToOgl((Blend)value); + _blendDstAlpha = (BlendingFactor)BlendToOgl((Blend)value); GL.BlendFuncSeparate(_blendSrcRgb, _blendDstRgb, _blendSrcAlpha, _blendDstAlpha); } break; case RenderState.BlendFactor: - GL.BlendColor(System.Drawing.Color.FromArgb((int)value)); + var col = System.Drawing.Color.FromArgb((int)value); + GL.BlendColor(col.R, col.G, col.B, col.A); break; default: throw new ArgumentOutOfRangeException(nameof(renderState)); @@ -2130,7 +2178,8 @@ public uint GetRenderState(RenderState renderState) { case RenderState.FillMode: { - GL.GetInteger(GetPName.PolygonMode, out int pm); + int pm = 0; + GL.GetInteger(GetPName.PolygonMode, ref pm); var ret = (PolygonMode)pm switch { PolygonMode.Point => FillMode.Point, @@ -2142,10 +2191,12 @@ public uint GetRenderState(RenderState renderState) } case RenderState.CullMode: { - GL.GetInteger(GetPName.CullFace, out int cullFace); + int cullFace = 0; + int frontFace = 0; + GL.GetInteger(GetPName.CullFace, ref cullFace); if (cullFace == 0) return (uint)Cull.None; - GL.GetInteger(GetPName.FrontFace, out int frontFace); + GL.GetInteger(GetPName.FrontFace, ref frontFace); if (frontFace == (int)FrontFaceDirection.Cw) return (uint)Cull.Clockwise; return (uint)Cull.Counterclockwise; @@ -2155,7 +2206,8 @@ public uint GetRenderState(RenderState renderState) return 1; // == true case RenderState.ZFunc: { - GL.GetInteger(GetPName.DepthFunc, out int depFunc); + int depFunc = 0; + GL.GetInteger(GetPName.DepthFunc, ref depFunc); var ret = (DepthFunction)depFunc switch { DepthFunction.Never => Compare.Never, @@ -2172,52 +2224,61 @@ public uint GetRenderState(RenderState renderState) } case RenderState.ZEnable: { - GL.GetInteger(GetPName.DepthTest, out int depTest); + int depTest = 0; + GL.GetInteger(GetPName.DepthTest, ref depTest); return (uint)(depTest); } case RenderState.ZWriteEnable: { - GL.GetInteger(GetPName.DepthWritemask, out int depWriteMask); + int depWriteMask = 0; + GL.GetInteger(GetPName.DepthWritemask, ref depWriteMask); return (uint)(depWriteMask); } case RenderState.AlphaBlendEnable: { - GL.GetInteger(GetPName.Blend, out int blendEnable); + int blendEnable = 0; + GL.GetInteger(GetPName.Blend, ref blendEnable); return (uint)(blendEnable); } case RenderState.BlendOperation: { - GL.GetInteger(GetPName.BlendEquationRgb, out int rgbMode); - return (uint)BlendOperationFromOgl((BlendEquationMode)rgbMode); + int rgbMode = 0; + GL.GetInteger(GetPName.BlendEquationRgb, ref rgbMode); + return (uint)BlendOperationFromOgl((BlendEquationModeEXT)rgbMode); } case RenderState.BlendOperationAlpha: { - GL.GetInteger(GetPName.BlendEquationAlpha, out int alphaMode); - return (uint)BlendOperationFromOgl((BlendEquationMode)alphaMode); + int alphaMode = 0; + GL.GetInteger(GetPName.BlendEquationAlpha, ref alphaMode); + return (uint)BlendOperationFromOgl((BlendEquationModeEXT)alphaMode); } case RenderState.SourceBlend: { - GL.GetInteger(GetPName.BlendSrcRgb, out int rgbSrc); + int rgbSrc = 0; + GL.GetInteger(GetPName.BlendSrcRgb, ref rgbSrc); return (uint)BlendFromOgl(rgbSrc); } case RenderState.DestinationBlend: { - GL.GetInteger(GetPName.BlendSrcRgb, out int rgbDst); + int rgbDst = 0; + GL.GetInteger(GetPName.BlendSrcRgb, ref rgbDst); return (uint)BlendFromOgl(rgbDst); } case RenderState.SourceBlendAlpha: { - GL.GetInteger(GetPName.BlendSrcAlpha, out int alphaSrc); + int alphaSrc = 0; + GL.GetInteger(GetPName.BlendSrcAlpha, ref alphaSrc); return (uint)BlendFromOgl(alphaSrc); } case RenderState.DestinationBlendAlpha: { - GL.GetInteger(GetPName.BlendDstAlpha, out int alphaDst); + int alphaDst = 0; + GL.GetInteger(GetPName.BlendDstAlpha, ref alphaDst); return (uint)BlendFromOgl(alphaDst); } case RenderState.BlendFactor: - int col; - GL.GetInteger(GetPName.BlendColorExt, out col); + int col = 0; + GL.GetInteger(GetPName.BlendColorExt, ref col); return (uint)col; default: throw new ArgumentOutOfRangeException(nameof(renderState)); @@ -2240,7 +2301,7 @@ public void BlitMultisample2DTextureToTexture(ITextureHandle input, ITextureHand GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, ((TextureHandle)output).FrameBufferHandle); GL.BlitFramebuffer(0, 0, width, height, 0, 0, width, height, ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Nearest); - GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); + GL.BindFramebuffer(FramebufferTarget.Framebuffer, new FramebufferHandle(0)); } /// @@ -2263,13 +2324,13 @@ public void SetRenderTarget(IWritableTexture tex, ITextureHandle texHandle) /// The texture handle, associated with the given texture. Should be created by the TextureManager in the RenderContext. public void SetRenderTarget(WritableTexture tex, ITextureHandle texHandle) { - if (((TextureHandle)texHandle).FrameBufferHandle == -1) + if (((TextureHandle)texHandle).FrameBufferHandle.Handle == -1) { var fBuffer = GL.GenFramebuffer(); ((TextureHandle)texHandle).FrameBufferHandle = fBuffer; GL.BindFramebuffer(FramebufferTarget.Framebuffer, fBuffer); - GL.BindTexture(TextureTarget.Texture2D, ((TextureHandle)texHandle).TexHandle); + GL.BindTexture(TextureTarget.Texture2d, ((TextureHandle)texHandle).TexHandle); if (tex.TextureType != RenderTargetTextureTypes.Depth) { @@ -2292,7 +2353,7 @@ public void SetRenderTarget(WritableTexture tex, ITextureHandle texHandle) else GL.BindFramebuffer(FramebufferTarget.Framebuffer, ((TextureHandle)texHandle).FrameBufferHandle); - if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete) + if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferStatus.FramebufferComplete) throw new Exception($"Error creating RenderTarget: {GL.GetError()}, {GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer)}"); GL.Clear(ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit); @@ -2306,23 +2367,23 @@ public void SetRenderTarget(WritableTexture tex, ITextureHandle texHandle) /// The texture handle, associated with the given texture. Should be created by the TextureManager in the RenderContext. public void SetRenderTarget(WritableMultisampleTexture tex, ITextureHandle texHandle) { - if (((TextureHandle)texHandle).FrameBufferHandle == -1) + if (((TextureHandle)texHandle).FrameBufferHandle.Handle == -1) { var fBuffer = GL.GenFramebuffer(); ((TextureHandle)texHandle).FrameBufferHandle = fBuffer; GL.BindFramebuffer(FramebufferTarget.Framebuffer, fBuffer); - GL.BindTexture(TextureTarget.Texture2DMultisample, ((TextureHandle)texHandle).TexHandle); + GL.BindTexture(TextureTarget.Texture2dMultisample, ((TextureHandle)texHandle).TexHandle); if (tex.TextureType != RenderTargetTextureTypes.Depth) { ((TextureHandle)texHandle).DepthRenderBufferHandle = CreateDepthRenderBufferMultisample(tex.Width, tex.Height, tex.MultisampleFactor); - GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2DMultisample, ((TextureHandle)texHandle).TexHandle, 0); + GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2dMultisample, ((TextureHandle)texHandle).TexHandle, 0); GL.DrawBuffer(DrawBufferMode.ColorAttachment0); } else { - GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture2DMultisample, ((TextureHandle)texHandle).TexHandle, 0); + GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture2dMultisample, ((TextureHandle)texHandle).TexHandle, 0); GL.DrawBuffer(DrawBufferMode.None); GL.ReadBuffer(ReadBufferMode.None); } @@ -2334,7 +2395,7 @@ public void SetRenderTarget(WritableMultisampleTexture tex, ITextureHandle texHa else GL.BindFramebuffer(FramebufferTarget.Framebuffer, ((TextureHandle)texHandle).FrameBufferHandle); - if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete) + if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferStatus.FramebufferComplete) throw new Exception($"Error creating RenderTarget: {GL.GetError()}, {GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer)}"); GL.Clear(ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit); @@ -2348,7 +2409,7 @@ public void SetRenderTarget(WritableMultisampleTexture tex, ITextureHandle texHa /// The texture handle, associated with the given cube map. Should be created by the TextureManager in the RenderContext. public void SetRenderTarget(IWritableCubeMap tex, ITextureHandle texHandle) { - if (((TextureHandle)texHandle).FrameBufferHandle == -1) + if (((TextureHandle)texHandle).FrameBufferHandle.Handle == -1) { var fBuffer = GL.GenFramebuffer(); ((TextureHandle)texHandle).FrameBufferHandle = fBuffer; @@ -2372,7 +2433,7 @@ public void SetRenderTarget(IWritableCubeMap tex, ITextureHandle texHandle) else GL.BindFramebuffer(FramebufferTarget.Framebuffer, ((TextureHandle)texHandle).FrameBufferHandle); - if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete) + if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferStatus.FramebufferComplete) throw new Exception($"Error creating RenderTarget: {GL.GetError()}, {GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer)}"); @@ -2387,13 +2448,13 @@ public void SetRenderTarget(IWritableCubeMap tex, ITextureHandle texHandle) /// The texture handle, associated with the given texture. Should be created by the TextureManager in the RenderContext. public void SetRenderTarget(IWritableArrayTexture tex, int layer, ITextureHandle texHandle) { - if (((TextureHandle)texHandle).FrameBufferHandle == -1) + if (((TextureHandle)texHandle).FrameBufferHandle.Handle == -1) { var fBuffer = GL.GenFramebuffer(); ((TextureHandle)texHandle).FrameBufferHandle = fBuffer; GL.BindFramebuffer(FramebufferTarget.Framebuffer, fBuffer); - GL.BindTexture(TextureTarget.Texture2DArray, ((TextureHandle)texHandle).TexHandle); + GL.BindTexture(TextureTarget.Texture2dArray, ((TextureHandle)texHandle).TexHandle); if (tex.TextureType != RenderTargetTextureTypes.Depth) { @@ -2411,11 +2472,11 @@ public void SetRenderTarget(IWritableArrayTexture tex, int layer, ITextureHandle else { GL.BindFramebuffer(FramebufferTarget.Framebuffer, ((TextureHandle)texHandle).FrameBufferHandle); - GL.BindTexture(TextureTarget.Texture2DArray, ((TextureHandle)texHandle).TexHandle); + GL.BindTexture(TextureTarget.Texture2dArray, ((TextureHandle)texHandle).TexHandle); GL.FramebufferTextureLayer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, ((TextureHandle)texHandle).TexHandle, 0, layer); } - if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete) + if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferStatus.FramebufferComplete) throw new Exception($"Error creating RenderTarget: {GL.GetError()}, {GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer)}"); GL.Clear(ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit); @@ -2430,11 +2491,11 @@ public void SetRenderTarget(IRenderTarget renderTarget, ITextureHandle[] texHand { if (renderTarget == null || (renderTarget.RenderTextures.All(x => x == null))) { - GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); + GL.BindFramebuffer(FramebufferTarget.Framebuffer, new FramebufferHandle(0)); return; } - int gBuffer; + FramebufferHandle gBuffer; if (renderTarget.GBufferHandle == null) { @@ -2450,7 +2511,7 @@ public void SetRenderTarget(IRenderTarget renderTarget, ITextureHandle[] texHand if (renderTarget.RenderTextures[(int)RenderTargetTextureTypes.Depth] == null && !renderTarget.IsDepthOnly) { - int gDepthRenderbufferHandle; + RenderbufferHandle gDepthRenderbufferHandle; if (renderTarget.DepthBufferHandle == null) { renderTarget.DepthBufferHandle = new RenderBufferHandle(); @@ -2465,7 +2526,7 @@ public void SetRenderTarget(IRenderTarget renderTarget, ITextureHandle[] texHand } } - if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete) + if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferStatus.FramebufferComplete) { throw new Exception($"Error creating RenderTarget: {GL.GetError()}, {GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer)}"); } @@ -2473,31 +2534,31 @@ public void SetRenderTarget(IRenderTarget renderTarget, ITextureHandle[] texHand GL.Clear(ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit); } - private int CreateDepthRenderBuffer(int width, int height) + private RenderbufferHandle CreateDepthRenderBuffer(int width, int height) { GL.Enable(EnableCap.DepthTest); - GL.GenRenderbuffers(1, out int gDepthRenderbufferHandle); + var gDepthRenderbufferHandle = GL.GenRenderbuffer(); //((FrameBufferHandle)renderTarget.DepthBufferHandle).Handle = gDepthRenderbufferHandle; GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, gDepthRenderbufferHandle); - GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.DepthComponent24, width, height); + GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, InternalFormat.DepthComponent24, width, height); GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, gDepthRenderbufferHandle); return gDepthRenderbufferHandle; } - private int CreateDepthRenderBufferMultisample(int width, int height, int samples) + private RenderbufferHandle CreateDepthRenderBufferMultisample(int width, int height, int samples) { GL.Enable(EnableCap.DepthTest); - GL.GenRenderbuffers(1, out int gDepthRenderbufferHandle); + var gDepthRenderbufferHandle = GL.GenRenderbuffer(); //((FrameBufferHandle)renderTarget.DepthBufferHandle).Handle = gDepthRenderbufferHandle; GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, gDepthRenderbufferHandle); - GL.RenderbufferStorageMultisample(RenderbufferTarget.Renderbuffer, samples, RenderbufferStorage.DepthComponent24, width, height); + GL.RenderbufferStorageMultisample(RenderbufferTarget.Renderbuffer, samples, InternalFormat.DepthComponent24, width, height); GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, gDepthRenderbufferHandle); return gDepthRenderbufferHandle; } - private int CreateFrameBuffer(IRenderTarget renderTarget, ITextureHandle[] texHandles) + private FramebufferHandle CreateFrameBuffer(IRenderTarget renderTarget, ITextureHandle[] texHandles) { var gBuffer = GL.GenFramebuffer(); GL.BindFramebuffer(FramebufferTarget.Framebuffer, gBuffer); @@ -2508,32 +2569,32 @@ private int CreateFrameBuffer(IRenderTarget renderTarget, ITextureHandle[] texHa if (!renderTarget.IsDepthOnly) { - var attachments = new List(); + var attachments = new List(); //Textures - for (int i = 0; i < texHandles.Length; i++) + for (uint i = 0; i < texHandles.Length; i++) { - attachments.Add(DrawBuffersEnum.ColorAttachment0 + i); + attachments.Add(DrawBufferMode.ColorAttachment0 + i); var texHandle = texHandles[i]; if (texHandle == null) continue; if (i == depthTexPos) { - GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment + (depthCnt), TextureTarget.Texture2D, ((TextureHandle)texHandle).TexHandle, 0); + GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment + (uint)(depthCnt), TextureTarget.Texture2d, ((TextureHandle)texHandle).TexHandle, 0); depthCnt++; } else - GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0 + (i - depthCnt), TextureTarget.Texture2D, ((TextureHandle)texHandle).TexHandle, 0); + GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0 + (uint)(i - depthCnt), TextureTarget.Texture2d, ((TextureHandle)texHandle).TexHandle, 0); } - GL.DrawBuffers(attachments.Count, attachments.ToArray()); + GL.DrawBuffers(attachments.ToArray()); } else //If a frame-buffer only has a depth texture we don't need draw buffers { var texHandle = texHandles[depthTexPos]; if (texHandle != null) - GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture2D, ((TextureHandle)texHandle).TexHandle, 0); + GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture2d, ((TextureHandle)texHandle).TexHandle, 0); else throw new NullReferenceException("Texture handle is null!"); @@ -2552,7 +2613,7 @@ private int CreateFrameBuffer(IRenderTarget renderTarget, ITextureHandle[] texHa /// Determines if the texture is a depth texture. In this case the texture currently associated with will be detached. public void DetachTextureFromFbo(IRenderTarget renderTarget, bool isDepthTex, int attachment = 0) { - ChangeFramebufferTexture2D(renderTarget, attachment, 0, isDepthTex); + ChangeFramebufferTexture2d(renderTarget, attachment, new OpenTK.Graphics.TextureHandle(0), isDepthTex); } @@ -2565,32 +2626,33 @@ public void DetachTextureFromFbo(IRenderTarget renderTarget, bool isDepthTex, in /// The gpu handle of the texture. public void AttacheTextureToFbo(IRenderTarget renderTarget, bool isDepthTex, ITextureHandle texHandle, int attachment = 0) { - ChangeFramebufferTexture2D(renderTarget, attachment, ((TextureHandle)texHandle).TexHandle, isDepthTex); + ChangeFramebufferTexture2d(renderTarget, attachment, ((TextureHandle)texHandle).TexHandle, isDepthTex); } - private void ChangeFramebufferTexture2D(IRenderTarget renderTarget, int attachment, int handle, bool isDepth) + private void ChangeFramebufferTexture2d(IRenderTarget renderTarget, int attachment, OpenTK.Graphics.TextureHandle handle, bool isDepth) { - var boundFbo = GL.GetInteger(GetPName.FramebufferBinding); + int boundFbo = 0; + GL.GetInteger(GetPName.DrawFramebufferBinding, ref boundFbo); var rtFbo = ((FrameBufferHandle)renderTarget.GBufferHandle).Handle; var isCurrentFbo = true; - if (boundFbo != rtFbo) + if (boundFbo != rtFbo.Handle) { isCurrentFbo = false; GL.BindFramebuffer(FramebufferTarget.Framebuffer, rtFbo); } if (!isDepth) - GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0 + attachment, TextureTarget.Texture2D, handle, 0); + GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0 + (uint)attachment, TextureTarget.Texture2d, handle, 0); else - GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture2D, handle, 0); + GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture2d, handle, 0); - if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete) + if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferStatus.FramebufferComplete) throw new Exception($"Error creating RenderTarget: {GL.GetError()}, {GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer)}"); if (!isCurrentFbo) - GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFbo); + GL.BindFramebuffer(FramebufferTarget.Framebuffer, new FramebufferHandle(boundFbo)); } @@ -2651,8 +2713,9 @@ public uint GetHardwareCapabilities(HardwareCapability capability) private uint GetSampleSize() { - GL.GetInternalformat(ImageTarget.Texture2DMultisample, GetSizedInteralFormat(new ImagePixelFormat(ColorFormat.RGBA)), InternalFormatParameter.Samples, 32, out int sampleSize); - return (uint)sampleSize; + int size = 0; + GL.GetInternalformati(TextureTarget.Texture2dMultisample, GetInteralFormat(new ImagePixelFormat(ColorFormat.RGBA)), InternalFormatPName.Samples, 32, ref size); + return (uint)size; } /// @@ -2663,23 +2726,6 @@ public string GetHardwareDescription() { return "Vendor: " + GL.GetString(StringName.Vendor) + "\nRenderer: " + GL.GetString(StringName.Renderer) + "\nVersion: " + GL.GetString(StringName.Version) + "\nExtensions: " + GL.GetString(StringName.Extensions); } - - /// - /// Draws a Debug Line in 3D Space by using a start and end point (float3). - /// - /// The starting point of the DebugLine. - /// The endpoint of the DebugLine. - /// The color of the DebugLine. - public void DebugLine(float3 start, float3 end, float4 color) - { - GL.Begin(OpenTK.Graphics.OpenGL.PrimitiveType.Lines); - GL.Color4(color.x, color.y, color.z, color.w); - GL.Vertex3(start.x, start.y, start.z); - GL.Color4(color.x, color.y, color.z, color.w); - GL.Vertex3(end.x, end.y, end.z); - GL.End(); - } - #endregion #region Shader Storage Buffer @@ -2695,7 +2741,7 @@ public void ConnectBufferToShaderStorage(IShaderHandle currentProgram, IStorageB var shaderProgram = ((ShaderHandleImp)currentProgram).Handle; var resInx = GL.GetProgramResourceIndex(shaderProgram, ProgramInterface.ShaderStorageBlock, ssboName); GL.ShaderStorageBlockBinding(shaderProgram, resInx, buffer.BindingIndex); - GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, buffer.BindingIndex, ((StorageBufferHandle)buffer.BufferHandle).Handle); + GL.BindBufferBase(BufferTargetARB.ShaderStorageBuffer, buffer.BindingIndex, ((StorageBufferHandle)buffer.BufferHandle).Handle); } /// @@ -2712,9 +2758,9 @@ public void StorageBufferSetData(IStorageBuffer storageBuffer, T[] data) wher int dataBytes = storageBuffer.Count * storageBuffer.Size; //1. Generate Buffer and or set the data - if (bufferHandle.Handle == -1) + if (bufferHandle.Handle.Handle == -1) { - GL.GenBuffers(1, out bufferHandle.Handle); + bufferHandle.Handle = GL.GenBuffer(); } if (data == null || data.Length == 0) @@ -2722,14 +2768,20 @@ public void StorageBufferSetData(IStorageBuffer storageBuffer, T[] data) wher throw new ArgumentException("Data must not be null or empty"); } - GL.BindBuffer(BufferTarget.ShaderStorageBuffer, bufferHandle.Handle); - GL.BufferData(BufferTarget.ShaderStorageBuffer, dataBytes, data, BufferUsageHint.DynamicCopy); + GL.BindBuffer(BufferTargetARB.ShaderStorageBuffer, bufferHandle.Handle); + + unsafe + { + using var dataMemHandle = data.AsMemory().Pin(); + GL.BufferData(BufferTargetARB.ShaderStorageBuffer, dataBytes, dataMemHandle.Pointer, BufferUsageARB.StaticDraw); + } - GL.GetBufferParameter(BufferTarget.ShaderStorageBuffer, BufferParameterName.BufferSize, out int bufferBytes); + int bufferBytes = 0; + GL.GetBufferParameteri(BufferTargetARB.ShaderStorageBuffer, BufferPNameARB.BufferSize, ref bufferBytes); if (bufferBytes != dataBytes) throw new ApplicationException(string.Format("Problem uploading bone indices buffer to SSBO. Tried to upload {0} bytes, uploaded {1}.", bufferBytes, dataBytes)); - GL.BindBuffer(BufferTarget.ShaderStorageBuffer, 0); + GL.BindBuffer(BufferTargetARB.ShaderStorageBuffer, new BufferHandle(0)); } /// @@ -2756,7 +2808,11 @@ public void DeleteStorageBuffer(IBufferHandle storageBufferHandle) public IImageData GetPixelColor(int x, int y, int w = 1, int h = 1) { ImageData image = ImageData.CreateImage(w, h, ColorUint.Black); - GL.ReadPixels(x, y, w, h, PixelFormat.Rgb, PixelType.UnsignedByte, image.PixelData); + unsafe + { + using var data = image.PixelData.AsMemory().Pin(); + GL.ReadPixels(x, y, w, h, PixelFormat.Bgr, PixelType.UnsignedByte, data.Pointer); + } return image; } @@ -2773,9 +2829,6 @@ public float GetPixelDepth(int x, int y) return depth; } - - - #endregion } } \ No newline at end of file diff --git a/src/Engine/Imp/Graphics/Desktop/ShaderHandleImp.cs b/src/Engine/Imp/Graphics/Desktop/ShaderHandleImp.cs new file mode 100644 index 000000000..50aede537 --- /dev/null +++ b/src/Engine/Imp/Graphics/Desktop/ShaderHandleImp.cs @@ -0,0 +1,13 @@ +using Fusee.Engine.Common; +using OpenTK.Graphics; + +namespace Fusee.Engine.Imp.Graphics.Desktop +{ + /// + /// Implementation of for usage with OpenTK framework. + /// + public class ShaderHandleImp : IShaderHandle + { + internal ProgramHandle Handle; + } +} \ No newline at end of file diff --git a/src/Engine/Imp/Graphics/Desktop/TextureHandle.cs b/src/Engine/Imp/Graphics/Desktop/TextureHandle.cs new file mode 100644 index 000000000..995d6bb42 --- /dev/null +++ b/src/Engine/Imp/Graphics/Desktop/TextureHandle.cs @@ -0,0 +1,14 @@ +using Fusee.Engine.Common; + +namespace Fusee.Engine.Imp.Graphics.Desktop +{ + /// + /// Texture Implementation for OpenTK, an integer value is used as a handle + /// + public class TextureHandle : ITextureHandle + { + public OpenTK.Graphics.TextureHandle TexHandle = new(-1); + public OpenTK.Graphics.FramebufferHandle FrameBufferHandle = new(-1); + public OpenTK.Graphics.RenderbufferHandle DepthRenderBufferHandle = new(-1); + } +} \ No newline at end of file diff --git a/src/Engine/Imp/Graphics/Desktop/TexturePixelInfo.cs b/src/Engine/Imp/Graphics/Desktop/TexturePixelInfo.cs index c9643898e..37101fc88 100644 --- a/src/Engine/Imp/Graphics/Desktop/TexturePixelInfo.cs +++ b/src/Engine/Imp/Graphics/Desktop/TexturePixelInfo.cs @@ -6,7 +6,7 @@ namespace Fusee.Engine.Imp.Graphics.Desktop /// Type that sums up infos about the pixels OpenGl needs to create textures on the gpu. internal struct TexturePixelInfo : ITexturePixelInfo { - public PixelInternalFormat InternalFormat; + public InternalFormat InternalFormat; public PixelFormat Format; public PixelType PxType; public int RowAlignment; diff --git a/src/Engine/Imp/Graphics/Shared/Fusee.Engine.Imp.Graphics.Shared.projitems b/src/Engine/Imp/Graphics/Shared/Fusee.Engine.Imp.Graphics.Shared.projitems index 98fe78419..fff5b89cf 100644 --- a/src/Engine/Imp/Graphics/Shared/Fusee.Engine.Imp.Graphics.Shared.projitems +++ b/src/Engine/Imp/Graphics/Shared/Fusee.Engine.Imp.Graphics.Shared.projitems @@ -9,12 +9,8 @@ Shared - - - - \ No newline at end of file diff --git a/src/ImGui/Desktop/Fusee.ImGui.Desktop/ImGuiController.cs b/src/ImGui/Desktop/Fusee.ImGui.Desktop/ImGuiController.cs index 1bcba6de9..34fe0c36f 100644 --- a/src/ImGui/Desktop/Fusee.ImGui.Desktop/ImGuiController.cs +++ b/src/ImGui/Desktop/Fusee.ImGui.Desktop/ImGuiController.cs @@ -1,7 +1,7 @@ using Fusee.Base.Core; -using Fusee.Engine.Core; using Fusee.Math.Core; using ImGuiNET; +using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; using System; using System.Collections.Generic; @@ -13,10 +13,10 @@ namespace Fusee.ImGuiDesktop { public class ImGuiController { - private static int _vertexArray; - private static int _vertexBuffer; + private static VertexArrayHandle _vertexArray; + private static BufferHandle _vertexBuffer; private static int _vertexBufferSize; - private static int _indexBuffer; + private static BufferHandle _indexBuffer; private static int _indexBufferSize; public int GameWindowWidth; @@ -47,7 +47,7 @@ void main() outputColor = color * texture(in_fontTexture, texCoord); }"; - private static int _shaderProgram; + private static ProgramHandle _shaderProgram; private static readonly Dictionary _uniformVarToLocation = new(); public ImGuiController(int width, int height) => WindowResized(width, height); @@ -99,22 +99,23 @@ private static void CreateDeviceResources() GL.ShaderSource(vertexShader, _vertexSource); GL.CompileShader(vertexShader); - GL.GetShader(vertexShader, ShaderParameter.CompileStatus, out int success); + int success = -1; + GL.GetShaderi(vertexShader, ShaderParameterName.CompileStatus, ref success); if (success == 0) { - string Info = GL.GetShaderInfoLog(vertexShader); - Diagnostics.Error($"GL.CompileShader for shader '{vertexShader}' had info log:\n{Info}"); + GL.GetShaderInfoLog(vertexShader, out var info); + Diagnostics.Error($"GL.CompileShader for shader '{vertexShader}' had info log:\n{info}"); } var pixelShader = GL.CreateShader(ShaderType.FragmentShader); GL.ShaderSource(pixelShader, _fragmentSource); GL.CompileShader(pixelShader); - GL.GetShader(pixelShader, ShaderParameter.CompileStatus, out success); + GL.GetShaderi(pixelShader, ShaderParameterName.CompileStatus, ref success); if (success == 0) { - string Info = GL.GetShaderInfoLog(pixelShader); - Diagnostics.Error($"GL.CompileShader for shader '{pixelShader}' had info log:\n{Info}"); + GL.GetShaderInfoLog(pixelShader, out var info); + Diagnostics.Error($"GL.CompileShader for shader '{pixelShader}' had info log:\n{info}"); } GL.AttachShader(_shaderProgram, vertexShader); @@ -122,12 +123,12 @@ private static void CreateDeviceResources() GL.LinkProgram(_shaderProgram); - GL.GetProgram(_shaderProgram, GetProgramParameterName.LinkStatus, out success); + GL.GetProgrami(_shaderProgram, ProgramPropertyARB.LinkStatus, ref success); if (success == 0) { - string Info = GL.GetProgramInfoLog(_shaderProgram); - Diagnostics.Error($"GL.LinkProgram had info log:\n{Info}"); + GL.GetProgramInfoLog(_shaderProgram, out var info); + Diagnostics.Error($"GL.LinkProgram had info log:\n{info}"); } GL.DetachShader(_shaderProgram, vertexShader); @@ -135,34 +136,40 @@ private static void CreateDeviceResources() GL.DeleteShader(vertexShader); GL.DeleteShader(pixelShader); - GL.GetProgram(_shaderProgram, GetProgramParameterName.ActiveUniforms, out int cnt); + int count = -1; + GL.GetProgrami(_shaderProgram, ProgramPropertyARB.ActiveUniforms, ref count); - for (var i = 0; i < cnt; i++) + for (uint i = 0; i < count; i++) { - var name = GL.GetActiveUniform(_shaderProgram, i, out int Size, out ActiveUniformType Type); + UniformType type = UniformType.Int; + var size = 0; + var length = 0; + + GL.GetActiveUniform(_shaderProgram, i, (int)ProgramInterfacePName.MaxNameLength, ref length, ref size, ref type, out var name); UniformFieldInfo FieldInfo; FieldInfo.Location = GL.GetUniformLocation(_shaderProgram, name); FieldInfo.Name = name; - FieldInfo.Size = Size; - FieldInfo.Type = Type; + FieldInfo.Size = size; + FieldInfo.Type = type; _uniformVarToLocation.Add(name, FieldInfo); } - GL.CreateVertexArrays(1, out _vertexArray); + _vertexArray = GL.CreateVertexArray(); _vertexBufferSize = 10000; _indexBufferSize = 2000; - GL.CreateBuffers(1, out _vertexBuffer); - GL.CreateBuffers(1, out _indexBuffer); - GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBuffer); - GL.BufferData(BufferTarget.ArrayBuffer, _vertexBufferSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); - GL.BindBuffer(BufferTarget.ArrayBuffer, _indexBuffer); - GL.BufferData(BufferTarget.ArrayBuffer, _indexBufferSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); - GL.BindBuffer(BufferTarget.ArrayBuffer, 0); + _vertexBuffer = GL.CreateBuffer(); + _indexBuffer = GL.CreateBuffer(); + + GL.BindBuffer(BufferTargetARB.ArrayBuffer, _vertexBuffer); + GL.BufferData(BufferTargetARB.ArrayBuffer, _vertexBufferSize, IntPtr.Zero, BufferUsageARB.DynamicDraw); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, _indexBuffer); + GL.BufferData(BufferTargetARB.ArrayBuffer, _indexBufferSize, IntPtr.Zero, BufferUsageARB.DynamicDraw); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, new BufferHandle(0)); RecreateFontDeviceTexture(); @@ -193,18 +200,18 @@ private static unsafe void RecreateFontDeviceTexture() ImGuiIOPtr io = ImGui.GetIO(); io.Fonts.GetTexDataAsRGBA32(out IntPtr pixels, out int width, out int height, out int bytesPerPixel); - int id = GL.GenTexture(); - GL.BindTexture(TextureTarget.Texture2D, id); + TextureHandle handle = GL.GenTexture(); + GL.BindTexture(TextureTarget.Texture2d, handle); - GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, pixels); + GL.TexImage2D(TextureTarget.Texture2d, 0, (int)InternalFormat.Rgba, width, height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, pixels); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)OpenTK.Graphics.OpenGL.TextureWrapMode.ClampToEdge); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)OpenTK.Graphics.OpenGL.TextureWrapMode.ClampToEdge); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapR, (int)OpenTK.Graphics.OpenGL.TextureWrapMode.ClampToEdge); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureWrapS, (int)OpenTK.Graphics.OpenGL.TextureWrapMode.ClampToEdge); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureWrapT, (int)OpenTK.Graphics.OpenGL.TextureWrapMode.ClampToEdge); + GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureWrapR, (int)OpenTK.Graphics.OpenGL.TextureWrapMode.ClampToEdge); - io.Fonts.SetTexID(new IntPtr(id)); + io.Fonts.SetTexID(new IntPtr(handle.Handle)); io.Fonts.ClearTexData(); } @@ -253,9 +260,9 @@ internal unsafe void RenderImDrawData(ImDrawDataPtr draw_data) { int newSize = (int)M.Max(_vertexBufferSize * 1.5f, totalVBSize); - GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBuffer); - GL.BufferData(BufferTarget.ArrayBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); - GL.BindBuffer(BufferTarget.ArrayBuffer, 0); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, _vertexBuffer); + GL.BufferData(BufferTargetARB.ArrayBuffer, newSize, IntPtr.Zero, BufferUsageARB.DynamicDraw); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, new BufferHandle(0)); _vertexBufferSize = newSize; @@ -267,9 +274,9 @@ internal unsafe void RenderImDrawData(ImDrawDataPtr draw_data) { int newSize = (int)M.Max(_indexBufferSize * 1.5f, totalIBSize); - GL.BindBuffer(BufferTarget.ArrayBuffer, _indexBuffer); - GL.BufferData(BufferTarget.ArrayBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); - GL.BindBuffer(BufferTarget.ArrayBuffer, 0); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, _indexBuffer); + GL.BufferData(BufferTargetARB.ArrayBuffer, newSize, IntPtr.Zero, BufferUsageARB.DynamicDraw); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, new BufferHandle(0)); _indexBufferSize = newSize; @@ -281,17 +288,17 @@ internal unsafe void RenderImDrawData(ImDrawDataPtr draw_data) { var cmd_list = draw_data.CmdListsRange[i]; - GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBuffer); - GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)(vertexOffsetInVertices * Unsafe.SizeOf()), cmd_list.VtxBuffer.Size * Unsafe.SizeOf(), cmd_list.VtxBuffer.Data); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, _vertexBuffer); + GL.BufferSubData(BufferTargetARB.ArrayBuffer, (IntPtr)(vertexOffsetInVertices * Unsafe.SizeOf()), cmd_list.VtxBuffer.Size * Unsafe.SizeOf(), cmd_list.VtxBuffer.Data); - GL.BindBuffer(BufferTarget.ArrayBuffer, _indexBuffer); - GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)(indexOffsetInElements * sizeof(ushort)), cmd_list.IdxBuffer.Size * sizeof(ushort), cmd_list.IdxBuffer.Data); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, _indexBuffer); + GL.BufferSubData(BufferTargetARB.ArrayBuffer, (IntPtr)(indexOffsetInElements * sizeof(ushort)), cmd_list.IdxBuffer.Size * sizeof(ushort), cmd_list.IdxBuffer.Data); vertexOffsetInVertices += (uint)cmd_list.VtxBuffer.Size; indexOffsetInElements += (uint)cmd_list.IdxBuffer.Size; } - GL.BindBuffer(BufferTarget.ArrayBuffer, 0); + GL.BindBuffer(BufferTargetARB.ArrayBuffer, new BufferHandle(0)); // Setup orthographic projection matrix into our constant buffer ImGuiIOPtr io = ImGui.GetIO(); @@ -306,8 +313,8 @@ internal unsafe void RenderImDrawData(ImDrawDataPtr draw_data) GL.UseProgram(_shaderProgram); // Column order notation - GL.UniformMatrix4(_uniformVarToLocation["projection_matrix"].Location, false, ref mvp); - GL.Uniform1(_uniformVarToLocation["in_fontTexture"].Location, 0); + GL.UniformMatrix4f(_uniformVarToLocation["projection_matrix"].Location, false, in mvp); + GL.Uniform1i(_uniformVarToLocation["in_fontTexture"].Location, 0); GL.BindVertexArray(_vertexArray); @@ -315,7 +322,7 @@ internal unsafe void RenderImDrawData(ImDrawDataPtr draw_data) GL.Enable(EnableCap.Blend); GL.Enable(EnableCap.ScissorTest); - GL.BlendEquation(BlendEquationMode.FuncAdd); + GL.BlendEquation(BlendEquationModeEXT.FuncAdd); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); @@ -337,7 +344,7 @@ internal unsafe void RenderImDrawData(ImDrawDataPtr draw_data) else { GL.ActiveTexture(TextureUnit.Texture0); - GL.BindTexture(TextureTarget.Texture2D, (int)pcmd.TextureId); + GL.BindTexture(TextureTarget.Texture2d, new TextureHandle((int)pcmd.TextureId)); // We do _windowHeight - (int)clip.W instead of (int)clip.Y because gl has flipped Y when it comes to these coordinates var clip = pcmd.ClipRect; diff --git a/src/ImGui/Desktop/Fusee.ImGui.Desktop/ImGuiRenderCanvasImp.cs b/src/ImGui/Desktop/Fusee.ImGui.Desktop/ImGuiRenderCanvasImp.cs index f8d5601fd..a87d01b50 100644 --- a/src/ImGui/Desktop/Fusee.ImGui.Desktop/ImGuiRenderCanvasImp.cs +++ b/src/ImGui/Desktop/Fusee.ImGui.Desktop/ImGuiRenderCanvasImp.cs @@ -1,23 +1,9 @@ using Fusee.Base.Core; using Fusee.Engine.Common; using Fusee.Engine.Core; -using Fusee.Engine.Imp.Graphics.Desktop; -using Fusee.Math.Core; -using ImGuiNET; using OpenTK.Graphics.OpenGL; -using OpenTK.Windowing.Common.Input; using OpenTK.Windowing.Desktop; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing; using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; namespace Fusee.ImGuiDesktop { @@ -26,7 +12,7 @@ struct UniformFieldInfo public int Location; public string Name; public int Size; - public ActiveUniformType Type; + public UniformType Type; } /// @@ -389,7 +375,7 @@ public class RenderCanvasGameWindow : GameWindow /// public bool Blending { - get => GL.IsEnabled(EnableCap.Blend); + get => GL.IsEnabled(EnableCap.Blend) == 0 ? false : true; set { if (value) diff --git a/src/ImGui/Desktop/Fusee.ImGui.Desktop/Templates/FuseeControlToTexture.cs b/src/ImGui/Desktop/Fusee.ImGui.Desktop/Templates/FuseeControlToTexture.cs index b391601d5..4d651156a 100644 --- a/src/ImGui/Desktop/Fusee.ImGui.Desktop/Templates/FuseeControlToTexture.cs +++ b/src/ImGui/Desktop/Fusee.ImGui.Desktop/Templates/FuseeControlToTexture.cs @@ -106,13 +106,13 @@ public IntPtr RenderToTexture(int width, int height) var tex = ((Engine.Imp.Graphics.Desktop.TextureHandle)hndl).TexHandle; // Disable FB, reset size etc. to previous size - GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); - GL.BindTexture(TextureTarget.Texture2D, 0); + GL.BindFramebuffer(FramebufferTarget.Framebuffer, new OpenTK.Graphics.FramebufferHandle(0)); + GL.BindTexture(TextureTarget.Texture2d, new OpenTK.Graphics.TextureHandle(0)); GL.Viewport(0, 0, _originalWidth, _originalHeight); // bind the render result and return ptr to texture - GL.BindTexture(TextureTarget.Texture2D, tex); - return new IntPtr(tex); + GL.BindTexture(TextureTarget.Texture2d, tex); + return new IntPtr(tex.Handle); } }