Copy model vertex buffer position data to array

Do I need to use a struct with the exact size of the vertex buffer’s vertex stride when copying the vertex buffer data to an array to access the posittions?
Is there some way I can extract only the positions? This would be simpler because I would not need to know the vertex declaration beforehand, define a matching vertex format and use this as the array’s data type…

No, but it’s faster if the two match.
(Unless it runs in 32bit mode on an AMD Phenom. Then it’s painfully slow)

1 Like

Is that for a tool or a game?
ES GL (Android) doesn’t support getting data from buffers.

Also this is generally a slow operation. if you plan to update a buffer on every frame you can create a shadow copy initially to speed thing up.

Also also, if this is about manipulating Models look at my RawModelProcessor and DynamicModelProcessor at Aether.Extras

I just wanted to visualize the teapot thread normals and I wanted to compare the normals from the VertexBuffer against normals calculated from the positions.

Ok, then you can get the normals in a Vector3[] as well.
A good example is the GetTextureCoordinate test. You have to pass an offsetInBytes that points at the Normal element.

1 Like

It worked, I adjusted it and could read the positions to a Vector3[] :slight_smile:

You might find this helpful as well. I use it to read indices into pairs of three (one triange).

        //convert indexed, to non indexed
        Vector3[] tmpVertices = new Vector3[vnum];
        int sizeOfEachVertexInBytes = vertexBuffer.VertexDeclaration.VertexStride;
        vertexBuffer.GetData(baseVertex * sizeOfEachVertexInBytes, tmpVertices, 0, vnum, sizeOfEachVertexInBytes);

        TriangleIndices16[] tmpTriangles = new TriangleIndices16[primitiveCount];
        indexBuffer.GetData(startIndex * 2, tmpTriangles, 0, primitiveCount);

        for (int i = 0; i < primitiveCount; i++)
        {
            Vertices[i * 3 + 0 + vbase] = tmpVertices[tmpTriangles[i].A];
            Vertices[i * 3 + 1 + vbase] = tmpVertices[tmpTriangles[i].B];
            Vertices[i * 3 + 2 + vbase] = tmpVertices[tmpTriangles[i].C];
        }

struct TriangleIndices16
{
    public Int16 A, B, C;
    public int VertexStride { get { return (sizeof(Int16)) * 3; } }

    public static TriangleIndices32 operator +(TriangleIndices16 left, int value)
    {
        TriangleIndices32 result;
        result.A = (Int32)(left.A + value);
        result.B = (Int32)(left.B + value);
        result.C = (Int32)(left.C + value);
        return result;
    }

    public override string ToString()
    {
        return String.Format("A:{0,4} B:{1,4} C:{2,4}", A, B, C);
    }
}

internal struct Triangle : IEquatable<Triangle>
{
    public Vector3 A;
    public Vector3 B;
    public Vector3 C;

    public Triangle(Vector3 A, Vector3 B, Vector3 C)
    {
        this.A = A;
        this.B = B;
        this.C = C;
    }

    public Triangle(ref Vector3 A, ref Vector3 B, ref Vector3 C)
    {
        this.A = A;
        this.B = B;
        this.C = C;
    }

    public Vector3[] GetCorners()
    {
        return new Vector3[] {A,B,C};
    }

    public BoundingBox GetBoundingBox()
    {
        return BoundingBox.CreateFromPoints(GetCorners());
    }

    public Plane GetPlane()
    {            
        return new Plane(A,B,C);
    }

    public Vector3 GetNormal()
    {
        return GetPlane().Normal;
    }
    
    public bool Equals(Triangle other)
    {
        return (A==other.A && B==other.B && C==other.C);
    }

    public static bool operator !=(Triangle a, Triangle b) { return !a.Equals(b); }
    public static bool operator ==(Triangle a, Triangle b) { return a.Equals(b); }

    public static Triangle Zero { get { return new Triangle(Vector3.Zero, Vector3.Zero, Vector3.Zero); } }
}
2 Likes