std::vector<MyClass*> 的 VBO 和正确的步幅

Posted

技术标签:

【中文标题】std::vector<MyClass*> 的 VBO 和正确的步幅【英文标题】:VBO of std::vector<MyClass*> and correct strides 【发布时间】:2013-01-31 23:00:10 【问题描述】:

我想知道如何在没有数据复制的情况下为以下问题获得最大的数据局部性和性能。

我有一个 std::vector 其中MyClass 类似于

class MyClass

public:
    MyClass(int n,double px,double py,double pz)
    
        someField=n;
        x=px;
        y=py;
        z=pz;
        anotherField=100;
        anotherUnusefulField=-10.0;
    

    int someField;
    int anotherField;


    double x;
    double y;
    double z;
    double anotherUnusefulField;
;

std::vector<MyClass*> myClassVector;
// add some values and set x,y,z

for (std::vector<MyClass*>::iterator iter = myClassVector.begin(); iter!=myClassVector.end();++iter)

    MyClass *tmp = *iter;
    tmp->x+=1.0;
    tmp->y+=2.0;
    tmp->z+=3.0;

我经常对这些数据进行迭代,并且我还想强制执行数据局部性。指向 MyClass 的指针中包含的数据应发送到 OpenGL 顶点数组,其中顶点x,y,z 变量确定。正如您可能想象的那样,很难正确设置步幅,所以我在这里询问是否有其他(便携式)解决方案来解决这个问题。

(p.s. 我已经阅读了VBOs with std::vector 的帖子,但我的情况基本不同,因为我有指针,并且类中还有其他变量。)

【问题讨论】:

复制哪部分数据?能详细点吗? 如果MyClass 只包含你所说明的成员变量,那么将它们直接存储在向量中将使它们对数据局部性最友好。使用您在此处采用的指针方法,我怀疑您正在破坏 CPU 缓存,更不用说数据对 OpenGL 的无用了。 【参考方案1】:

我有指点

这些指针对 OpenGL 没有用处,因为它们位于客户端地址空间中。 OpenGL 也不会取消引用二级指针。

而且我在类中还有其他变量。

好吧,那就不要这样做了。如果你将这些类实例传递给 OpenGL,你会复制很多无用的数据。我建议您只需将索引存储到类成员中紧密打包的 std::vector 或数组中,并引用向量/数组本身。您可以使用 getter/setter/referencer 成员函数来抽象出对向量的访问,即

class …


    // …
    std::vector<v_t> *v;
    size_t index_v;
    x_t getX() const  return (*v)[index_v]; 
    x_t setX(x_t x)  return (*v)[index_v] = x;
    x_t &x()  return (*v)[index_v]; 

;

【讨论】:

以上是关于std::vector<MyClass*> 的 VBO 和正确的步幅的主要内容,如果未能解决你的问题,请参考以下文章

对 MyClass 的数据成员之一的 Vector<MyClass> 排序? [复制]

调整指针段错误向量的大小

具有成员 std::vector 的移动语义

包装 std::vector 的 std::vectors,C++ SWIG Python

从 std::vector 继承时 g++ 7 中的未定义引用

std::vector 类与非成员函数(连同 typedef)[关闭]