将顶点stdcts的std :: vector转换为float *

时间:2017-05-15 21:56:37

标签: c++ std

将std :: vector of Vertices转换为float *的最佳方法是什么?我有vtx作为我的原始数据,它包含两个顶点,包括position,normal和uv,我有std :: vector of vertices v,具有相同的位置,normal和uv。我想要实现的是使用std :: vector v将相同的内存布局和数据作为vtx转换为vtx2。我尝试使用memcpy将内存从v复制到vtx2但是当我打印它们时它们以不同的方式排序。

#include <iostream>
#include <vector>

using namespace std;

struct Vector3
{
    float x;
    float y;
    float z;
};

struct Vector2
{
    float x;
    float y;
};

struct Vertex
{
    Vector3 position;
    Vector3 normal;
    Vector2 uv;
};

int main(int argc, char *argv[])
{
    const int n = 16;
    float* vtx = new float[n];

    // Vertex 1
    // Position
    vtx[0] = 1.0f;
    vtx[1] = 2.0f;
    vtx[2] = 3.0f;
    // Normal
    vtx[3] = 0.1f;
    vtx[4] = 0.2f;
    vtx[5] = 0.3f;
    // UV
    vtx[6] = 0.0f;
    vtx[7] = 1.0f;

    vtx += 8;

    // Vertex 2
    // Position
    vtx[0] = 4.0f;
    vtx[1] = 5.0f;
    vtx[2] = 6.0f;
    // Normal
    vtx[3] = 0.2f;
    vtx[4] = 0.3f;
    vtx[5] = 0.4f;
    // UV
    vtx[6] = 0.0f;
    vtx[7] = 1.0f;

    vtx += 8;


    for (int i = n; i>0; i--)
    {
        cout << *(vtx + i * -1) << endl;
    }

    vector<Vertex> v;
    Vertex vt;

    // Vertex 1
    // Position
    Vector3 pos1 = {1.0, 2.0, 3.0};
    vt.position = pos1;
    // Normal
    Vector3 normal1 = {0.1, 0.2, 0.3};
    vt.position = normal1;
    // UV
    Vector2 uv1 = {0.0, 1.0};
    vt.uv = uv1;

    v.push_back(vt);

    // Vertex 2
    // Position
    Vector3 pos2 = {4.0, 5.0, 6.0};
    vt.position = pos2;
    // Normal
    Vector3 normal2 = {0.2, 0.3, 0.4};
    vt.position = normal2;
    // UV
    Vector2 uv2 = {0.0, 1.0};
    vt.uv = uv2;

    v.push_back(vt);

    float* vtx2 = new float[n];
    memcpy(vtx2, &v[0], v.size() * sizeof(Vertex));

    for (int i = n; i>0; i--)
    {
        cout << *(vtx2 + i * -1) << endl;
    }

    delete[] vtx;
    delete[] vtx2;

    return 0;
}

2 个答案:

答案 0 :(得分:1)

您的代码中存在错误:

vt.position = normal1

应该阅读

vt.normal = normal1

类似于矢量中的第二个顶点。修复后你可能会发现输出匹配(它对我来说),但它可能取决于编译器填充结构的方式。

例如,使用Vector3强制struct Vector3 {...} __attribute__ ((aligned (16)));上的不同对齐将生成&#34;已损坏的&#34;输出

答案 1 :(得分:1)

#include <cstring>
#include <iostream>
#include <vector>
#include <cstddef>

using namespace std;

struct Vector3
{
    float x;
    float y;
    float z;
};

struct Vector2
{
    float x;
    float y;
};

struct Vertex
{
    Vector3 position;
    Vector3 normal;
    Vector2 uv;
};

int main(int argc, char *argv[])
{
    const int n = 16;
    float* vtx1 = new float[n];
    float* vtx = vtx1;

    cout << offsetof(Vertex, normal) << " " << offsetof(Vertex, uv) << " " << sizeof(Vertex) << "\n";

    // Vertex 1
    // Position
    vtx[0] = 1.0f;
    vtx[1] = 2.0f;
    vtx[2] = 3.0f;
    // Normal
    vtx[3] = 0.1f;
    vtx[4] = 0.2f;
    vtx[5] = 0.3f;
    // UV
    vtx[6] = 0.0f;
    vtx[7] = 1.0f;

    vtx += 8;

    // Vertex 2
    // Position
    vtx[0] = 4.0f;
    vtx[1] = 5.0f;
    vtx[2] = 6.0f;
    // Normal
    vtx[3] = 0.2f;
    vtx[4] = 0.3f;
    vtx[5] = 0.4f;
    // UV
    vtx[6] = 0.0f;
    vtx[7] = 1.0f;

    vtx += 8;


    for (int i = n; i>0; i--)
    {
        cout << *(vtx + i * -1) << endl;
    }

    cout << "\n";

    vector<Vertex> v;
    Vertex vt;

    // Vertex 1
    // Position
    Vector3 pos1 = {1.0, 2.0, 3.0};
    vt.position = pos1;
    // Normal
    Vector3 normal1 = {0.1, 0.2, 0.3};
    vt.normal = normal1;
    // UV
    Vector2 uv1 = {0.0, 1.0};
    vt.uv = uv1;

    v.push_back(vt);

    // Vertex 2
    // Position
    Vector3 pos2 = {4.0, 5.0, 6.0};
    vt.position = pos2;
    // Normal
    Vector3 normal2 = {0.2, 0.3, 0.4};
    vt.normal = normal2;
    // UV
    Vector2 uv2 = {0.0, 1.0};
    vt.uv = uv2;

    v.push_back(vt);

    float* vtx2 = new float[n];
    vtx = vtx2;
    memcpy(vtx, &v[0], n*sizeof(float));
    vtx += n;

    for (int i = n; i>0; i--)
    {
        cout << *(vtx + i * -1) << endl;
    }

    delete[] vtx1;
    delete[] vtx2;

    return 0;
}

这是一些更正的代码,使用.normal而不是.position,它不会删除随机内存,删除vtx,第二个打印循环是固定的,以显示数组中的数据,而不是前面的16字节内存。它还在第一行打印结构大小和偏移量。如果你没有将12 24 32作为第一行,那么你的编译器会用空格填充结构,这会导致你的问题。您可以使用struct Vertex __attribute__((packed))来阻止GCC或clang。其他编译器有不同的方法。