我正在开发一个程序的一部分,在这个程序中给出了xyz坐标的集合,制作了一个3D模型。我已经完成了这张图片所需的所有功能(即平移,旋转,缩放),但是给出的xyz坐标越多,我的程序运行得越慢。处理29,000个坐标时,我的程序运行得非常顺利,但是当我有300,000个点时,我的程序速度变慢了。我正在使用SharpGL在WPF中使用OpenGL。插入所有这些点的代码如下:
gl.Begin(OpenGL.GL_LINES);
for (int i = 0; i < (parser.dataSet.Count - 1); i++)
{
gl.Color(1.0f, 0.0f, 0.0f);
gl.Vertex(parser.dataSet[i].X / parser.xDiv, parser.dataSet[i].Y / parser.yDiv, parser.dataSet[i].Z);
gl.Vertex(parser.dataSet[i + 1].X / parser.xDiv, parser.dataSet[i + 1].Y / parser.yDiv, parser.dataSet[i + 1].Z);
}
gl.End();
gl.Flush();
我能做些什么(我不熟悉OpenGL)可以修复吗?有些人提到缩小我的数据,我并不完全反对,但有没有办法在图片上“缩放”(重新缩放)时“缩放”?
答案 0 :(得分:7)
300,000点的立即模式(glBegin()
/ glEnd()
)函数调用开销大量。
使用顶点数组或顶点缓冲区对象批量提交几何体。这样你就可以在10-20个电话中抽取所有积分而不是近百万个。
答案 1 :(得分:1)
要添加一粒盐,您可以优化分割:
divParserDotxDiv=1.0f/parser.xDiv;
divParserDotyDiv=1.0f/parser.yDiv;
gl.Color(1.0f, 0.0f, 0.0f);
for (int i = 0; i < (parser.dataSet.Count - 1); i++)
{
gl.Vertex(parser.dataSet[i].X * divParserDotxDiv,
parser.dataSet[i].Y * divParserDotyDiv,
parser.dataSet[i].Z);
gl.Vertex(parser.dataSet[i + 1].X * divParserDotxDiv,
parser.dataSet[i + 1].Y * divParserDotyDiv,
parser.dataSet[i + 1].Z);
}
应该至少%1到%3更快:)
答案 2 :(得分:0)
genpfault对“使用顶点缓冲区”的回答是正确的答案,但值得注意的是,如果你受到目标环境的限制和/或无法解决远离OpenGL 1.x API的端口,那么display lists中的替代方案。
使用显示列表,您可以创建并激活列表对象(使用glGenLists
和glNewList
),它实际上充当您的顶点调用的记录器。激活列表后,您可以像往常一样调用渲染调用(glBegin
,glEnd
,glVertex
等)。完成几何图形后,调用glEndList
,完成录制。将来当您想要渲染相同的几何图形时,您只需将glCallList
作为快捷方式调用即可。由于驱动程序可以捕获列表数据 并存储在视频卡上,因此开销要小得多。
但是,使用显示列表有一些警告。有一整套OpenGL函数无法在列表中调用,它们仅适用于静态几何。此外,无法保证驱动程序实际上会将信息存储在视频卡上,这意味着不一定会提高性能。最好的办法是远离即时模式和固定功能管道。