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

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);
}
}