2017-05-15 59 views
1

将Vertex的std :: vector转换为float的最佳方式是什么?我有vtx作为我的原始数据,其中包含两个顶点的位置,正常和紫外线,我有std ::向量的顶点v与相同的位置,正常和紫外线。我试图实现的是使用std :: vector v获得与vtx2相同的内存布局和数据。我尝试使用memcpy将内存从v复制到vtx2,但是当我打印它们时,它们以不同的方式排序。将Vertices图形的std :: vector转换为float *

#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; 
} 
+0

你想用它做什么?你可以访问'data'成员来获得一个指向底层数组的指针,但这是不变的,你不应该直接改变它。 – Donnie

+0

我有一些VBO,最初我使用float *。我试图将它们转换为Vertices的std :: vector,并保留相同的内存布局。 – sabotage3d

+0

*为什么*你想保留内存布局?通常当你使用标准容器时,内存布局不是你关心的问题。 – Beta

回答

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; 
} 

这里是。中性代替.POSITION一些校正码,它不通过删除VTX和第二打印循环删除随机存储器被固定到显示阵列中的数据,而不是16个字节的内存在它之前。它还在第一行中显示结构大小和偏移量。如果你没有得到12 24 32作为第一行,你的编译器就会用空间填充结构,这会导致你的问题。您可以使用struct Vertex __attribute__((packed))来防止GCC或叮当声音。其他编译器有不同的方法。

+0

vtx被移位了8我需要为vtx2保留相同的布局。 – sabotage3d

+0

vtx只是因为你已经向它添加了8次而转移了两次。在任何一种情况下,数据都在内存中的相同位置。你可以通过在memcpy之后加上'vtx2 + = 16;'来使它们等价。 – patstew

+0

@ sabotage3d @patstew指出的是,当你打印“vtx2”的内容时,它现在是无稽之谈......'vtx2'指向数组的**前**,并且你正在使用'编辑vtx2 + i * -1' – donkopotamus

1

。在你的代码中的错误:

vt.position = normal1 

应该读

vt.normal = normal1 

,类似的还有在您的载体第二个顶点。修复后,你可能会发现输出匹配(它对我来说),但它可能取决于你的编译器如何填充结构。

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

+0

另外第二个打印循环从vtx2向后打印 – patstew

+0

我认为你错过了我正在将vtx转换为8,问题在于为vtx2获得相同的布局,因此向后打印。 – sabotage3d

+0

@ sabotage3d @patstew指出的一点是,当你打印“vtx2”的内容时,它现在是无稽之谈......'vtx2'指向数组的**前**,并且你正在使用' vtx2 + i * -1' – donkopotamus

相关问题