forked from mirror/DotRecast
Update ModernOpenGLDraw.cs
(cherry picked from commit 6fb44cc3ce47be2c724d6093ef4b3168aacf9480)
This commit is contained in:
parent
7ffda46c2f
commit
ab04256cdf
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using DotRecast.Core;
|
using DotRecast.Core;
|
||||||
|
|
||||||
namespace DotRecast.Recast.Demo.Draw;
|
namespace DotRecast.Recast.Demo.Draw;
|
||||||
|
@ -9,19 +9,19 @@ public class ArrayBuffer<T>
|
||||||
private T[] _items;
|
private T[] _items;
|
||||||
public int Count => _size;
|
public int Count => _size;
|
||||||
|
|
||||||
public ArrayBuffer()
|
public ArrayBuffer() : this(512) { }
|
||||||
|
|
||||||
|
public ArrayBuffer(int capacity)
|
||||||
{
|
{
|
||||||
|
if (capacity <= 0)
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
|
||||||
_size = 0;
|
_size = 0;
|
||||||
_items = Array.Empty<T>();
|
_items = new T[capacity];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(T item)
|
public void Add(T item)
|
||||||
{
|
{
|
||||||
if (0 >= _items.Length)
|
|
||||||
{
|
|
||||||
_items = new T[256];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_items.Length <= _size)
|
if (_items.Length <= _size)
|
||||||
{
|
{
|
||||||
var temp = new T[(int)(_size * 1.5)];
|
var temp = new T[(int)(_size * 1.5)];
|
||||||
|
@ -37,8 +37,8 @@ public class ArrayBuffer<T>
|
||||||
_size = 0;
|
_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T[] AsArray()
|
public Span<T> AsArray()
|
||||||
{
|
{
|
||||||
return _items;
|
return _items.AsSpan(0, _size);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System.Numerics;
|
||||||
using DotRecast.Core.Numerics;
|
using DotRecast.Core.Numerics;
|
||||||
|
|
||||||
namespace DotRecast.Recast.Demo.Draw;
|
namespace DotRecast.Recast.Demo.Draw;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
|
||||||
using Silk.NET.OpenGL;
|
using Silk.NET.OpenGL;
|
||||||
using DotRecast.Core.Numerics;
|
using DotRecast.Core.Numerics;
|
||||||
|
|
||||||
namespace DotRecast.Recast.Demo.Draw;
|
namespace DotRecast.Recast.Demo.Draw;
|
||||||
|
|
||||||
|
// TODO use a lot of Memory, 2GB+
|
||||||
|
|
||||||
public class ModernOpenGLDraw : IOpenGLDraw
|
public class ModernOpenGLDraw : IOpenGLDraw
|
||||||
{
|
{
|
||||||
private GL _gl;
|
private GL _gl;
|
||||||
|
@ -19,8 +20,8 @@ public class ModernOpenGLDraw : IOpenGLDraw
|
||||||
private float fogEnd;
|
private float fogEnd;
|
||||||
private bool fogEnabled;
|
private bool fogEnabled;
|
||||||
private int uniformViewMatrix;
|
private int uniformViewMatrix;
|
||||||
private readonly ArrayBuffer<OpenGLVertex> vertices = new();
|
private readonly ArrayBuffer<OpenGLVertex> vertices = new(512);
|
||||||
private readonly ArrayBuffer<int> elements = new();
|
private readonly ArrayBuffer<int> elements = new(512);
|
||||||
private GLCheckerTexture _texture;
|
private GLCheckerTexture _texture;
|
||||||
private readonly float[] _viewMatrix = new float[16];
|
private readonly float[] _viewMatrix = new float[16];
|
||||||
private readonly float[] _projectionMatrix = new float[16];
|
private readonly float[] _projectionMatrix = new float[16];
|
||||||
|
@ -36,36 +37,42 @@ public class ModernOpenGLDraw : IOpenGLDraw
|
||||||
|
|
||||||
public unsafe void Init()
|
public unsafe void Init()
|
||||||
{
|
{
|
||||||
string SHADER_VERSION = "#version 400\n";
|
const string SHADER_VERSION = "#version 400\n";
|
||||||
string vertex_shader = SHADER_VERSION + "uniform mat4 ProjMtx;\n" //
|
const string vertex_shader = $@"
|
||||||
+ "uniform mat4 ViewMtx;\n" //
|
{SHADER_VERSION}
|
||||||
+ "in vec3 Position;\n" //
|
uniform mat4 ProjMtx;
|
||||||
+ "in vec2 TexCoord;\n" //
|
uniform mat4 ViewMtx;
|
||||||
+ "in vec4 Color;\n" //
|
in vec3 Position;
|
||||||
+ "out vec2 Frag_UV;\n" //
|
in vec2 TexCoord;
|
||||||
+ "out vec4 Frag_Color;\n" //
|
in vec4 Color;
|
||||||
+ "out float Frag_Depth;\n" //
|
out vec2 Frag_UV;
|
||||||
+ "void main() {\n" //
|
out vec4 Frag_Color;
|
||||||
+ " Frag_UV = TexCoord;\n" //
|
out float Frag_Depth;
|
||||||
+ " Frag_Color = Color;\n" //
|
void main() {{
|
||||||
+ " vec4 VSPosition = ViewMtx * vec4(Position, 1);\n" //
|
Frag_UV = TexCoord;
|
||||||
+ " Frag_Depth = -VSPosition.z;\n" //
|
Frag_Color = Color;
|
||||||
+ " gl_Position = ProjMtx * VSPosition;\n" //
|
vec4 VSPosition = ViewMtx * vec4(Position, 1);
|
||||||
+ "}\n";
|
Frag_Depth = -VSPosition.z;
|
||||||
string fragment_shader = SHADER_VERSION + "precision mediump float;\n" //
|
gl_Position = ProjMtx * VSPosition;
|
||||||
+ "uniform sampler2D Texture;\n" //
|
}}
|
||||||
+ "uniform float UseTexture;\n" //
|
";
|
||||||
+ "uniform float EnableFog;\n" //
|
const string fragment_shader = $@"
|
||||||
+ "uniform float FogStart;\n" //
|
{SHADER_VERSION}
|
||||||
+ "uniform float FogEnd;\n" //
|
precision mediump float;
|
||||||
+ "const vec4 FogColor = vec4(0.3f, 0.3f, 0.32f, 1.0f);\n" //
|
uniform sampler2D Texture;
|
||||||
+ "in vec2 Frag_UV;\n" //
|
uniform float UseTexture;
|
||||||
+ "in vec4 Frag_Color;\n" //
|
uniform float EnableFog;
|
||||||
+ "in float Frag_Depth;\n" //
|
uniform float FogStart;
|
||||||
+ "out vec4 Out_Color;\n" //
|
uniform float FogEnd;
|
||||||
+ "void main(){\n" //
|
const vec4 FogColor = vec4(0.3f, 0.3f, 0.32f, 1.0f);
|
||||||
+ " 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" //
|
in vec2 Frag_UV;
|
||||||
+ "}\n";
|
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();
|
program = _gl.CreateProgram();
|
||||||
uint vert_shdr = _gl.CreateShader(GLEnum.VertexShader);
|
uint vert_shdr = _gl.CreateShader(GLEnum.VertexShader);
|
||||||
|
@ -150,6 +157,10 @@ public class ModernOpenGLDraw : IOpenGLDraw
|
||||||
_gl.BindVertexArray(0);
|
_gl.BindVertexArray(0);
|
||||||
_gl.BindBuffer(GLEnum.ArrayBuffer, 0);
|
_gl.BindBuffer(GLEnum.ArrayBuffer, 0);
|
||||||
_gl.BindBuffer(GLEnum.ElementArrayBuffer, 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()
|
public void Clear()
|
||||||
|
@ -191,35 +202,18 @@ public class ModernOpenGLDraw : IOpenGLDraw
|
||||||
// GlBufferData(GL_ARRAY_BUFFER, MAX_VERTEX_BUFFER, GL_STREAM_DRAW);
|
// GlBufferData(GL_ARRAY_BUFFER, MAX_VERTEX_BUFFER, GL_STREAM_DRAW);
|
||||||
// GlBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_ELEMENT_BUFFER, GL_STREAM_DRAW);
|
// GlBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_ELEMENT_BUFFER, GL_STREAM_DRAW);
|
||||||
|
|
||||||
uint vboSize = (uint)vertices.Count * 24;
|
_gl.BufferData<OpenGLVertex>(GLEnum.ArrayBuffer, vertices.AsArray(), GLEnum.DynamicDraw);
|
||||||
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
|
|
||||||
|
|
||||||
{
|
|
||||||
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())
|
|
||||||
{
|
|
||||||
System.Buffer.MemoryCopy(v, pVerts, vboSize, vboSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentPrim == DebugDrawPrimitives.QUADS)
|
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)
|
for (int i = 0; i < vertices.Count; i += 4)
|
||||||
{
|
{
|
||||||
bw.Write(i);
|
elements.Add(i);
|
||||||
bw.Write(i + 1);
|
elements.Add(i + 1);
|
||||||
bw.Write(i + 2);
|
elements.Add(i + 2);
|
||||||
bw.Write(i);
|
elements.Add(i);
|
||||||
bw.Write(i + 2);
|
elements.Add(i + 2);
|
||||||
bw.Write(i + 3);
|
elements.Add(i + 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -228,16 +222,10 @@ public class ModernOpenGLDraw : IOpenGLDraw
|
||||||
{
|
{
|
||||||
elements.Add(i);
|
elements.Add(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed (void* e = elements.AsArray())
|
|
||||||
{
|
|
||||||
System.Buffer.MemoryCopy(e, pElems, eboSize, eboSize);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_gl.UnmapBuffer(GLEnum.ElementArrayBuffer);
|
_gl.BufferData<int>(GLEnum.ElementArrayBuffer, elements.AsArray(), GLEnum.DynamicDraw);
|
||||||
_gl.UnmapBuffer(GLEnum.ArrayBuffer);
|
|
||||||
}
|
|
||||||
if (_texture != null)
|
if (_texture != null)
|
||||||
{
|
{
|
||||||
_texture.Bind();
|
_texture.Bind();
|
||||||
|
@ -271,15 +259,22 @@ public class ModernOpenGLDraw : IOpenGLDraw
|
||||||
_gl.BindBuffer(GLEnum.ArrayBuffer, 0);
|
_gl.BindBuffer(GLEnum.ArrayBuffer, 0);
|
||||||
_gl.BindBuffer(GLEnum.ElementArrayBuffer, 0);
|
_gl.BindBuffer(GLEnum.ElementArrayBuffer, 0);
|
||||||
vertices.Clear();
|
vertices.Clear();
|
||||||
|
elements.Clear();
|
||||||
_gl.LineWidth(1.0f);
|
_gl.LineWidth(1.0f);
|
||||||
_gl.PointSize(1.0f);
|
_gl.PointSize(1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Vertex(float x, float y, float z, int color)
|
public void Vertex(float x, float y, float z, int color)
|
||||||
{
|
{
|
||||||
vertices.Add(new OpenGLVertex(x, y, z, 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)
|
public void Vertex(float[] pos, int color)
|
||||||
{
|
{
|
||||||
vertices.Add(new OpenGLVertex(pos, color));
|
vertices.Add(new OpenGLVertex(pos, color));
|
||||||
|
|
Loading…
Reference in New Issue