指向特征数据的`std :: list`的指针

时间:2013-06-29 15:35:48

标签: c++ opengl std eigen3

我使用Eigen3二维向量作为opengl绘图的2D点,将它们存储在列表中:

typedef Eigen::Vector2d Vec2D;
std::list<Vec2D> points;

现在,我需要一个GLfloat数组来将原始浮点坐标值的整个数据结构传递给图形卡:

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

_vertex = new GLfloat[points.size()*2];
_colors = new GLfloat[points.size()*4];

std::list<Vec2D>::const_iterator it;
int i=0, j=0;
for(it=points.begin(); it!=points.end(); ++it) {
    _vertex[i] = it->x()+2;
    _vertex[i+1] = it->y()+2;
    i+=2;

    _colors[j] = getRed(j/4.0f, it);
    _colors[j+1] = getGreen(j/4.0f, it);
    _colors[j+2] = getBlue(j/4.0f, it);
    _colors[j+3] = getAlpha(j/4.0f, it);
    j+=4;
}

glColorPointer(4, GL_FLOAT, 0, _colors);
glVertexPointer(2, GL_FLOAT, 0, _vertex);
glDrawArrays(GL_LINE_STRIP, 0, points.size());

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);

delete _vertex;
delete _colors;

是否有更有效的方法来创建传递给图形卡的阵列?比如传递points.begin()并找出偏移量是什么,并避免遍历所有点?

我的意思是..在内存中Eigen::Vector2d的x和y坐标必须存储在一些连续的空间中..所以..我想我可以将它直接传递给显卡..但我无法理解如何。

2 个答案:

答案 0 :(得分:4)

std :: list不会将它的数据保存在连续的内存中,你需要std :: vector(或者std :: array,如果你知道编译时的大小,但你可能不知道)。 Vector有一个方法data(),它返回一个指向底层数据的指针。但是,如果您在内部存储Eigen :: vec2d,则无法将其传递给openGl,因为它是一个动态结构,您的数据将遍布您的内存。您需要保持数据到位的结构(并且btw比vec2d更具可读性,在此上下文中有点奇怪)。例如:

struct VertexData
{
    GLfloat x;
    GLfloat y;
    GLfloat red;
    GLfloat green;
    GLfloat blue;
    GLfloat alpha;    
}

然后使用glVertexPointer将sizeof(VertexData)作为步幅传递给openGL

要删除新的数组,您需要使用

delete [] _vertex;

正常删除只会释放第一个元素。或者甚至更好,你可以使用智能指针,std :: unique_ptr在这种情况下最好

std::unique_ptr<GLfloat[]> _vertex(new GLfloat[points.size() * sizeof(GLfloat)]);

当内存超出范围时(在程序段结束时),它将自动释放内存

答案 1 :(得分:2)

pointsstd::list,因此它不包含连续的数据数组。

但是,如果您使用std::vector,那么在C ++ 11中,您可以访问内部使用points.data()的数组。这意味着您不再需要_vertex

要知道,作为替代方案,您甚至可以更进一步,拥有一个包含顶点位置及其颜色的类(以Vertex命名),然后使用data()方法std::vector<Vertex>glInterleavedArraysstride=sizeof(Vertex))结合使用。{/ p>