Странный результат с тестом глубины

У меня проблема при включении GL_DEPTH_TEST при рендеринге моих объектов, вот что происходит:

введите описание изображения здесь

GL_CULL_FACE отключен на этом.

Это происходит только в перспективе! У кого-нибудь есть и представление о том, что происходит?

Я использую Qt 4.8 для этого.

Конечно, если я отключу тест глубины, он выглядит хорошо, но тогда объекты накладываются неправильно, как и ожидалось.

Обновить

Я создаю свою матрицу проекции с этим:

ProjectionMatrix.setToIdentity();
ProjectionMatrix.perspective(45, float(width) / float(height), 0, 20.0);

Где ширина и высота связаны с размером области просмотра.

Вот код, где я рисую свою сцену:

void GLWidget::paintGL()
{
glClearColor(0.4765625, 0.54296875, 0.6171875, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

editor->setUniformValue("projectMatrix", controller->getProjectionMatrix());
editor->setUniformValue("viewMatrix", controller->getViewMatrix());

/** Dibujemos los grids **/
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
for (int i=0; i<3; i++)
{
if ((front && i==1) || (side && i==2) || (i==0))
{
editor->setUniformValue("modelMatrix", Objects.at(i).modelMatrix);
editor->setUniformValue("normalMatrix", Objects[i].getNormalMatrix());
editor->setUniformValue("texture", textureon);

glEnableClientState(GL_VERTEX_ARRAY);
editor->enableAttributeArray("vertices");
Objects[i].vertexbuffer->bind();
editor->setAttributeBuffer("vertices", GL_FLOAT, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
editor->enableAttributeArray("texuv");
Objects[i].uvbuffer->bind();
editor->setAttributeBuffer ("texuv", GL_FLOAT, 0, 2);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

glEnableClientState(GL_NORMAL_ARRAY);
editor->enableAttributeArray("normals");
Objects[i].normalbuffer->bind();
editor->setAttributeBuffer ("normals", GL_FLOAT, 0, 3);
glDisableClientState(GL_NORMAL_ARRAY);

Objects[i].elementbuffer->bind();
glBindTexture(GL_TEXTURE_2D, Objects[i].texture);
glDrawElements(GL_TRIANGLES, Objects[i].indices.size(), GL_UNSIGNED_SHORT, (void*)0);
}
}

/** Ahora para las operaciones especificas de cada objeto **/
glEnable(GL_DEPTH_TEST);
//glEnable(GL_CULL_FACE);
for (int i=3; i<Objects.size(); i++)
{
//Objects[i].modelMatrix.scale(1.0, 1.0, 1.0);
//Objects[i].modelMatrix.rotate(1.0, 0.0, 1.0, 0.0);

editor->setUniformValue("modelMatrix", Objects.at(i).modelMatrix);
editor->setUniformValue("normalMatrix", Objects[i].getNormalMatrix());
editor->setUniformValue("texture", textureoff);
editor->setUniformValue("diffuseColor", Objects.at(i).diffuseColor);
editor->setUniformValue("shininess", Objects.at(i).shininess);
editor->setUniformValue("hardness", Objects.at(i).hardness);
editor->setUniformValue("LPos1", Objects.at(i).L1Pos);
editor->setUniformValue("LPos2", Objects.at(i).L2Pos);
editor->setUniformValue("LPos3", Objects.at(i).L3Pos);
editor->setUniformValue("LPos4", Objects.at(i).L4Pos);

glEnableClientState(GL_VERTEX_ARRAY);
editor->enableAttributeArray("vertices");
Objects[i].vertexbuffer->bind();
editor->setAttributeBuffer("vertices", GL_FLOAT, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);

glEnableClientState(GL_NORMAL_ARRAY);
editor->enableAttributeArray("normals");
Objects[i].normalbuffer->bind();
editor->setAttributeBuffer ("normals", GL_FLOAT, 0, 3);
glDisableClientState(GL_NORMAL_ARRAY);

Objects[i].elementbuffer->bind();
glDrawElements(GL_TRIANGLES, Objects[i].indices.size(), GL_UNSIGNED_SHORT, (void*)0);
}
}

Короткими линиями я сначала рисую сетки в соответствии с тем, куда направлена ​​камера, чтобы придать функциональность, подобную Blender’у. Затем я рисую все объекты. Я использую индексированные VBO для достижения этой цели.

Я также рисую их в CCW, я на 99% уверен, что таким образом треугольники передаются в OpenGL.

1

Решение

Ближайшее значение [РЕДАКТИРОВАТЬ перспектива] проекционная матрица равна нулю. В результате все значения глубины равны единице после деления перспективы (.xyz/.w). У @Raxvan явно была правильная идея. Попробуй это…

ProjectionMatrix.perspective(45, float(width) / float(height), 0.01, 20.0);

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

Если у вас очень большие сцены, вам может понадобиться альтернативные методы. Для начала используйте буфер глубины более высокой точности. Если этого недостаточно, возможно, используйте две матрицы проекций и разделите сцену на ближние и дальние объекты. Иногда это вызывает проблемы, если объекты пересекают границу. Вот некоторые ссылки по теме …

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]