Во-первых, несколько ошибок в коде.
Никогда не помещайте матрицу gluLookAt в матрицу GL_PROJECTION.Это может играть havok с вашим освещением.Матрица gluLookAt должна быть первой матрицей, вставленной вами в GL_MODELVIEW.
Также неплохо иметь матрицу GL_MODELVIEW в качестве матрицы по умолчанию.То есть любой код, который переключается на GL_PROJECTION (или одну из матриц текстуры), отвечает за переключение обратно на GL_MODELVIEW сразу после того, как это сделано с другой матрицей.
Наконец, всегда полезно вызывать glClearDepth иglDepthFunc.Значения по умолчанию (1.0 и GL_LESS) - это именно то, что вы хотите, но всегда хорошо быть откровенным об этих вещах.Таким образом, вам не нужно искать в спецификации, чтобы убедиться, что значения по умолчанию соответствуют вашим ожиданиям.
Теперь перейдем к основной проблеме.
Правила дляэто всего лишь правила для буферов глубины.Что является простым и сложным одновременно.
Во-первых, есть наклон двух плоскостей.Хотя они, безусловно, имеют одинаковый наклон в мировом пространстве, они не обязательно имеют одинаковый наклон в пространстве после проецирования.Это связано с ошибками с плавающей точкой в различных вычислениях, которые преобразуются из мирового пространства в пространство после проецирования.
Во-вторых, если Z-разница между ними слишком мала, то может произойти то, что они будутполучить то же значение Z, примененное к ним.Или ковер может даже иметь меньшее значение Z из-за ошибок с плавающей точкой.
Я полагаю, если бы вы анимировали угол обзора, вы бы увидели, что ковровое покрытие появляется и выходит из поля зрения.
Одна простая вещь, которую вы можете сделать, это всегда рисовать ковер после плоскости земли и использовать GL_LEQUAL для glDepthFunc.Это может не работать 100% времени, опять же из-за ошибок с плавающей точкой.
Следующим шагом является использование смещения полигонов.Это смещает значение Z примитива на некоторое фиксированное значение.Детали того, как это работает, слишком технически для этого обсуждения (проверьте спецификацию OpenGL, если вам интересно), но основная идея заключается в том, что ваша carpet
функция должна выглядеть примерно так:
glEnable(GL_POLYGON_OFFSET_FILL); //Activates polygon offsets for filled triangles.
glPolygonOffset(0, 2); //The 2 is just for safety's sake; 1 ought to be enough.
//Draw the carpet
glDisable(GL_POLYGON_OFFSET_FILL); //Turn off polygon offsetting.