Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Copying mesh data with GetNativeVertexBufferPtr and SetVertexBufferData

Discussion in 'General Graphics' started by joebain, Jun 18, 2020.

  1. joebain

    joebain

    Joined:
    Oct 24, 2014
    Posts:
    44
    I'm trying to create a mesh by copying a bunch of smaller meshes into it. In this case it's a series of letters that I want to form an animated sentence with. I'm trying to improve performance by avoiding `mesh.vertices = ...` so I'm trying to make use of `Mesh.SetVertexData()`. I feel like I should be able to tell unity to copy the vertex data straight over, so I'm using this code:

    Code (CSharp):
    1.  
    2. void AddLetter(Mesh letterMesh) {
    3.     int letterVertBufferWidth = 0;
    4.     foreach (var vertAttr in letterMesh.GetVertexAttributes())
    5.     {
    6.         letterVertBufferWidth += vertAttr.dimension;
    7.     }
    8.  
    9.     int prevIndexCount = totalIndexCount;
    10.     int prevVertCount = totalVertCount;
    11.  
    12.     int indexCount = (int)mesh.GetIndexCount(0);
    13.     totalIndexCount += indexCount;
    14.     totalVertCount += letterMesh.vertexCount;
    15.  
    16.     int vertBufferLen = letterVertBufferWidth * letterMesh.vertexCount;
    17.     IntPtr vertPtr = letterMesh.GetNativeVertexBufferPtr(0);
    18.     NativeArray<byte> letterBytes = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<byte>((void*)vertPtr, vertBufferLen, Allocator.None);
    19.     mesh.SetVertexBufferParams(totalVertCount, letterMesh.GetVertexAttributes());
    20.     mesh.SetVertexBufferData(letterBytes, 0, prevVertCount, letterMesh.vertexCount);
    21.  
    22.     var letterIndexBuffer = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<byte>((void*)letterMesh.GetNativeIndexBufferPtr(), indexCount, Allocator.None);
    23.     mesh.SetIndexBufferParams(totalIndexCount, letterMesh.indexFormat);
    24.     mesh.SetIndexBufferData(letterIndexBuffer, 0, prevIndexCount, indexCount);
    25. }
    26.  
    When I run this I get an exception at the line

    Code (CSharp):
    1. mesh.SetVertexBufferData(letterBytes, 0, prevVertCount, letterMesh.vertexCount);
    The error is a null reference and if I debug the code it looks like the `letterBytes` NativeArray is not created properly. Does anyone know if it's possible to load mesh vertex data into a NativeArray in this way?
     
    AndersModen likes this.
  2. AndersModen

    AndersModen

    Joined:
    Nov 19, 2019
    Posts:
    51
    I have the same problem using NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<byte>(pointer, (int)size, Allocator.None); on 2019.3.1f1
     
  3. joebain

    joebain

    Joined:
    Oct 24, 2014
    Posts:
    44
    I did find out a bit more on this. The pointer you get from GetNativeVertexBufferPtr is not necessarily to CPU addressable memory, it is often GPU memory. What's more it will be in native opengl or directx format (they do actually state this on the doc page, which I had missed). I don't know a lot about those formats but I believe they're not necessarily the same format as the vertex buffer that unity allows you to write to. Looking at this unity repo it seems that you're not really expected to read from that pointer, but to use it to pass to other native graphics apis.
     
    jperry_oddgames likes this.