weixin_39991305
weixin_39991305
2021-01-11 07:04

How to update indices slice?

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.

该提问来源于开源项目:gfx-rs/gfx

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

7条回答

  • weixin_39991305 weixin_39991305 4月前

    Can you point me to some tutorials or examples. I'm having a hard time finding them on internet.

    点赞 评论 复制链接分享
  • weixin_39551103 weixin_39551103 4月前

    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).

    点赞 评论 复制链接分享
  • weixin_39991305 weixin_39991305 4月前

    I managed to get it working.

    1. I create both buffers:
    
    let test_vbuf:gfx::handle::Buffer<:resources vertexposcoloruv> = factory.create_buffer(
        10000, 
        gfx::buffer::Role::Vertex, 
        gfx::memory::Usage::Dynamic, 
        gfx::Bind::empty()
    ).unwrap();
    
    let test_ibuf:gfx::handle::Buffer<:resources u16> = factory.create_buffer(
        10000, 
        gfx::buffer::Role::Index, 
        gfx::memory::Usage::Dynamic, 
        gfx::Bind::empty()
    ).unwrap();
    </:resources></:resources>
    1. Update buffers, create slice and draw:
    
    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.

    点赞 评论 复制链接分享
  • weixin_39551103 weixin_39551103 4月前

    I'm glad it works! Thanks for the sharing the snippets.

    点赞 评论 复制链接分享
  • weixin_39702335 weixin_39702335 4月前

    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)

    点赞 评论 复制链接分享
  • weixin_39991305 weixin_39991305 4月前

    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.

    点赞 评论 复制链接分享
  • weixin_39551103 weixin_39551103 4月前

    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.

    点赞 评论 复制链接分享

相关推荐