2

我使用 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()并找出偏移量是什么并避免遍历所有点?

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

4

2 回答 2

4

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

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

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

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

delete [] _vertex;

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

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

它会在超出范围时自动释放内存(在块的末尾)

于 2013-06-29T15:57:03.387 回答
2

points是 astd::list所以它不包含连续的数据数组。

但是,如果您改用std::vector,那么在 C++11 中,您可以使用points.data(). 这意味着您不再需要_vertex

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

于 2013-06-29T16:08:44.270 回答