Странное поведение рендеринга OpenGL (мерцающие лица)

PRE: я использую библиотеку Assimp (Open Asset Import) для импорта файла .3ds. Меши визуализируются с помощью нормалей и материалов. Использование Qt. Драйвера обновлены на всех компьютерах, которые мы пробовали.

POST: когда я вращаю объекты с помощью камеры, я вижу, что лица некоторых мешей мерцают.

То же самое происходит с использованием метода Assimp'а render() (пример кода загружен с сайта A. wsite).

1) Странно то, что это обычно происходит с маленькими размерами .3ds, а с большими никогда не бывает.

2) Если я очень близко, артефактов нет. Чем дальше, тем больше артефактов вижу.

Это проблема .3ds или моя?

Пример большого .3ds (20 МБ) e

Пример небольшого .3ds (3 МБ) введите здесь описание изображения

Я вставляю сюда свою функцию Draw() (использует glLists, но я не могу от них избавиться):

void Preview::BuildObjectsLists(Scene *sc,GLenum mode){             
QHash<QString, SceneObject*>& hash=sc->getObj();
int counter =0;

for (QHash<QString,SceneObject*>::ConstIterator i = hash.begin();i!=hash.end();++i) {
    glNewList(index-counter, GL_COMPILE);                       
    Mesh* p = dynamic_cast<Mesh*>(i.value());
    if(p){
        Matrix4x4& a=p->getTrasformation();
        a.transpose();
        if(mode==GL_SELECT){                                  
            glPushName(counter);
        }
        glPushMatrix();
        glMultMatrixf((float*) &(a.values));
        applyMaterial(p->getMat());
        QList<Face>& faccie=p->getFaces();
        int numerofacce=faccie.count();
        QList<Vector3D>& normals =p->getNormals();
        bool hasNormals=(!(normals.isEmpty()));
        if(hasNormals)  glEnable(GL_LIGHTING);
        else glDisable(GL_LIGHTING);
        for (int t = 0; t < numerofacce; ++t) {
            Face& f = faccie[t];
            GLenum face_mode;
            Vector3D* lista=f.arrayVertici;
            int* listaNorm=f.normalIndex;
            switch(f.numVertici) {
            case 1:
                face_mode = GL_POINTS;
                glBegin(face_mode);
                if(hasNormals)
                    glNormal3fv(&((normals[listaNorm[0]]).pos[0]));
                glVertex3fv(&lista[0].pos[0]);
                break;
            case 2:
                face_mode = GL_LINES;
                glBegin(face_mode);
                if(hasNormals){
                    glNormal3fv(&((normals[(f.normalIndex)[0]]).pos[0]));
                    glVertex3fv(&lista[0].pos[0]);
                    glNormal3fv(&((normals[(f.normalIndex)[1]]).pos[0]));
                    glVertex3fv(&lista[1].pos[0]);
                }
                else{
                    glVertex3fv(&lista[0].pos[0]);
                    glVertex3fv(&lista[1].pos[0]);
                }
                break;
            case 3:
                face_mode = GL_TRIANGLES;
                glBegin(face_mode);
                if(hasNormals){
                    glNormal3fv(&normals[(f.normalIndex)[0]].pos[0]);
                    glVertex3fv(&lista[0].pos[0]);
                    glNormal3fv(&normals[(f.normalIndex)[1]].pos[0]);
                    glVertex3fv(&lista[1].pos[0]);
                    glNormal3fv(&normals[(f.normalIndex)[2]].pos[0]);
                    glVertex3fv(&lista[2].pos[0]);
                }
                else{
                    glVertex3fv(&lista[0].pos[0]);
                    glVertex3fv(&lista[1].pos[0]);
                    glVertex3fv(&lista[2].pos[0]);
                }
                break;
            default: face_mode = GL_POLYGON; break;
            }
            glEnd();
        }
        glPopMatrix();
    }
    if(mode==GL_SELECT) glPopName();
    glEndList();
    counter++;
}

}

person Nicola    schedule 22.06.2013    source источник


Ответы (1)


12.040 Буферизация глубины работает, но полигоны, кажется, просачиваются через полигоны, которые находятся перед ними. Что происходит?

Возможно, вы настроили плоскости отсечения zNear и zFar таким образом, что это сильно ограничивает точность буфера глубины. Как правило, это вызвано тем, что значение плоскости отсечения zNear слишком близко к 0,0.

http://www.opengl.org/archives/resources/faq/technical/depthbuffer.htm

person Andreas Haferburg    schedule 22.06.2013
comment
gluPerspective(fov,ratio,0.1f,20000); к gluPerspective(fov,ratio,5.0f,20000); решил проблему, большое спасибо - person Nicola; 23.06.2013
comment
@nicolagenesin: я бы посоветовал также уменьшить 200000, это кажется довольно высоким значением, но, конечно, это зависит от размера вашего объекта в единицах OpenGL. Вопрос, на который вы должны ответить: полезно ли в вашем приложении видеть так далеко? - person Boris Dalstein; 24.06.2013
comment
Я загрузил несколько файлов .3ds из Интернета, и 2 из них имеют размер около 10 КБ. Итак, если я хочу увидеть их целиком, я должен находиться на расстоянии 15 КБ от источника. Но то, что вы сказали, - умная вещь: я мог бы динамически расположить zFar во время загрузки сцены (я знаю, насколько велика модель -> установить zFar с помощью некоторого алгоритма). Спасибо - person Nicola; 24.06.2013