Opengl: проблемы с прозрачностью и глубиной - PullRequest
0 голосов
/ 14 февраля 2012

Я пытаюсь визуализировать два разных объекта, используя обычную функцию glColor4f (). Сцена содержит огромную плоскость с равномерно разделенной поверхностью и простой куб в центре, который меньше плоскости и разделен пополам плоскостью.

Проблема 1: Когда я пытаюсь перевернуть вид, куб кажется полностью над плоскостью.Это выглядит как фигура Эшера. Как правильно исправить глубину?

Проблема 2: предполагается, что маленький куб прозрачный и прозрачный, но прозрачность не работает.

Myметод инициализации.

void GWidget::initializeGL()
{
    setFormat(QGLFormat(QGL::DoubleBuffer|QGL::DepthBuffer|QGL::Rgba|QGL::DepthBuffer));


    glEnable(GL_POINT_SMOOTH);
    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_POLYGON_SMOOTH);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glEnable(GL_COLOR_MATERIAL);

    glEnable(GL_ALPHA_TEST);
    glAlphaFunc(GL_GREATER, 0.0f);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_SRC_ALPHA);

    glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
    glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);
    glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);

    glCullFace(GL_BACK);
    glDepthFunc(GL_LEQUAL);
    glDepthMask(GL_TRUE);

    glFrontFace(GL_CCW);

        glMatrixMode(GL_MODELVIEW);
        glTranslatef(0,0,-1);
        glClearColor(0.4,0.5,0.4,0);
        glClearDepth(1.0f);
        glPushMatrix();
        glShadeModel(GL_SMOOTH);
        glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);

        glEnable(GL_MULTISAMPLE);

//        glScalef(0.1f,0.1f,0.1f);

}

Метод изменения размера:

void GWidget::resizeGL(int width, int height)
{
    glViewport( 0, 0, (GLint)width, (GLint)height );
     glMatrixMode( GL_PROJECTION );
     glLoadIdentity();

     glOrtho ( -width,width,-height,height, 0.0, 200.0 );
     glPushMatrix();

     glMatrixMode( GL_MODELVIEW );
     glLoadIdentity();
     glTranslatef(0,0,-3);
     glScalef(0.7,0.7,0.7);
     glPushMatrix();
     glEnable (GL_DEPTH_TEST);
}

Метод рисования для класса ObjectX: (Плоскость)

void ObjectX::GDraw(int i)
{
    qint32 count,iter;
    MeshX *dmesh;
    VertX *dvert;
    EdgeX *dedge;
    FaceX *dface;

    QList<VertX* > *vlist;


    dmesh=this->Meshes[i];
    vlist=dmesh->getVList();

     iter=0;
     int a,b;
     int c,d;
     glColor4f(0.81,0.71,0.51,1);
     glBegin(GL_QUADS);
     foreach(iter,dmesh->QFaces)
     {
            dface=dmesh->getFaceX(iter);
            a=dface->getA();b=dface->getB();c=dface->getC();d=dface->getD();

            dvert=vlist->at(a);
            glVertex3fv(dvert->getV());

            dvert=vlist->at(b);
            glVertex3fv(dvert->getV());

            dvert=vlist->at(c);
            glVertex3fv(dvert->getV());

            dvert=vlist->at(d);
            glVertex3fv(dvert->getV());

    }
    glEnd();
    glFlush();

    glColor4f(0.51,0.41,0.51,1);
    glBegin(GL_TRIANGLES);
    foreach(iter,dmesh->TFaces)
    {
       glBegin(GL_QUADS);
           dface=dmesh->getFaceX(iter);
           a=dface->getA();b=dface->getB();c=dface->getC();d=dface->getD();

           dvert=vlist->at(a);
           glVertex3fv(dvert->getV());

           dvert=vlist->at(b);
           glVertex3fv(dvert->getV());

           dvert=vlist->at(c);
           glVertex3fv(dvert->getV());
    }
    glEnd();
    glFlush();

    iter=0;
    glLineWidth(3.0f);
    glColor4f(0.31,0.27,0.51,1.0);
    glBegin(GL_LINES);
        count=dmesh->getEListLength();
        while(iter<count)
        {
            dedge=dmesh->getEdgeX(iter);
            a=dedge->getA();b=dedge->getB();
            dvert=vlist->at(a);
            glVertex3fv(dvert->getV());

            dvert=vlist->at(b);
            glVertex3fv(dvert->getV());
            iter++;
        }
    glEnd();
    glFlush();

    iter=0;
    glColor4f(1,1,1,1.0);
    glPointSize(3.0f);
    glBegin(GL_POINTS);

        count=dmesh->getVListLength();
        while(iter<count)
        {
            dvert=dmesh->getVertX(iter);
            glColor4fv(dvert->getColorV());
            glVertex3fv(dvert->getV());
            iter++;
        }
    glEnd();
    glFlush();

}

