Я пишу свой собственный движок с использованием OpenTK (в основном только привязки OpenGL для C #, gl * становится GL. *), И я собираюсь хранить множество буферов вершин с несколькими тысячами вершин в каждом. Поэтому мне нужен собственный формат вершин, так как Vec3 с числами с плавающей запятой просто займет слишком много места. (Я говорю о миллионах вершин)
Я хочу создать свой собственный формат вершин с помощью этого макета:
Byte 0: Position X
Byte 1: Position Y
Byte 2: Position Z
Byte 3: Texture Coordinate X
Byte 4: Color R
Byte 5: Color G
Byte 6: Color B
Byte 7: Texture Coordinate Y
Вот код на C # для вершины:
public struct SmallBlockVertex
{
public byte PositionX;
public byte PositionY;
public byte PositionZ;
public byte TextureX;
public byte ColorR;
public byte ColorG;
public byte ColorB;
public byte TextureY;
}
Байт в качестве позиции для каждой оси достаточно, так как мне нужно только 32 ^ 3 уникальных позиции.
Я написал свой собственный вершинный шейдер, который принимает два вектора vec4 в качестве входных данных для каждого набора байтов. Мой вершинный шейдер таков:
attribute vec4 pos_data;
attribute vec4 col_data;
uniform mat4 projection_mat;
uniform mat4 view_mat;
uniform mat4 world_mat;
void main()
{
vec4 position = pos_data * vec4(1.0, 1.0, 1.0, 0.0);
gl_Position = projection_mat * view_mat * world_mat * position;
}
Чтобы попытаться изолировать проблему, я сделал свой вершинный шейдер максимально простым. Код для компиляции шейдеров протестирован в режиме немедленного рисования, и он работает, так что этого быть не может.
Вот моя функция, которая генерирует, настраивает и заполняет буфер вершин данными и устанавливает указатель на атрибуты.
public void SetData<VertexType>(VertexType[] vertices, int vertexSize) where VertexType : struct
{
GL.GenVertexArrays(1, out ArrayID);
GL.BindVertexArray(ArrayID);
GL.GenBuffers(1, out ID);
GL.BindBuffer(BufferTarget.ArrayBuffer, ID);
GL.BufferData<VertexType>(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * vertexSize), vertices, BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(Shaders.PositionDataID, 4, VertexAttribPointerType.UnsignedByte, false, 4, 0);
GL.VertexAttribPointer(Shaders.ColorDataID, 4, VertexAttribPointerType.UnsignedByte, false, 4, 4);
}
Насколько я понимаю, это правильная процедура для: создания объекта массива вершин и его привязки; создания буфера вершин и его привязки; заполнения буфера вершин данными; установки указателей атрибутов.
Шейдеры. * DataID устанавливается с помощью этого кода после компиляции и использования шейдера.
PositionDataID = GL.GetAttribLocation(shaderProgram, "pos_data");
ColorDataID = GL.GetAttribLocation(shaderProgram, "col_data");
А это моя функция рендеринга:
void Render()
{
GL.UseProgram(Shaders.ChunkShaderProgram);
Matrix4 view = Constants.Engine_Physics.Player.ViewMatrix;
GL.UniformMatrix4(Shaders.ViewMatrixID, false, ref view);
//GL.Enable(EnableCap.DepthTest);
//GL.Enable(EnableCap.CullFace);
GL.EnableClientState(ArrayCap.VertexArray);
{
Matrix4 world = Matrix4.CreateTranslation(offset.Position);
GL.UniformMatrix4(Shaders.WorldMatrixID, false, ref world);
GL.BindVertexArray(ArrayID);
GL.BindBuffer(OpenTK.Graphics.OpenGL.BufferTarget.ArrayBuffer, ID);
GL.DrawArrays(OpenTK.Graphics.OpenGL.BeginMode.Quads, 0, Count / 4);
}
//GL.Disable(EnableCap.DepthTest);
//GL.Disable(EnableCap.CullFace);
GL.DisableClientState(ArrayCap.VertexArray);
GL.Flush();
}
Может ли кто-нибудь быть так любезен, чтобы дать мне несколько указателей (без каламбура)? Я делаю это в неправильном порядке или мне нужно вызвать какие-то функции?
Я поискал по всей сети, но не нашел ни одного хорошего учебника или руководства, объясняющего, как реализовать собственные вершины. Если вам нужна дополнительная информация, сообщите об этом.