Hi,
I use
let (vertex_buffer, slice) = self.factory.create_vertex_buffer_with_slice(&self.vec_pos_color_uv_data, &*self.ind_data);
to create vertex buffer and indices slice. Do I need to call this function every frame when my data changes or is there another way to update vertex buffer and indices slice?
I noticed that my log is printing: Created buffer 4545, Created buffer 4546... when I do this every frame.
Thanks.
Hello!
Vertex buffers are stored in GPU memory, so you don't need to create them every frame.
You can use update_buffer function to upload new info in your buffer.
Usually there's no need in changing slice (if you have the same number of elements)
Hi.
I use the following code
if !self.buffers_created
{
let (vertex_buffer, slice) = self.factory.create_vertex_buffer_with_slice(&self.vec_pos_color_uv_data, &*self.ind_data);
self.slice = slice;
self.pos_color_uv_data.vbuf = vertex_buffer;
self.buffers_created = true;
}
else
{
let ok = self.encoder.update_buffer(&self.pos_color_uv_data.vbuf, &self.vec_pos_color_uv_data, 0);
match ok
{
Ok(_) =>
{
self.encoder.draw(&self.slice, &self.pso2, &self.pos_color_uv_data);
},
Err(err) =>
{
println!("{:?}", err);
}
}
}
self.encoder.draw(&self.slice, &self.pso2, &self.pos_color_uv_data);
But it doesn't work. Update_buffer functions returns error _InvalidUsage(Data)_. I should probably change buffer Usage to Dynamic but I don't know how to do that.
The code works if I use only the top part.
You can also manually assemble the vertex buffers and index buffers/slices. create_vertex_buffer_with_slice is a high level helper function (static mesh, mostly). But for more specific use-cases the lower level functions can be called as seen in the implementation, allowing more control.
Can you point me to some tutorials or examples. I'm having a hard time finding them on internet.
I'm afraid, we don't have much in-depth tutorials at the moment.
With implementation, I meant this part right here: https://github.com/gfx-rs/gfx/blob/pre-ll/src/render/src/factory.rs#L131-L145
Instead of creating immutable buffers (as done by create_vertex_buffer and create_index_buffer), dynamic buffers could be created for example as done here: https://github.com/gfx-rs/gfx/blob/pre-ll/src/render/src/factory.rs#L152-L155 (note that Role should be Vertex or Index).
These buffers should be done updateable as in your snippet above.
For less frequent updates on dedicated GPUs, 'staging' is a common optimization technique by storing the data in device local memory and copy data from an upload buffer (create_upload_buffer) over to the buffer (needs to be created with TRANSFER_DST bind).
I managed to get it working.
let test_vbuf:gfx::handle::Buffer<gfx_device_gl::Resources, VertexPosColorUV> = factory.create_buffer(
10000,
gfx::buffer::Role::Vertex,
gfx::memory::Usage::Dynamic,
gfx::Bind::empty()
).unwrap();
let test_ibuf:gfx::handle::Buffer<gfx_device_gl::Resources, u16> = factory.create_buffer(
10000,
gfx::buffer::Role::Index,
gfx::memory::Usage::Dynamic,
gfx::Bind::empty()
).unwrap();
self.encoder.update_buffer(&self.pos_color_uv_data.vbuf, &self.vec_pos_color_uv, 0).unwrap();
self.encoder.update_buffer(&self.ib, &self.ind_data, 0).unwrap();
let s = Slice {
start: 0,
end: self.ind_data.len() as u32,
base_vertex: 0,
instances: None,
buffer: gfx::IndexBuffer::Index16(self.ib.clone()),
};
self.encoder.draw(&s, &self.pso2, &self.pos_color_uv_data);
Thanks for all help.
I'm glad it works! Thanks for the sharing the snippets.
Most helpful comment
I managed to get it working.
Thanks for all help.