Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Мультимедия, OpenGL/DirectX > Как сглаживать полигоны? и еще пара вопросов...


Автор: MaxS 28.2.2008, 14:02
Экспериментирую с OpenGL. Написал программку: бутылка, рядом с ней кружатся 2 источника света (синий и зелёный). 
1) Как сгладить полигоны бутылки?
user posted image
2) При запуске из компилятора бутылка отображается, но нет треугольника, обозначающего позицию источника света. При запуске непосредственно exe-шника бутылка не отображается, но треугольник появляется! Почему? Как это исправить? Вопрос решен.
3) При нажатии Print Screen изображение пропадает полностью. Почему? И с этим разобрался )

Заранее спасибо!

Код инициализации и рисования:
Код

GLvoid GLinit (GLsizei width,GLsizei height)
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClearDepth(1.0);                        // Разрешить очистку буфера глубины
    glDepthFunc(GL_LESS);                    // Тип теста глубины
    glEnable(GL_DEPTH_TEST);                // разрешить тест глубины
    glEnable(GL_POINT_SMOOTH);
    glEnable(GL_LINE_SMOOTH);
    glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
    //glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    //glBlendFunc(GL_SRC_ALPHA_SATURATE ,GL_ONE);
    //glShadeModel(GL_FLAT);
    glShadeModel(GL_SMOOTH);                // разрешить плавное цветовое сглаживание
    //glEnable(GL_POLYGON_SMOOTH); 
    glMatrixMode(GL_PROJECTION);            // Выбор матрицы проекции
    glLoadIdentity();                        // Сброс матрицы проекции
    gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
    glMatrixMode(GL_MODELVIEW);

    glLightfv(GL_LIGHT1, GL_AMBIENT, lightGlo);
    glLightfv(GL_LIGHT2, GL_DIFFUSE, lightDif2);
    glLightfv(GL_LIGHT2, GL_POSITION, lightPos2);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDif);
    glLightfv(GL_LIGHT1, GL_POSITION, lightPos);
    glEnable(GL_LIGHT2);
    glEnable(GL_LIGHT1);
    glEnable(GL_LIGHTING);

    Load3DS (&object,"beer.3ds");            // грузим объект
    MakeNormals(&object);                    // вычисляем нормали
    glNewList(LIST_NUM1,GL_COMPILE);
    glBegin(GL_TRIANGLES);
    for (l_index = 0; l_index < object.polygons_qty; l_index++)
    {
        glNormal3f( object.normvert[ l_index ].x,
                    object.normvert[ l_index ].y,
                    object.normvert[ l_index ].z);
        //glEnable(GL_NORMALIZE);    //!!!!
        //glColor3f(0.0f,1.0f,0.0f);
        glVertex3f( object.vertex[ object.polygon[l_index].a ].x,
                    object.vertex[ object.polygon[l_index].a ].y,
                    object.vertex[ object.polygon[l_index].a ].z);
        //glColor3f(1.0f,0.0f,0.0f);
        glVertex3f( object.vertex[ object.polygon[l_index].b ].x,
                    object.vertex[ object.polygon[l_index].b ].y,
                    object.vertex[ object.polygon[l_index].b ].z);
        //glColor3f(0.0f,0.0f,1.0f);
        glVertex3f( object.vertex[ object.polygon[l_index].c ].x,
                    object.vertex[ object.polygon[l_index].c ].y,
                    object.vertex[ object.polygon[l_index].c ].z);
    }
    glEnd();
    glEndList();
}

Код

GLvoid DrawGLScene(GLvoid)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        // очистка Экрана и буфера глубины
    glLoadIdentity();

    //оси координат
    glTranslatef(-0.53f,0.35f,-1.0f);                    
    glRotatef(lightRot,0.5,1.0,0.0);
    lightRot += 1.5;
    glDisable(GL_LIGHTING);
    glColor3f(1.0,0.0,0.0);
    glBegin(GL_LINES);
    glVertex3f(0.0,0.0,0.0);
    glVertex3f(0.05,0.0,0.0);
    glVertex3f(0.0,0.0,0.0);
    glVertex3f(0.0,0.05,0.0);
    glVertex3f(0.0,0.0,0.0);
    glVertex3f(0.0,0.0,0.05);
    glEnd();
    glEnable(GL_LIGHTING);
    glLoadIdentity();
    glTranslatef(0.0f,0.0f,glubina);

    //источник света
    glRotatef(lightRot,0.5,1.0,0.0);
    //lightRot += 1;
    glBegin(GL_TRIANGLES);
    glVertex3f(lightPos[0],lightPos[1],lightPos[2]-1);
    glVertex3f(lightPos[0]+1,lightPos[1]+1,lightPos[2]-1);
    glVertex3f(lightPos[0]-1,lightPos[1],lightPos[2]-1);
    glEnd();//(!!!)
    glLightfv(GL_LIGHT1, GL_POSITION, lightPos);
    glRotatef(lightRot,0.6,1.0,0.5);
    glLightfv(GL_LIGHT2, GL_POSITION, lightPos2);
    glLoadIdentity();
    glTranslatef(0.0f,0.0f,glubina);

    //glColor3f(0.0f,1.0f,0.0f);
    glCallList(LIST_NUM1);
}

Автор: baldina 28.2.2008, 17:54
Проверяй нормали.
Судя по рисунку (и коду) нормали сейчас определяются по треугольникам (перпендикулярны им), а должны быть перпендикулярны образующей.
Для каждой точки одного треугольника будет своя нормаль (две из них могут совпадать, но не все три сразу)

Автор: MaxS 28.2.2008, 20:55
Спасибо, буду пробовать. 
А есть ли функция для автоматического вычисления нормалей? Или все "вручную"?

Автор: baldina 29.2.2008, 13:41
нет, нормали сам считаешь. в данном случае нормаль можно вычислять по смежным треугольникам (правильная нормаль в точке будет среднее между нормалями этой точки в соседних треугольниках).
см. рисунок: черные стрелки это текущие нормали, красным - как должны быть

Автор: MaxS 29.2.2008, 18:57
Спасибо! Теперь отображается как надо.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)