如何使用QTimer修复QTGLWidget以减少渲染时间?
我目前正在为我的程序使用OpenGL。我的程序在3D空间中绘制点。这些点可以是一到几千之间的任何数字。我使用函数“glusphere”来绘制球体以表示每个点。 这样,就创建了每个帧,我需要使用QTimer将每个帧显示为动画。这个动画应该由fps控制。例如,如果fps=30,我会将t=1000/30作为QTimer的设置间隔(t)。无论fps=10还是30,我发现fps对我的程序没有太大的改变。 我通过将fps设置为0来查找问题,并通过使用setInterval(0)观察渲染时间。结果如下: n=球体数 当n=10时:28ms=>约30ms 当n=100:87ms=>约90ms时 当n=150:137ms=>约140ms时 当n=1000时:598ms=>约600ms=>0.6秒 从上面的结果来看,每帧的渲染时间随着球体的数量线性增加。以下是我的代码的一部分:如何使用QTimer修复QTGLWidget以减少渲染时间?,qt,opengl,render,qtimer,qtopengl,Qt,Opengl,Render,Qtimer,Qtopengl,我目前正在为我的程序使用OpenGL。我的程序在3D空间中绘制点。这些点可以是一到几千之间的任何数字。我使用函数“glusphere”来绘制球体以表示每个点。 这样,就创建了每个帧,我需要使用QTimer将每个帧显示为动画。这个动画应该由fps控制。例如,如果fps=30,我会将t=1000/30作为QTimer的设置间隔(t)。无论fps=10还是30,我发现fps对我的程序没有太大的改变。 我通过将fps设置为0来查找问题,并通过使用setInterval(0)观察渲染时间。结果如下: n=
GLWidget::GLWidget(QWidget *parent) : QGLWidget(parent)
{
setFormat(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer));
scale=1.0;
rot_x=0;
rot_y=0;
rot_z=0;
trans_x=0;
trans_y=0;
trans_z=0;
isloaded=false;
isplayed=false;
currentFrame=1;
sphereNum=1;
myTimer=new QTimer(this);
//fps=60;
myTimer->setInterval(0);
//myTimer->setInterval();
connect(myTimer, SIGNAL(timeout()), this, SLOT(timerEvent()));
}
void GLWidget::initializeGL()
{
qglClearColor(QColor(Qt::black));
glEnable(GL_DEPTH_TEST);
srand((unsigned)time(NULL));
//QGLFormat::setDoubleBuffer(true);
//qDebug() << "initGL context: " << this->context();
}
void GLWidget::timerEvent()
{
static QTime current_time, last_time;
int elapsed_time;
last_time=current_time;
current_time=QTime::currentTime();
elapsed_time=(current_time.second()*1000 + current_time.msec())-(last_time.second()*1000 + last_time.msec());
//qDebug() << "Timer elapsed time: " << elapsed_time;
if(isloaded && isplayed) {
if(currentFrame<markerData.frameSize) currentFrame++;
makeCurrent();
updateGL();
}
if(currentFrame==markerData.frameSize) {
isplayed=false;
myTimer->stop();
currentFrame=1;
}
}
void GLWidget::drawSphere(GLfloat x, GLfloat y, GLfloat z, GLfloat radius)
{
qglColor(Qt::yellow);
glPushMatrix();
glTranslatef(x, y, z);
gluSphere(p, radius, 10, 10);
//gluCylinder(p, 10, 10, 10, 4, 4);
glPopMatrix();
}
void GLWidget::drawMarkers() {
int markerIndex;
glPushMatrix();
/*for(int i=0; i<markerData.rowSize; i++) {
markerIndex=(currentFrame-1)*markerData.rowSize+i;
//qDebug() << markerIndex;
drawSphere(markerData.markerSet[markerIndex].x, markerData.markerSet[markerIndex].y, markerData.markerSet[markerIndex].z, 10);
}*/
for(int i=0; i<sphereNum; i++) {
markerIndex=rand()%1000;
drawSphere(markerIndex, markerIndex, markerIndex, 10);
}
glPopMatrix();
}
void GLWidget::drawText(double x, double y, double z, QString txt)
{
glDisable(GL_DEPTH_TEST);
qglColor(Qt::white);
renderText(x, y, z, txt, QFont("Arial", 12, QFont::Bold, false) );
glEnable(GL_DEPTH_TEST);
}
void GLWidget::paintGL()
{
static QTime current_time, last_time;
int elapsed_time;
float paint_fps;
//if file data is loaded
if(isloaded)
{
//calculate elapsed time drown 1 frame per second
//elapsed time is millisecond
last_time=current_time;
current_time=QTime::currentTime();
elapsed_time=(current_time.second()*1000 + current_time.msec())-(last_time.second()*1000 + last_time.msec());
paint_fps=1000/elapsed_time;
//qDebug() << "elapsed time: " << elapsed_time << " fps: " << paint_fps;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-20.0f);
glRotatef(30.0, 0.0, 1.0, 0.0);
glRotatef(15.0, 1.0, 0.0, 0.0);
glRotatef(rot_x, 1.0, 0.0, 0.0);
glRotatef(rot_y, 0.0, 1.0, 0.0);
glRotatef(rot_z, 0.0, 0.0, 1.0);
glScalef(scale, scale, scale);
glTranslatef(trans_x, trans_y, trans_z);
//draw elapsed time(ms)
glPushMatrix();
drawText(100, -300, 100, QString::number(elapsed_time) + "ms");
glPopMatrix();
//draw 3-axis
glBegin(GL_LINES);
qglColor(Qt::red);
glVertex3f(0, 0, 0);
glVertex3f(3000, 0, 0);
glEnd();
glBegin(GL_LINES);
qglColor(Qt::green);
glVertex3f(0, 0, 0);
glVertex3f(0, 3000, 0);
glEnd();
glBegin(GL_LINES);
qglColor(Qt::blue);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, 3000);
glEnd();
//draw spheres
p=gluNewQuadric();
drawMarkers();
gluDeleteQuadric(p);
//swapBuffers
if(doubleBuffer()) {
swapBuffers();
makeCurrent();
}
}
}
GLWidget::GLWidget(QWidget*parent):QGLWidget(parent)
{
setFormat(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer));
比例=1.0;
rot_x=0;
rot_y=0;
rot_z=0;
trans_x=0;
trans_y=0;
trans_z=0;
isloaded=false;
显示=假;
currentFrame=1;
sphereNum=1;
myTimer=新的QTimer(此);
//fps=60;
myTimer->setInterval(0);
//myTimer->setInterval();
连接(myTimer,SIGNAL(timeout()),此,插槽(timerEvent());
}
void GLWidget::initializeGL()
{
qglClearColor(QColor(Qt::黑色));
glEnable(GLU深度试验);
srand((无符号)时间(NULL));
//QGLFormat::setDoubleBuffer(true);
//qDebug()不使用固定函数管道(glBegin/glEnd)相反,请查看着色器、VBO和实例rendering@ratchet怪物谢谢你的评论。但我不知道怎么做。这是渲染速度慢的原因吗?VBOs比任何东西都快!当它有10000个球体时,只需花费2毫秒禁用vSync。谢谢@ratchetfreak:)无论如何,如果你想快速绘制许多图形对象,你可以使用VBO和glMapBufferARB。