Question

I am using Assimp to load a .3ds file, and a QGLWidget derived class to draw it using PaintGL(). It works with small .3ds files (some KBytes) but if i try to render bigger files (like 1MBytes) the application crashes. Is my way too bad and twisted? Am I doing something wrong?

With qDebug i understand that paintGL() works correctly.The problem is in ourRender method,because if i obscure the

for (int t = 0; t < p->getFaces().count(); ++t)

and in detail

glVertex3f(f.getVerticesArray()[s].getX(),f.getVerticesArray();

cycle it all works fast (but obviously nothing is painted) except grid and axis.With it,and loading some complicated 3ds,it crashes

my hardware is

Phenom II X3 2.10ghz,4GB and 6650M (last drivers)

On a Celeron 2.1 Ghz it crash BUT on a i7 the program starts but render @2FPS (if I dont use "ourRender" method,it renders at 120fps on my pc)

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;
}

And this is the "ourRender" method:

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();
}

...in the derived QGLWidget class costructor...

SceneImporter* aa = new AssimpAdapter();
Scene * nuovo=aa->importFile("C:/Users/nicola/Desktop/Source/aces.3ds");
scenaa=nuovo;
Was it helpful?

Solution 2

Optimizazion.The fact is that for every vertex we were accessing to a QList 3 times.Now we've modified it,and instead of Qlist we use a Vector3D* array that saves the position of the vertices and so we can use the GL method glVertex3fv((GLfloat*)array[numface].posvertex); So,given the pointer to the face,its much faster than before (4 to 10 fps on the same scene).

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();

}

Where Vector3D is initialized like this:

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
}

PS:Grimmy suggests me to use DisplayLists (discovered right now).Tomorrow I will try them.

OTHER TIPS

We solved the problem modifying "ourender" method (using references instead of copyes)

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++;
}

Now we can render 8MBytes .3Ds @4fps during camera rotations (instead of application crash).Could someone of you give us an opinion about this result?is it good or bad?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top