You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a requirement for me to upgrade o!f-xr to work with arbitrary graphics surfaces (along with some minimal changes to shader managers, but I'll leave that for later). I would like to implement this myself if possible, but I would like to first know your opinion on the details.
The basic idea is that currently (from the public API) we can only create vertex batches, which are essentially a list of raw vertex buffers and a raw element buffer. This is somewhat limiting in terms of how we can render things. o!f-xr currently bypasses IRenderer for this step and creates raw buffers directly with the GL api.
I would like for the public API to add 3 new methods: a way to create a minimally-encapsulated vertex buffer, element buffer and vertex array respectively. This is pretty much a requirement for 3D rendering as we do not wish to re-upload or re-link big meshes every frame using batches. It might also prove useful for 2D rendering given complex shapes (paths, cached batches).
The ideal implementation of this for me would be something like this and nothing more (sample implementation with GL):
{I, GL}Renderer {public CreateRaw{Vertex, Element}Buffer(), CreateRawVertexArray()}
GL{Vertex, Element}Buffer<T>{
internal Handle = GL.GenBuffer();publicBind()=> GL.BindBuffer(...);publicUnbind()=> GL.BindBuffer(...);// no book keeping - the cpu side will not store the uploaded data or its size. This can be done with a wrapper classpublicBuffer(ReadOnlySpan<T> data[, offset, usageHint])=> GL.BufferData(...);publicDispose()=> GL.DeleteBuffer(...);
# VertexBuffer only
public Draw( topology[, offset, count])=> GL.DrawArrays(...);
# ElementBuffer only
// we do not store the topology in the element buffer. This can be done with a wrapper class
public Draw( topology[, offset, count])=> GL.DrawElements(...);}
GLVertexArray {internal Handle = GL.GenVertexArray(); public Bind()=> GL.BindVertexArray(...);
public Unbind()=> GL.BindVertexArray(...);
public Dispose()=> GL.DeleteVertexArray(...);
public LinkElementBuffer( IRawElementBuffer ebo )=> ...;// just binds both since that links an ebo to a vao// binds the vao and vbo, then does stuff with VertexAttribPointer and EnableVertexAttribArray
public LinkVertexBuffer( IRawVertexBuffer vbo[,ReadOnlySpan<int> attributeLayouts])=> ...;}
Please do not look at o!f-xr for how it implements, this, it implements a wrapper around this.
Some considerations for this are:
Binding raw buffers grinds with the batches. We might need to somehow ensure the "draw context" is in correct state, possibly the least invasive way to do this is with debug-only check+exceptions. This would at the very least include making sure no vertex array is bound (I am pretty sure o!f only uses the implicit vertex array)
Should there be a stack of bound buffers, or is this not needed? If not, should we provide a property with the currently bound buffers, so whoever needs a stack-like behaviour can create it on the call stack? Perhaps a using which binds the previous buffer on dispose would be better?
How do we know the layout values for IVertexArray.LinkVertexBuffer? Please note that this cant be derived from the vertex type used as one vertex array might be linked to multiple vertex buffers - I think this issue can be left for later though and is possibly fixed with shader descriptors (or simply knowing the layout of the used shader), which I think are a thing in veldrid? (o!f-xr has explicit descriptors for materials)
I would like for the usage of them to be draw-thread only, meaning we don't need to schedule deleting or creating the handle. We might also want to create basic wrappers which can be accessed on the update thread (for example so we can create shared data) which delegate creation and disposal, or just leave that part to the user
The text was updated successfully, but these errors were encountered:
While Implementing this, I've noticed that only opengl has the concept of a vertex array, and as such I will need to rethink how the vertex layout binding will work in this proposal.
Discussion started on discord
This is a requirement for me to upgrade o!f-xr to work with arbitrary graphics surfaces (along with some minimal changes to shader managers, but I'll leave that for later). I would like to implement this myself if possible, but I would like to first know your opinion on the details.
The basic idea is that currently (from the public API) we can only create vertex batches, which are essentially a list of raw vertex buffers and a raw element buffer. This is somewhat limiting in terms of how we can render things. o!f-xr currently bypasses
IRenderer
for this step and creates raw buffers directly with the GL api.I would like for the public API to add 3 new methods: a way to create a minimally-encapsulated vertex buffer, element buffer and vertex array respectively. This is pretty much a requirement for 3D rendering as we do not wish to re-upload or re-link big meshes every frame using batches. It might also prove useful for 2D rendering given complex shapes (paths, cached batches).
The ideal implementation of this for me would be something like this and nothing more (sample implementation with GL):
Please do not look at o!f-xr for how it implements, this, it implements a wrapper around this.
Some considerations for this are:
using
which binds the previous buffer on dispose would be better?IVertexArray.LinkVertexBuffer
? Please note that this cant be derived from the vertex type used as one vertex array might be linked to multiple vertex buffers - I think this issue can be left for later though and is possibly fixed with shader descriptors (or simply knowing the layout of the used shader), which I think are a thing in veldrid? (o!f-xr has explicit descriptors for materials)The text was updated successfully, but these errors were encountered: