绘制数以千计的多边形与OpenGL VBO
Drawing thousands of polygons with OpenGL VBO
我正在尝试创建能够渲染超过100000个2d原始对象的OpenGL应用程序。
我敢肯定,使用现代OpenGL和VBO应该是可能的。
所以这里是代码(使用Qt):
#include "paintwidget.h"
PaintWidget::PaintWidget(QGLWidget *parent) : QGLWidget(parent)
{
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(updateTimer()));
timer->start(16);
}
GLuint indices[100000];
void PaintWidget::initializeGL()
{
VBOBuffer= new QGLBuffer(QGLBuffer::VertexBuffer);
VBOBuffer->create();
VBOBuffer->bind();
VBOBuffer->setUsagePattern(QGLBuffer::DynamicDraw);
VBOBuffer->allocate(100000 * 10 * sizeof(double));
// load data into VBO:
for(int i=0; i<100000; i++)
{
GLdouble vertices[] = {100 + (double)i * 100, 100 + (double)i * 100,
100 + (double)i * 100, 200 + (double)i * 100,
200 + (double)i * 100, 200 + (double)i * 100,
300 + (double)i * 100, 150 + (double)i * 100,
200 + (double)i * 100, 100 + (double)i * 100 };
VBOBuffer->write(i * 10 * sizeof(double), vertices, 10 * sizeof(double));
}
// fill indices array:
for(int i=0; i<100000; i+=10)
{
indices[i] = i;
indices[i+1] = i+1;
indices[i+2] = i+1;
indices[i+3] = i+2;
indices[i+4] = i+2;
indices[i+5] = i+3;
indices[i+6] = i+3;
indices[i+7] = i+4;
indices[i+8] = i+4;
indices[i+9] = i;
}
}
void PaintWidget::paintEvent(QPaintEvent*)
{
QPainter paint(this);
paint.beginNativePainting();
glEnable(GL_LINE_SMOOTH);
glEnable(GL_MULTISAMPLE);
glClearColor(0.1, 0.96, 0.1, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_DOUBLE, 0, 0);
// draw my polygons:
for(int i=0; i<100000; i+=5)
{
glDrawArrays(GL_POLYGON, i, 5);
}
glDisableClientState(GL_VERTEX_ARRAY);
paint.endNativePainting();
}
void PaintWidget::updateTimer()
{
paintEvent(nullptr);
}
这段代码每16毫秒渲染100000个多边形。
我对我的代码的性能不是很满意。它加载处理器相当多(尽管使用VBO)。我能让它更有效率吗,或者这是最好的性能?
谢谢。
这就是你的问题:
// draw my polygons: for(int i=0; i<100000; i+=5) { glDrawArrays(GL_POLYGON, i, 5); }
您正在为单个VBO执行100000次draw调用。这就是CPU的负担。相比之下,最新的《毁灭战士》在整个场景中平均只需要不到1500次draw call。
你应该用glDrawArrays
或glDrawElements
的一次调用来绘制整个几何图形。顺便说一句:现代OpenGL不再支持GL_POLYGON(唯一支持的原语是GL_POINTS, GL_LINE*和GL_TRIANGLE*)。
如果你关心的是启动一个新的原语,用glDrawElements
你可以指定一个特殊的索引重新启动。或者(这实际上是首选的方法)把它画成带索引的三角形。索引是高效缓存的关键,所以如果你想要最大的性能,那就这样做。
相关文章:
- OpenGL VBO Indexing ( How to compute Index Array)
- 将 OpenGL VBO 与自定义类/数据结构一起使用
- OpenGL VBO批处理最佳实践
- OpenGL VBO Troubles
- OpenGL VBO正常/照明问题
- OpenGL VBO内存泄漏
- OpenGL:VBO和一个坏GC
- OpenGL VBO Drawing
- 如何使用 CUDA 内核更新 OpenGL VBO
- OpenGL VBO会泄漏到CPU RAM吗?
- OpenGL VBO数据似乎已损坏
- c++和OpenGL, VBO顶点交错与骨信息
- OpenGL VBO在调用glDrawArrays()时出现分段错误
- OpenGL vbo和指针的问题
- OpenGL: VBO函数没有定义
- OpenGL VBO EXC_BAD_ACCESS Crash
- OpenGL VBO绘图问题
- 绘制数以千计的多边形与OpenGL VBO
- QThread在GUI事件上调用glBufferData()时不更新OpenGL vbo和不渲染任何东西
- OpenGL VBO not working (C++)