OpenGL 渲染大量动态 2D 圆
OpenGL rendering large amounts of dynamic 2D circles
我在这里看到了一篇关于这个主题的类似帖子,但是,我的问题有点不同。
我有一个 2D 图,它将由不同位置、不同大小的圆组成。目前,我的渲染方案使用显示列表来存储预先绘制的圆圈,用户可以使用 glScalef/glTranslatef 主动调整大小和转换该圆圈。但是,由于我渲染了数千个圆圈,因此调整大小和绘制变得非常慢。每个圆可以有不同的半径和颜色,因此这些事情必须在循环内完成。
当用户更改圆圈的大小时,我可以尝试哪些方法来提高圆渲染的速度?我已经像上面的链接一样研究了 VBO,但对于这种类型的应用程序,我的对象大小不断变化,我将获得多少性能提升是模棱两可的。
因为我正在渲染数千个圆圈,所以调整大小和绘制变得非常慢
仅使用顶点阵列,在具有 10,000 个圆圈的英特尔核芯显卡 3000 上每帧大约 60 毫秒:
// g++ -O3 circles.cpp -o circles -lglut -lGL
#include <GL/glut.h>
#include <vector>
#include <iostream>
#include <cmath>
using namespace std;
// returns a GL_TRIANGLE_FAN-able buffer containing a unit circle
vector< float > glCircle( unsigned int subdivs = 20 )
{
vector< float > buf;
buf.push_back( 0 );
buf.push_back( 0 );
for( unsigned int i = 0; i <= subdivs; ++i )
{
float angle = i * ((2.0f * 3.14159f) / subdivs);
buf.push_back( cos(angle) );
buf.push_back( sin(angle) );
}
return buf;
}
struct Circle
{
Circle()
{
x = ( rand() % 200 ) - 100;
y = ( rand() % 200 ) - 100;
scale = ( rand() % 10 ) + 4;
r = rand() % 255;
g = rand() % 255;
b = rand() % 255;
a = 1;
}
float x, y;
float scale;
unsigned char r, g, b, a;
};
vector< Circle > circles;
vector< float > circleGeom;
void init()
{
srand( 0 );
for( size_t i = 0; i < 10000; ++i )
circles.push_back( Circle() );
circleGeom = glCircle( 100 );
}
void display()
{
int beg = glutGet( GLUT_ELAPSED_TIME );
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
double ar = w / h;
glOrtho( -100 * ar, 100 * ar, -100, 100, -1, 1);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 2, GL_FLOAT, 0, &circleGeom[0] );
for( size_t i = 0; i < circles.size(); ++i )
{
Circle& c = circles[i];
c.scale = ( rand() % 10 ) + 4;
glPushMatrix();
glTranslatef( c.x, c.y, 0 );
glScalef( c.scale, c.scale, 0 );
glColor3ub( c.r, c.g, c.b );
glDrawArrays( GL_TRIANGLE_FAN, 0, circleGeom.size() / 2 );
glPopMatrix();
}
glDisableClientState( GL_VERTEX_ARRAY );
glutSwapBuffers();
int end = glutGet( GLUT_ELAPSED_TIME );
double elapsed = (double)( end - beg );
cout << elapsed << "ms" << endl;
}
void timer(int extra)
{
glutPostRedisplay();
glutTimerFunc(16, timer, 0);
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowSize( 600, 600 );
glutCreateWindow( "Circles" );
init();
glutDisplayFunc( display );
glutTimerFunc(0, timer, 0);
glutMainLoop();
return 0;
}
ARB_instanced_arrays
的实例化可能是最干净的。
您将有一个带有 M 顶点的圆,您将绘制N 次,将每个圆的 x/y 位置、半径和颜色存储为顶点属性,并适当地使用glVertexAttribDivisor()
。
如果您想要半径自适应LOD,则会变得更加棘手。 为此,您可能需要深入研究几何着色器。
其次,使用带有 glDrawElementsInstanced 或 glDrawArraysInstanced 的实例化数组作为干净的解决方案,可以很好地转移到其他类型的几何体。
如果你想/需要坚持OpenGL 2(例如,必须在iThing上运行)并且你只需要圆圈,也考虑点精灵。每个圆的原点是点顶点值。将半径存储为纹理坐标的 S 值、表面法线的 X 值等。启用混合、GL_PROGRAM_POINT_SIZE,也许是点平滑;并编写一个顶点着色器,仅将gl_PointSize设置为所需的半径。即时圆圈。
- 这是使用回溯的 nqueen 问题,但我使用了动态 2d 数组,我的程序编译良好,但不返回任何输出
- 检测到堆损坏:在正常块 c++ 动态 2D 数组之后
- 动态 2D 阵列.为什么分段错误?
- 不使用新的动态2D阵列
- 为什么我们在传递动态 2D 数组时不需要列数?
- 如何解决在使用动态 2D 数组进行矩阵乘法的 MPI 进行并行编程时的问题
- C++ 在类中删除动态 2D 数组时不断"Aborted (core dumped)"
- 如何在不使用指针的情况下将动态2D数组传递到函数
- 如何从文件中读取并将内容存储在动态 2D 数组中并以网格格式显示
- 如何在使用动态 2D 数组时修复此代码
- 创建一个动态2D数组来存储类对象
- 访问动态 2D 字符数组时引发访问冲突异常
- 在动态2D布尔数组中更改一个值似乎会更改不同数组中不同位置的值
- 动态2D阵列访问侵犯剩余
- C++动态 2D 阵列
- OpenGL 渲染大量动态 2D 圆
- 在 C++ 中销毁指向动态 2D 数组的指针
- 正在从CIN声明动态2D阵列
- c++中动态2d字符串数组的解除分配
- 无法在C++中声明动态 2D 数组