From ab04256cdffcc6582056670f79347f30aa36d816 Mon Sep 17 00:00:00 2001 From: Sarofc Date: Sat, 6 Jul 2024 20:44:49 +0800 Subject: [PATCH] Update ModernOpenGLDraw.cs (cherry picked from commit 6fb44cc3ce47be2c724d6093ef4b3168aacf9480) --- src/DotRecast.Recast.Demo/Draw/ArrayBuffer.cs | 20 +-- src/DotRecast.Recast.Demo/Draw/IOpenGLDraw.cs | 1 + .../Draw/ModernOpenGLDraw.cs | 145 +++++++++--------- 3 files changed, 81 insertions(+), 85 deletions(-) diff --git a/src/DotRecast.Recast.Demo/Draw/ArrayBuffer.cs b/src/DotRecast.Recast.Demo/Draw/ArrayBuffer.cs index 3002693..59ad39f 100644 --- a/src/DotRecast.Recast.Demo/Draw/ArrayBuffer.cs +++ b/src/DotRecast.Recast.Demo/Draw/ArrayBuffer.cs @@ -1,4 +1,4 @@ -using System; +using System; using DotRecast.Core; namespace DotRecast.Recast.Demo.Draw; @@ -9,19 +9,19 @@ public class ArrayBuffer private T[] _items; public int Count => _size; - public ArrayBuffer() + public ArrayBuffer() : this(512) { } + + public ArrayBuffer(int capacity) { + if (capacity <= 0) + throw new ArgumentOutOfRangeException(); + _size = 0; - _items = Array.Empty(); + _items = new T[capacity]; } public void Add(T item) { - if (0 >= _items.Length) - { - _items = new T[256]; - } - if (_items.Length <= _size) { var temp = new T[(int)(_size * 1.5)]; @@ -37,8 +37,8 @@ public class ArrayBuffer _size = 0; } - public T[] AsArray() + public Span AsArray() { - return _items; + return _items.AsSpan(0, _size); } } \ No newline at end of file diff --git a/src/DotRecast.Recast.Demo/Draw/IOpenGLDraw.cs b/src/DotRecast.Recast.Demo/Draw/IOpenGLDraw.cs index 0558c41..8086962 100644 --- a/src/DotRecast.Recast.Demo/Draw/IOpenGLDraw.cs +++ b/src/DotRecast.Recast.Demo/Draw/IOpenGLDraw.cs @@ -1,3 +1,4 @@ +using System.Numerics; using DotRecast.Core.Numerics; namespace DotRecast.Recast.Demo.Draw; diff --git a/src/DotRecast.Recast.Demo/Draw/ModernOpenGLDraw.cs b/src/DotRecast.Recast.Demo/Draw/ModernOpenGLDraw.cs index 8ca2ed6..d850f9e 100644 --- a/src/DotRecast.Recast.Demo/Draw/ModernOpenGLDraw.cs +++ b/src/DotRecast.Recast.Demo/Draw/ModernOpenGLDraw.cs @@ -1,10 +1,11 @@ using System; -using System.IO; using Silk.NET.OpenGL; using DotRecast.Core.Numerics; namespace DotRecast.Recast.Demo.Draw; +// TODO use a lot of Memory, 2GB+ + public class ModernOpenGLDraw : IOpenGLDraw { private GL _gl; @@ -19,8 +20,8 @@ public class ModernOpenGLDraw : IOpenGLDraw private float fogEnd; private bool fogEnabled; private int uniformViewMatrix; - private readonly ArrayBuffer vertices = new(); - private readonly ArrayBuffer elements = new(); + private readonly ArrayBuffer vertices = new(512); + private readonly ArrayBuffer elements = new(512); private GLCheckerTexture _texture; private readonly float[] _viewMatrix = new float[16]; private readonly float[] _projectionMatrix = new float[16]; @@ -36,36 +37,42 @@ public class ModernOpenGLDraw : IOpenGLDraw public unsafe void Init() { - string SHADER_VERSION = "#version 400\n"; - string vertex_shader = SHADER_VERSION + "uniform mat4 ProjMtx;\n" // - + "uniform mat4 ViewMtx;\n" // - + "in vec3 Position;\n" // - + "in vec2 TexCoord;\n" // - + "in vec4 Color;\n" // - + "out vec2 Frag_UV;\n" // - + "out vec4 Frag_Color;\n" // - + "out float Frag_Depth;\n" // - + "void main() {\n" // - + " Frag_UV = TexCoord;\n" // - + " Frag_Color = Color;\n" // - + " vec4 VSPosition = ViewMtx * vec4(Position, 1);\n" // - + " Frag_Depth = -VSPosition.z;\n" // - + " gl_Position = ProjMtx * VSPosition;\n" // - + "}\n"; - string fragment_shader = SHADER_VERSION + "precision mediump float;\n" // - + "uniform sampler2D Texture;\n" // - + "uniform float UseTexture;\n" // - + "uniform float EnableFog;\n" // - + "uniform float FogStart;\n" // - + "uniform float FogEnd;\n" // - + "const vec4 FogColor = vec4(0.3f, 0.3f, 0.32f, 1.0f);\n" // - + "in vec2 Frag_UV;\n" // - + "in vec4 Frag_Color;\n" // - + "in float Frag_Depth;\n" // - + "out vec4 Out_Color;\n" // - + "void main(){\n" // - + " Out_Color = mix(FogColor, Frag_Color * mix(vec4(1), texture(Texture, Frag_UV.st), UseTexture), 1.0 - EnableFog * clamp( (Frag_Depth - FogStart) / (FogEnd - FogStart), 0.0, 1.0) );\n" // - + "}\n"; + const string SHADER_VERSION = "#version 400\n"; + const string vertex_shader = $@" +{SHADER_VERSION} +uniform mat4 ProjMtx; +uniform mat4 ViewMtx; +in vec3 Position; +in vec2 TexCoord; +in vec4 Color; +out vec2 Frag_UV; +out vec4 Frag_Color; +out float Frag_Depth; +void main() {{ + Frag_UV = TexCoord; + Frag_Color = Color; + vec4 VSPosition = ViewMtx * vec4(Position, 1); + Frag_Depth = -VSPosition.z; + gl_Position = ProjMtx * VSPosition; +}} +"; + const string fragment_shader = $@" +{SHADER_VERSION} +precision mediump float; +uniform sampler2D Texture; +uniform float UseTexture; +uniform float EnableFog; +uniform float FogStart; +uniform float FogEnd; +const vec4 FogColor = vec4(0.3f, 0.3f, 0.32f, 1.0f); +in vec2 Frag_UV; +in vec4 Frag_Color; +in float Frag_Depth; +out vec4 Out_Color; +void main(){{ + Out_Color = mix(FogColor, Frag_Color * mix(vec4(1), texture(Texture, Frag_UV.st), UseTexture), 1.0 - EnableFog * clamp( (Frag_Depth - FogStart) / (FogEnd - FogStart), 0.0, 1.0) ); +}} +"; program = _gl.CreateProgram(); uint vert_shdr = _gl.CreateShader(GLEnum.VertexShader); @@ -150,6 +157,10 @@ public class ModernOpenGLDraw : IOpenGLDraw _gl.BindVertexArray(0); _gl.BindBuffer(GLEnum.ArrayBuffer, 0); _gl.BindBuffer(GLEnum.ElementArrayBuffer, 0); + + //int* range = stackalloc int[2]; + //_gl.GetInteger(GetPName.LineWidthRange, range); + //Console.WriteLine($"\nLineWidthRange: {range[0]} {range[1]}"); } public void Clear() @@ -191,53 +202,30 @@ public class ModernOpenGLDraw : IOpenGLDraw // GlBufferData(GL_ARRAY_BUFFER, MAX_VERTEX_BUFFER, GL_STREAM_DRAW); // GlBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_ELEMENT_BUFFER, GL_STREAM_DRAW); - uint vboSize = (uint)vertices.Count * 24; - uint eboSize = currentPrim == DebugDrawPrimitives.QUADS ? (uint)vertices.Count * 6 : (uint)vertices.Count * 4; - - _gl.BufferData(GLEnum.ArrayBuffer, vboSize, null, GLEnum.StreamDraw); - _gl.BufferData(GLEnum.ElementArrayBuffer, eboSize, null, GLEnum.StreamDraw); - // load draw vertices & elements directly into vertex + element buffer + _gl.BufferData(GLEnum.ArrayBuffer, vertices.AsArray(), GLEnum.DynamicDraw); + if (currentPrim == DebugDrawPrimitives.QUADS) { - byte* pVerts = (byte*)_gl.MapBuffer(GLEnum.ArrayBuffer, GLEnum.WriteOnly); - byte* pElems = (byte*)_gl.MapBuffer(GLEnum.ElementArrayBuffer, GLEnum.WriteOnly); - - //vertices.ForEach(v => v.Store(verts)); - fixed (void* v = vertices.AsArray()) + for (int i = 0; i < vertices.Count; i += 4) { - System.Buffer.MemoryCopy(v, pVerts, vboSize, vboSize); + elements.Add(i); + elements.Add(i + 1); + elements.Add(i + 2); + elements.Add(i); + elements.Add(i + 2); + elements.Add(i + 3); } - - if (currentPrim == DebugDrawPrimitives.QUADS) - { - using var unmanagedElems = new UnmanagedMemoryStream(pElems, eboSize, eboSize, FileAccess.Write); - using var bw = new BinaryWriter(unmanagedElems); - for (int i = 0; i < vertices.Count; i += 4) - { - bw.Write(i); - bw.Write(i + 1); - bw.Write(i + 2); - bw.Write(i); - bw.Write(i + 2); - bw.Write(i + 3); - } - } - else - { - for (int i = elements.Count; i < vertices.Count; i++) - { - elements.Add(i); - } - - fixed (void* e = elements.AsArray()) - { - System.Buffer.MemoryCopy(e, pElems, eboSize, eboSize); - } - } - - _gl.UnmapBuffer(GLEnum.ElementArrayBuffer); - _gl.UnmapBuffer(GLEnum.ArrayBuffer); } + else + { + for (int i = elements.Count; i < vertices.Count; i++) + { + elements.Add(i); + } + } + + _gl.BufferData(GLEnum.ElementArrayBuffer, elements.AsArray(), GLEnum.DynamicDraw); + if (_texture != null) { _texture.Bind(); @@ -271,15 +259,22 @@ public class ModernOpenGLDraw : IOpenGLDraw _gl.BindBuffer(GLEnum.ArrayBuffer, 0); _gl.BindBuffer(GLEnum.ElementArrayBuffer, 0); vertices.Clear(); + elements.Clear(); _gl.LineWidth(1.0f); _gl.PointSize(1.0f); } + public void Vertex(float x, float y, float z, int color) { vertices.Add(new OpenGLVertex(x, y, z, color)); } + public unsafe void Vertex(float* pos, int color) + { + vertices.Add(new OpenGLVertex(pos[0], pos[1], pos[2], color)); + } + public void Vertex(float[] pos, int color) { vertices.Add(new OpenGLVertex(pos, color));