Milengine is just yet another OpenGL "retro style" renderer/engine implementation. Futhermore the project started as a small learning project, which should not reach more then 1000 lines of code. However I found out, that it is not possible to deploy easy to use engine, which would not act as a higher layer of OpenGL bindings.
Currently every implementation is not going to stay as it is... The only file which is probably not going to be changed is InlineParameter.cs.
Recently, I have been trying to find and also fix, rendering artefacts, which always appears from the center point of specific collection of meshes.
Everything happened on this specific line Model.cs - Line:51.
GraphicsContext.Graphics.DrawArrays(GraphicsContext.Global.CurrentRenderingType, 0, (uint)Meshes.Span[i].Indices.Buffer.Length);
In a short sentence, this method invokes to OpenGL, which calls to draw multiple combinations of geometric data(Vertex, Normal, Texture coordinate, or color), in a one API call. Although, it may sound as a ideal solution, you must provide those geometric data in a certain offset as a one big allocated block of memory. So in some situations, when you are writing your own parser for individual format type, you would be limited, of how you are going to save geometric data.
If you want more information about this API call, you could found it on khronos OpenGL documentation.
What caused the issue ? Well... for rendering Models from Obj format, I specified VertexFormatType
, which basically says order, of how the format parser is going to separate data.
protected override ImmutableArray<VertexFormatToken> vertexTokens { get; } = [
new VertexFormatToken("v ", VerticesType.Position),
new VertexFormatToken("vt ", VerticesType.Texture),
new VertexFormatToken("vn ", VerticesType.Color),
new VertexFormatToken("f ", VerticesType.FacesInternal)
];
For now, we could say that new VertexFormatToken("f ", VerticesType.FacesInternal)
is irrelevant. What we could dedicate is, that our obj
parser could handle three geometric data. So our indicies must do the same...
Warning
Indicies are containing three different sets of indexes. [1, 1, 1] - [1, 1, 2] - [1, 2, 1]
Back to the problematic line - GraphicsContext.Graphics.DrawArrays(GraphicsContext.Global.CurrentRenderingType, 0, (uint)Meshes.Span[i].Indices.Buffer.Length);
, parameters of this method are...
GLEnum
mode - Flag to set spesific type of buffer rendering.int
first - Defines the starting index.uint
count - Defines the number of indicies, which are going to be rendered.
Have you found it ? The uint
count, which I set as a (uint)Meshes.Span[i].Indices.Buffer.Length
is not correct, because it is a count of all three types of geometric data. So... what ended up as a result, was a block of memory containing count that overflows actual count of geometric data(Vertex, Normal, Texture coordinate, or color).
Important
The count means, specific number of geometric data in memory block and not count of all indexes...
Buffer: [1, 1, 1] - [1, 1, 2] - [1, 2, 1]
- Bad count:
buffer.Length
= 9 - Correct count:
buffer.Length / 3
= 3
GraphicsContext.Graphics.DrawArrays(GraphicsContext.Global.CurrentRenderingType, 0, (uint)Meshes.Span[i].Indices.Buffer.Length / 3);