You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
3.6 KiB
104 lines
3.6 KiB
using System; |
|
using gaemstone.ECS; |
|
using Silk.NET.Maths; |
|
using Silk.NET.OpenGL; |
|
using ModelRoot = SharpGLTF.Schema2.ModelRoot; |
|
|
|
namespace gaemstone.Client; |
|
|
|
public static class MeshManager |
|
{ |
|
const uint PositionAttribIndex = 0; |
|
const uint NormalAttribIndex = 1; |
|
const uint UvAttribIndex = 2; |
|
|
|
public static Mesh Load(Universe universe, string name) |
|
{ |
|
ModelRoot root; |
|
using (var stream = Resources.GetStream(name)) |
|
root = ModelRoot.ReadGLB(stream, new()); |
|
var primitive = root.LogicalMeshes[0].Primitives[0]; |
|
|
|
var indices = primitive.IndexAccessor; |
|
var vertices = primitive.VertexAccessors["POSITION"]; |
|
var normals = primitive.VertexAccessors["NORMAL"]; |
|
|
|
var GL = universe.Lookup<Game>().Get<Windowing.Canvas>().GL; |
|
var vao = GL.GenVertexArray(); |
|
GL.BindVertexArray(vao); |
|
|
|
GL.CreateBufferFromData(indices.SourceBufferView.Content, |
|
BufferTargetARB.ElementArrayBuffer); |
|
|
|
GL.CreateBufferFromData(vertices.SourceBufferView.Content); |
|
GL.EnableVertexAttribArray(PositionAttribIndex); |
|
unsafe { GL.VertexAttribPointer(PositionAttribIndex, 3, |
|
(VertexAttribPointerType)vertices.Encoding, vertices.Normalized, |
|
(uint)vertices.SourceBufferView.ByteStride, (void*)vertices.ByteOffset); } |
|
|
|
GL.CreateBufferFromData(normals.SourceBufferView.Content); |
|
GL.EnableVertexAttribArray(NormalAttribIndex); |
|
unsafe { GL.VertexAttribPointer(NormalAttribIndex, 3, |
|
(VertexAttribPointerType)vertices.Encoding, vertices.Normalized, |
|
(uint)vertices.SourceBufferView.ByteStride, (void*)vertices.ByteOffset); } |
|
|
|
var numVertices = primitive.IndexAccessor.Count; |
|
return new(vao, numVertices); |
|
} |
|
|
|
public static Mesh Create(Universe universe, |
|
ReadOnlySpan<ushort> indices, ReadOnlySpan<Vector3D<float>> vertices, |
|
ReadOnlySpan<Vector3D<float>> normals, ReadOnlySpan<Vector2D<float>> uvs) |
|
{ |
|
var GL = universe.Lookup<Game>().Get<Windowing.Canvas>().GL; |
|
var vao = GL.GenVertexArray(); |
|
GL.BindVertexArray(vao); |
|
|
|
GL.CreateBufferFromData(indices, BufferTargetARB.ElementArrayBuffer); |
|
GL.CreateBufferFromData(vertices); |
|
GL.EnableVertexAttribArray(PositionAttribIndex); |
|
unsafe { GL.VertexAttribPointer(PositionAttribIndex, 3, |
|
VertexAttribPointerType.Float, false, 0, (void*)0); } |
|
if (!normals.IsEmpty) { |
|
GL.CreateBufferFromData(normals); |
|
GL.EnableVertexAttribArray(NormalAttribIndex); |
|
unsafe { GL.VertexAttribPointer(NormalAttribIndex, 3, |
|
VertexAttribPointerType.Float, false, 0, (void*)0); } |
|
} |
|
if (!uvs.IsEmpty) { |
|
GL.CreateBufferFromData(uvs); |
|
GL.EnableVertexAttribArray(UvAttribIndex); |
|
unsafe { GL.VertexAttribPointer(UvAttribIndex, 2, |
|
VertexAttribPointerType.Float, false, 0, (void*)0); } |
|
} |
|
|
|
return new(vao, indices.Length); |
|
} |
|
|
|
public static Mesh Create(Universe universe, ReadOnlySpan<Vector3D<float>> vertices, |
|
ReadOnlySpan<Vector3D<float>> normals, ReadOnlySpan<Vector2D<float>> uvs) |
|
{ |
|
var GL = universe.Lookup<Game>().Get<Windowing.Canvas>().GL; |
|
var vao = GL.GenVertexArray(); |
|
GL.BindVertexArray(vao); |
|
|
|
GL.CreateBufferFromData(vertices); |
|
GL.EnableVertexAttribArray(PositionAttribIndex); |
|
unsafe { GL.VertexAttribPointer(PositionAttribIndex, 3, |
|
VertexAttribPointerType.Float, false, 0, (void*)0); } |
|
if (!normals.IsEmpty) { |
|
GL.CreateBufferFromData(normals); |
|
GL.EnableVertexAttribArray(NormalAttribIndex); |
|
unsafe { GL.VertexAttribPointer(NormalAttribIndex, 3, |
|
VertexAttribPointerType.Float, false, 0, (void*)0); } |
|
} |
|
if (!uvs.IsEmpty) { |
|
GL.CreateBufferFromData(uvs); |
|
GL.EnableVertexAttribArray(UvAttribIndex); |
|
unsafe { GL.VertexAttribPointer(UvAttribIndex, 2, |
|
VertexAttribPointerType.Float, false, 0, (void*)0); } |
|
} |
|
|
|
return new(vao, vertices.Length, false); |
|
} |
|
}
|
|
|