维也纳各组织在C#中使用交错顶点 [英] VBOs Using Interleaved Vertices in C#

查看:280
本文介绍了维也纳各组织在C#中使用交错顶点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用维也纳组织使用OpenTK吸引我的模型在C#。我在网上的研究,我在很多地方看,这是很好的做法,使交织的数据结构的大小为32字节的整数倍,所以我编写了以下内容:

I am trying to use VBOs to draw my model in in C# using OpenTK. In my online research I read in many places that it is good practice to make the size of the interleaved data structure an exact multiple of 32 bytes, so I coded up the following:

[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Byte4
{

    public byte R, G, B, A; 

    public Byte4(byte[] input)
    {
        R = input[0];
        G = input[1];
        B = input[2];
        A = input[3];
    }

    public uint ToUInt32()
    {
        byte[] temp = new byte[] { this.R, this.G, this.B, this.A };
        return BitConverter.ToUInt32(temp, 0);
    }
}

[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct VertexInterleaved
{
    // data section is exactly 36 bytes long??? - need padding to get multiple of 32?
    public Vector3 vertex; // Vertex
    public Vector3 normal; // Normal Vector
    public Vector2 textureCoord; // First Texture Coordinates
    public Byte4 rgbaColor; // RGBA value of this vertex
    //public byte[] padding;

    public static int VertexStride()
    {
        // if I'm using the padding I have to add the appropriate size to this...
        return (8 * sizeof(float) + 4 * sizeof(byte));
    }
}

public class VertexBufferObject
{
    private uint[] _VBOid;

    private int _vertexStride;
    private int _totalIndices;
    private int _totalVertices;

    public VertexBufferObject ()
    {
        _VBOid = new uint[2];
        GL.GenBuffers(2, _VBOid);
    }

    public bool DeleteVBO()
    {
        GL.DeleteBuffers(2, _VBOid);
    }

    private void BindBuffers()
    {
        GL.BindBuffer(BufferTarget.ArrayBuffer, _VBOid[0]);
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, _VBOid[1]);
    }

    private void ReleaseBuffers()
    {
        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
    }


    public void BufferMeshData(Mesh3DCollection mesh3Ds)
    {
        _vertexStride = VertexInterleaved.VertexStride();

        _totalIndices = mesh3Ds.TotalIndices();
        _totalVertices = mesh3Ds.TotalVertices();

        VertexInterleaved[] vboVertices = new VertexInterleaved[_totalVertices];
        uint[] vboIndices = new uint[_totalIndices];

        int vertexCounter = 0;
        int indexCounter = 0;

        foreach (Mesh3D m in mesh3Ds)
        {
            foreach (VertexInterleaved v in m.vertices)
            {
                vboVertices[vertexCounter] = v;
                vertexCounter++;
            }

            foreach (uint i in m.indices)
            {
                vboIndices[indexCounter] = i;
                indexCounter++;
            }
        }

        BindBuffers();

        GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr) (_totalIndices * sizeof(uint)), vboIndices, BufferUsageHint.StaticDraw);
        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(_totalVertices * _vertexStride), vboVertices, BufferUsageHint.StaticDraw);

        ReleaseBuffers();
    }

    public void RenderVBO()
    {
        GL.EnableClientState(ArrayCap.VertexArray);
        GL.EnableClientState(ArrayCap.NormalArray);
        GL.EnableClientState(ArrayCap.ColorArray);

        BindBuffers();

        GL.VertexPointer(3, VertexPointerType.Float, _vertexStride, (IntPtr) (0));
        GL.NormalPointer(NormalPointerType.Float, _vertexStride, (IntPtr) (3 * sizeof(float)));
        GL.TexCoordPointer(2, TexCoordPointerType.Float, _vertexStride, (IntPtr) (6 * sizeof(float)));
        GL.ColorPointer(4, ColorPointerType.Byte, _vertexStride, (IntPtr) (8 * sizeof(float)));

        GL.DrawElements(BeginMode.Quads, numIndices, DrawElementsType.UnsignedInt, startLocation);

        ReleaseBuffers();

        GL.DisableClientState(ArrayCap.VertexArray);
        GL.DisableClientState(ArrayCap.NormalArray);
        GL.DisableClientState(ArrayCap.ColorArray);
    {

}



具体的问题:

Specific Questions:

1。)如果我的交错顶点数据结构是一个结构或类?这是否有所作为至于VBO及/或内存占用是什么呢? (我决定使用结构,即使它觉得不对劲,因为顶点都不会改变,一旦他们在内存中。)

1.) Should my interleaved vertex data structure be a struct or a class? Does this make a difference as far as the VBO and/or memory footprint is concerned? (I decided to use a struct, even though it felt wrong, because the vertices aren't going to be altered once they're in memory.)

2)。这是否数据结构,真正需要的是在大小为32字节的整数倍? (也就是说,我需要一个虚拟芯构件强制正确的大小?所有我在网上找到的例子是在C ++中,所以我在是否有同样的想法/动机结转到C#特别感兴趣。

2.) Does this data structure really need to be a multiple of 32 bytes in size? (i.e., do I need a "dummy" padding member to force a correct size? All of the examples I found online were in C++, so I am particularly interested in whether the same ideas/motivations carry over to C#.

3。)是
[Serializable接口]
[StructLayout(LayoutKind.Sequential)]
真的有必要吗?我复制这从我在网上找到一个例子,所以......

3.) Is the [Serializable] [StructLayout(LayoutKind.Sequential)] really necessary? I copied this from an example that I found online, so...

推荐答案

1)。如果结构中的数据要定期更换则是更可取的使用类,即到所述存储器位置的引用。如果它是非常静态的,因为我想这将是,这是更好地使用结构,这是值类型。

1.) If the data within the structure is going to change regularly then it is more advisable to use a class, that is a reference to the memory location. If it is pretty much static, as i imagine this will be, it is better to use structs, that is value type.

2)我听说对准块在32位的字节交织的顶点数据 -aligned边界具有的性能增益,良好的高速缓存行的一致性,但我还没有看到任何性能提升的一个很好的例子。

2.) I have heard that aligning blocks of interleaved vertex data on 32-byte-aligned boundaries has a performance gain, good cache line coherence but I have yet to see a good example of any performance gain.

3。)是的,它是,它指定类型的字段应该在内存中以它们在源代码中声明相同的顺序进行排列。这是交错数据显然非常重要。

3.)yes it is, it specifies that the fields of the type should be laid out in memory in the same order they are declared in your source code. Which is obviously important for interleaved data.

这篇关于维也纳各组织在C#中使用交错顶点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