Метод рисования для метода DomainX :(Маленький кубик)

void DomainX::drawDomain()
{
    qint32 count,iter;
    MeshX *dmesh;
    VertX *dvert;
    EdgeX *dedge;
    FaceX *dface;

    QList<VertX* > *vlist;


    dmesh=this->DMesh;
    vlist=dmesh->getVList();

     iter=0;
     int a,b;
     int c,d;
     glColor4f(0.1,0.1,0.1,0.01);
     glBegin(GL_QUADS);
     foreach(iter,dmesh->QFaces)
     {
            dface=dmesh->getFaceX(iter);
            a=dface->getA();b=dface->getB();c=dface->getC();d=dface->getD();

            dvert=vlist->at(a);
            glVertex3fv(dvert->getV());

            dvert=vlist->at(b);
            glVertex3fv(dvert->getV());

            dvert=vlist->at(c);
            glVertex3fv(dvert->getV());

            dvert=vlist->at(d);
            glVertex3fv(dvert->getV());

    }
    glEnd();
    glFlush();

    glColor4f(0.51,0.41,0.51,0.01);
    glBegin(GL_TRIANGLES);
    foreach(iter,dmesh->TFaces)
    {
       glBegin(GL_QUADS);
           dface=dmesh->getFaceX(iter);
           a=dface->getA();b=dface->getB();c=dface->getC();d=dface->getD();

           dvert=vlist->at(a);
           glVertex3fv(dvert->getV());

           dvert=vlist->at(b);
           glVertex3fv(dvert->getV());

           dvert=vlist->at(c);
           glVertex3fv(dvert->getV());
    }
    glEnd();
    glFlush();

    iter=0;
    glLineWidth(3.0f);
    glColor4f(0.71,0.27,0.51,1.0);
    glBegin(GL_LINES);
        count=dmesh->getEListLength();
        while(iter<count)
        {
            dedge=dmesh->getEdgeX(iter);
            a=dedge->getA();b=dedge->getB();
            dvert=vlist->at(a);
            glVertex3fv(dvert->getV());

            dvert=vlist->at(b);
            glVertex3fv(dvert->getV());
            iter++;
        }
    glEnd();
    glFlush();

    iter=0;
    glColor4f(1,1,1,1.0);
    glPointSize(3.0f);
    glBegin(GL_POINTS);

        count=dmesh->getVListLength();
        while(iter<count)
        {
            dvert=dmesh->getVertX(iter);
            glColor4f(0.3,0.7,0.6,1);
            glVertex3fv(dvert->getV());
            iter++;
        }
    glEnd();
    glFlush();


}

1 Ответ

2 голосов
/ 14 февраля 2012

1) Порядок рисования является причиной.

  • Требуется отсортированный по глубине чертеж граней (от дальнего к ближнему). Если происходит пересечение, сортировка по глубине должна применяться для каждого подграфа, определенного пересечением. В вашем конкретном случае, разделив геометрию куба на плоскость на две половины, а затем нарисуйте грани по порядку, вы теоретически справитесь.

    РЕДАКТИРОВАТЬ: Если куб является единственным прозрачным объектом, сортировка по глубине чертежа куба (без разбиения геометрии) после рендеринга плоскости работает также.

  • Другим решением является фрагментная сортировка по глубине с использованием таких шейдерных методов, как пилинг по глубине.

2) Как уже упоминалось, задние поверхности полупрозрачного объекта должны быть нарисованы с обрезкой лица.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...