我使用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坐标必须存储在一些连续的空间中..所以..我想我可以将它直接传递给显卡..但我无法理解如何。
答案 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)
points
是std::list
,因此它不包含连续的数据数组。
但是,如果您使用std::vector
,那么在C ++ 11中,您可以访问内部使用points.data()
的数组。这意味着您不再需要_vertex
。
要知道,作为替代方案,您甚至可以更进一步,拥有一个包含顶点位置及其颜色的类(以Vertex
命名),然后使用data()
方法std::vector<Vertex>
与glInterleavedArrays
(stride=sizeof(Vertex)
)结合使用。{/ p>