Модераторы: Rickert, Alexeis, BorisVorontsov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Отражение в OpenGL, помогите справиться со stencil test 
V
    Опции темы
Arks
  Дата 25.12.2007, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 7.5.2006
Где: Барнаул

Репутация: нет
Всего: нет



Есть объект, есть зеркало. Нужно получить отражённый этим зеркалом объект.
Сначала заполняем stencil buffer, потом рисуем исходную сцену, далее с включённым GL_STENCIL_TEST - отражённую.
Не могу понять как надо использовать stencil, чтобы обрезать всё кроме области за зеркалом.
Вот код функции рисования:

Код

int DrawGLScene(GLvoid)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glLoadIdentity();

    glTranslatef(0.0f, 0.0f, -130.0f);
    glRotatef(45.0f, 0.0f, 1.0f, 0.0f);

    // ВОТ ЗДЕСЬ что надо задать, чтобы инициализировался stencil buffer правильно    ???
    glStencilFunc(GL_ALWAYS, 1, 0);
    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
    glEnable(GL_STENCIL_TEST);
    glDisable(GL_LIGHTING);
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_LIGHT0);

    //    Рисуем зеркало в stencil buffer.
    glColor4f(1, 1, 1, 0.2);
    glBegin(GL_TRIANGLES);
        glVertex3f(-1.0f,2.0f,-1.0f);
        glVertex3f(1.0f,2.0f,-1.0f);
        glVertex3f(1.0f,-2.0f,-1.0f);
        glVertex3f(-1.0f,2.0f,-1.0f);
        glVertex3f(1.0f,-2.0f,-1.0f);
        glVertex3f(-1.0f,-2.0f,-1.0f);
    glEnd();    

    glDisable(GL_STENCIL_TEST);

    // Рисуем саму сцену
    glEnable(GL_TEXTURE_2D);
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    // Зеркало
    glBindTexture(GL_TEXTURE_2D,texture[1]);
    glDisable(GL_TEXTURE_GEN_S);
    glDisable(GL_TEXTURE_GEN_T);
    glColor4f(1, 1, 1, 0.2);
    glBegin(GL_TRIANGLES);
        glTexCoord2f(1.0f,1.0f);
        glVertex3f(-1.0f,2.0f,-1.0f);

        glTexCoord2f(0.0f,1.0f);
        glVertex3f(1.0f,2.0f,-1.0f);

        glTexCoord2f(0.0f,0.0f);
        glVertex3f(1.0f,-2.0f,-1.0f);

        glTexCoord2f(1.0f,1.0f);
        glVertex3f(-1.0f,2.0f,-1.0f);

        glTexCoord2f(0.0f,0.0f);
        glVertex3f(1.0f,-2.0f,-1.0f);

        glTexCoord2f(1.0f,0.0f);
        glVertex3f(-1.0f,-2.0f,-1.0f);
    glEnd();    
    glBindTexture(GL_TEXTURE_2D, 0);    

    glPushMatrix();
        glTranslatef(0.0f,0.0f,0.27f);
        glColor4f(1.0f,1.0f,0.0f,1.0f);
        //glBindTexture(GL_TEXTURE_2D, texture[1]);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
        glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
        glEnable(GL_TEXTURE_GEN_S);
        glEnable(GL_TEXTURE_GEN_T);
        glCallList(lst);                          //  Один объект
        

        glPushMatrix();
            glBindTexture(GL_TEXTURE_2D, texture[4]);
            glTranslatef(0.0f,0.0f,0.27f);
            glRotatef(angle,1.0f,1.0f,0.0f);
            glRotatef(angle,0.0f,1.0f,0.0f);
            glTranslatef(0.0f,-0.9f,0.0f);
            glCullFace(GL_FRONT);
            glEnable(GL_CULL_FACE);
            glColor4f(1.0f,0.0f,0.5f,0.5f);
            glCallList(lst+1);                // Второй объект
            glCullFace(GL_BACK);
            glCallList(lst+1);
            glDisable(GL_CULL_FACE);
            glBindTexture(GL_TEXTURE_2D, 0);
        glPopMatrix();
    glPopMatrix();

     // ЧТО ЗАДАТЬ ЗДЕСЬ, чтобы правильно проверялось ???
    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_EQUAL, 1, 255);

    glPushMatrix();
        glScalef(1.0f, 1.0f, -1.0f);          // Отражаем по z, т.к. зеркало мордой к z повёрнуто
        glTranslatef(0.0f, 0.0f, 1.2f);       // Смещаем сцену за зеркало

        glColor4f(1.0f,1.0f,0.0f,1.0f);
        glCallList(lst);

        glPushMatrix();
            glBindTexture(GL_TEXTURE_2D, texture[4]);
        //    glRotatef(-angle,0.0f,1.0f,0.0f);
            glTranslatef(0.0f,0.0f,0.27f);
            glRotatef(angle,1.0f,1.0f,0.0f);
            glRotatef(angle,0.0f,1.0f,0.0f);
            glTranslatef(0.0f,0.9f,0.27f);
            glCullFace(GL_FRONT);
            glEnable(GL_CULL_FACE);
            glColor4f(1.0f,0.0f,0.5f,0.5f);
            glCallList(lst+1);
            glCullFace(GL_BACK);
            glCallList(lst+1);
            glDisable(GL_CULL_FACE);
            glBindTexture(GL_TEXTURE_2D, 0);
        glPopMatrix();

    glPopMatrix();

    angle += 0.1;

    return true;
}



Итак, сейчас у нас есть:
Код

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glStencilFunc(GL_ALWAYS, 1, 0);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glEnable(GL_STENCIL_TEST);
...
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_EQUAL, 1, 255);

В таком виде программа отсекает всё, что находится ЗА ПЛОСКОСТЬЮ зеркала. Т.е. то что отсекать не нужно по правде.

Другой вариант:
Код

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glStencilFunc(GL_ALWAYS, 1, 0);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glEnable(GL_STENCIL_TEST);
...
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_GREATER, 1, 255);

Так программа отсекает, всё что перед зеркалом и НЕПОСРЕДСТВЕННО за зеркалом. В остальном пространстве за плоскостью зеркала, всё рисуется нормально.
Мне же надо, чтобы отсекалось всё кроме того, что находится непосредственно за зеркалом.

Пробовал изменять GL_KEEP на GL_REPLACE, но толку никакого. Честно говоря это всё делал почти методом тыка, не понимаю как он заполняет этот буфер. Очень надеюсь на помощь, бьюсь с этим местом уже не первый день.
PM MAIL ICQ Skype MSN   Вверх
Arks
Дата 2.4.2008, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 7.5.2006
Где: Барнаул

Репутация: нет
Всего: нет



Проблему давно решил. На сколько помню, в программе надо было сменить порядок рисования объектов, чтобы тот, что позади рисовался последним.
PM MAIL ICQ Skype MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Вы можете найти полезным что...
Alexeis
Rickert
  • Английская документация по DirectX лежит где-то здесь.
  • Английская документация по OpenGL лежит где-то там.
  • Гейм-дев у нас обсуждают где-то тут

Ждём вас! С уважением, Alexeis, Rickert.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Мультимедия, OpenGL/DirectX | Следующая тема »


 




[ Время генерации скрипта: 0.0396 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.