C++ 助理及;paintGL(),渲染速度慢(和崩溃)
我正在使用Assimp加载一个.3ds文件,并使用一个QGLWidget派生类使用PaintGL()绘制它。它适用于小的.3ds文件(一些KB),但如果我尝试渲染较大的文件(如1M字节),应用程序会崩溃。我的方式是不是太糟糕和扭曲了?我做错什么了吗 有了qDebug,我知道paintGL()工作正常。问题出在我们的Render方法中,因为如果我模糊了C++ 助理及;paintGL(),渲染速度慢(和崩溃),c++,opengl,assimp,C++,Opengl,Assimp,我正在使用Assimp加载一个.3ds文件,并使用一个QGLWidget派生类使用PaintGL()绘制它。它适用于小的.3ds文件(一些KB),但如果我尝试渲染较大的文件(如1M字节),应用程序会崩溃。我的方式是不是太糟糕和扭曲了?我做错什么了吗 有了qDebug,我知道paintGL()工作正常。问题出在我们的Render方法中,因为如果我模糊了 for (int t = 0; t < p->getFaces().count(); ++t) 循环所有的工作都很快(但很明显,除了
for (int t = 0; t < p->getFaces().count(); ++t)
循环所有的工作都很快(但很明显,除了网格和轴,没有任何东西被绘制)。有了它,加载一些复杂的3ds,它崩溃了
我的硬件是
Phenom II X3 2.10ghz,4GB and 6650M (last drivers)
在赛扬2.1GHz上,它崩溃了
但在i7上,程序启动时只渲染@2FPS(如果我不使用“ourRender”方法,它在我的电脑上以120fps的速度渲染)
我们解决了修改“ourender”方法的问题(使用引用而不是副本)
void GLWidget::ourRender(场景*&sc){
QHash&hash=sc->getObj();
int计数器=0;
for(QHash::conditerator i=hash.begin();i!=hash.end();++i){
目标为x4x4米;
AitTransposeMatrix4&m;
glPushMatrix();
常量网格*p=动态投影(i.值());
glMultMatrixf((浮动*)&m);
如果(p){
//应用_材质(aaFuori.GetScene()->mm材质[计数器];
QList&faccie=p->getFaces();
对于(int t=0;t
现在我们可以在摄影机旋转期间渲染8MBytes.3Ds@4fps(而不是应用程序崩溃)。你们中有人能给我们一个关于这个结果的意见吗?它是好的还是坏的?优化。事实上,对于每个顶点,我们都访问了QList 3次。现在我们修改了它,我们使用了一个Vector3D*数组来代替QList,它保存顶点的位置,因此我们可以使用GL方法glVertex3fv((GLfloat*)数组[numface].posvertex);因此,给定指向面的指针,其速度比以前快得多(在同一场景中为4到10 fps)
PS:Grimmy建议我使用显示列表(现在发现)。明天我将尝试使用它们。如果可能的话,摆脱OpenGL 1。它在哪里崩溃?加载.3ds文件时?渲染时?进行一些调试以找出问题所在,然后编辑你的问题。经过编辑,我刚刚在另一台PC(i7)上尝试过它它是有效的。如果你有时间帮助我,你可以找到上面的详细信息。方法更新了,但我们仍然有相同的问题。如上所述,对于这样一个小场景来说,这仍然非常缓慢,但对于立即模式来说可能是可以接受的。在这里生成显示列表可能非常简单。这可以大大提高性能。我们已经再次修改它。事实上,对于每个顶点,我们访问QList 3次。现在我们修改了它,我们使用Vector3D*数组代替QList来保存顶点的位置,因此我们可以使用GL方法glVertex3fv((GLfloat*)数组[numface].posvertex);因此,给定指向面的指针,它比以前快得多(2.5X,4到10 fps)。关于displaylist…这()是一个好的起点吗?它们会提升很多吗?你能给我们一个百分比吗?我会在这里更新我的新方法。我读到displaylist不推荐使用“如果且仅当需要维护现有遗留代码且无法重写渲染系统时,与静态数据的顶点数组相比,使用显示列表可能非常有利。如果需要动态更新,则顶点数组周围没有任何方法。”。“从这里开始:在较新版本的OpenGL中,它是不推荐的,但即时模式和矩阵堆栈(您当前正在做的一切)也是不推荐的。是的,这个指南就足够了。显示列表可以非常快速地添加。它至少应该消除由构建网格数据(如您提到的优化)引起的任何延迟。”。对于更大的场景,肯定可以从中获益。第二种选择是使用VBOs/VAOs和着色器,但这需要一个完整的系统和绘图代码重写。谢谢你,格里姆,明天我将尝试它们,我会在这里告诉你。希望你再次检查此线程!
Phenom II X3 2.10ghz,4GB and 6650M (last drivers)
void GLWidget::paintGL()
{
qDebug << "Start PaintGL() #" << times;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(objCamera->mPos.x, objCamera->mPos.y, objCamera->mPos.z,
0, objCamera->mView.y, 0,
objCamera->mUp.x, objCamera->mUp.y, objCamera->mUp.z);
if (drawLines) glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
else glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
draw_grid();
drawAxis();
ourRender(this->scenaa);
qDebug << "Close PaintGL() #" << times;
}
void GLWidget::ourRender(const Scene* sc){
QHash<QString, SceneObject*>& hash=sc->getObj();
double molt =1/20;
int counter =0;
for (QHash<QString,SceneObject*>::ConstIterator i = hash.begin();i!=hash.end();++i) {
aiMatrix4x4 minchia(1,0,0,molt*20,0,1,0,molt*20,0,0,1,molt*20,0,0,0,1);
aiTransposeMatrix4(&minchia);
glPushMatrix();
const Mesh* p = dynamic_cast<Mesh*>(i.value());
glMultMatrixf((float*) &minchia);
if(p){
for (int t = 0; t < p->getFaces().count(); ++t) {
Face f = p->getFaces()[t];
GLenum face_mode;
switch(f.getVerticesArray().count()) {
case 1: face_mode = GL_POINTS; break;
case 2: face_mode = GL_LINES; break;
case 3: face_mode = GL_TRIANGLES; break;
default: face_mode = GL_POLYGON; break;
}
glBegin(face_mode);
QList<Vector3D> lista = f.getVerticesArray();
for(int s = 0; s < lista.count(); s++) {
if (p->getNormals().count()>0)
--------->glVertex3f(f.getVerticesArray()[s].getX(),f.getVerticesArray()[s].getY(),f.getVerticesArray()[s].getZ());
}
glEnd();
}
}
glPopMatrix();
molt+=13;
counter++;
}
glPopMatrix();
}
SceneImporter* aa = new AssimpAdapter();
Scene * nuovo=aa->importFile("C:/Users/nicola/Desktop/Source/aces.3ds");
scenaa=nuovo;
void GLWidget::ourRender(Scene *&sc){
QHash<QString, SceneObject*>& hash=sc->getObj();
int counter =0;
for (QHash<QString,SceneObject*>::ConstIterator i = hash.begin();i!=hash.end();++i) {
aiMatrix4x4 m;
aiTransposeMatrix4(&m);
glPushMatrix();
const Mesh* p = dynamic_cast<Mesh*>(i.value());
glMultMatrixf((float*) &m);
if(p){
//apply_material(aaFuori.GetScene()->mMaterials[counter]);
QList<Face>& faccie=p->getFaces();
for (int t = 0; t < faccie.count(); ++t) {
Face f = faccie[t];
GLenum face_mode;
switch(f.getVerticesArray().count()) {
case 1: face_mode = GL_POINTS; break;
case 2: face_mode = GL_LINES; break;
case 3: face_mode = GL_TRIANGLES; break;
default: face_mode = GL_POLYGON; break;
}
glBegin(face_mode);
QList<Vector3D>& lista = f.getVerticesArray();
int conta=lista.count();
glVertex3f(lista[0].x,lista[0].y,lista[0].z);
glVertex3f(lista[1].x,lista[1].y,lista[1].z);
glVertex3f(lista[2].x,lista[2].y,lista[2].z);
glEnd();
}
}
glPopMatrix();
counter++;
}
void GLWidget::ourRender(Scene *sc){
QHash<QString, SceneObject*>& hash=sc->getObj();
aiMatrix4x4 m;
for (QHash<QString,SceneObject*>::ConstIterator i = hash.begin();i!=hash.end();++i) {
aiTransposeMatrix4(&m);
glPushMatrix();
Mesh* p = dynamic_cast<Mesh*>(i.value());
glMultMatrixf((float*) &m);
if(p){
QList<Face>& faccie=p->getFaces();
int numerofacce=faccie.count();
for (int t = 0; t < numerofacce; ++t) {
Face& f = faccie[t];
GLenum face_mode;
Vector3D* lista=f.arrayVertici;
switch(f.getVerticesArray().count()) {
case 1:
face_mode = GL_POINTS;
glBegin(face_mode);
glVertex3fv((GLfloat*)lista[0].pos);
break;
case 2:
face_mode = GL_LINES;
glBegin(face_mode);
glVertex3fv((GLfloat*)lista[0].pos);
glVertex3fv((GLfloat*)lista[1].pos);
break;
case 3:
face_mode = GL_TRIANGLES;
glBegin(face_mode);
glVertex3fv(&lista[0].pos[0]);
glVertex3fv(&lista[1].pos[0]);
glVertex3fv(&lista[2].pos[0]);
break;
default: face_mode = GL_POLYGON; break;
}
glEnd();
}
}
glPopMatrix();
counter++;
}
glPopMatrix();
Vector3D::Vector3D(double x, double y, double z) {
setX(x);
setY(y);
setZ(z);
pos[0]=x; //vertex1
pos[1]=y; //vertex2
pos[2]=z; //vertex3
}