Бывалый

Профиль
Группа: Участник
Сообщений: 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, но толку никакого. Честно говоря это всё делал почти методом тыка, не понимаю как он заполняет этот буфер. Очень надеюсь на помощь, бьюсь с этим местом уже не первый день.
|