Странная глубина/смешение в моделях рисования OpenGL

У меня странная проблема, которую я не могу понять для жизни. Я загружаю файл модели OBJ из Maya и визуализирую его в среде OpenGL. Кажется, все идет хорошо, и в моем независимом средстве просмотра моделей они отображаются правильно. Однако при загрузке в игровую среду (с несколько странной матрицей проекций, которую я не могу контролировать) модель отображается НЕ правильно.

Вершины, КАЖЕТСЯ, находятся в правильном месте, поскольку вращение модели дает правильное ощущение трехмерности. Однако в зависимости от функции глубины появляются разные части модели (неправильно).

Например, в модели человека, когда человек идет слева направо (например, в камеру видна правая сторона модели); если функция глубины установлена ​​на GL_LEQUAL, вы не можете видеть правую руку человека, когда она находится перед туловищем. Однако, когда режим установлен на GL_LESS, вы можете видеть левую руку сквозь туловище. Это одна из тех вещей, которые легче увидеть на картинках, так что приступим:

GL_LESS or GL_NOTEQUAL:

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

GL_LEQUAL or GL_ALWAYS:

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

Следует отметить, что с любой другой функцией глубины ничего не отображается. На первом изображении из серии GL_LEQUAL вы почти можете видеть, что левая рука частично закрыта туловищем, хотя этого быть не должно.

Вот код, используемый для рендеринга модели:

gl.glDisable(GL.GL_BLEND);
    gl.glMatrixMode(GL.GL_MODELVIEW);
    gl.glPushMatrix();
    gl.glLoadIdentity();

    layerTextureShader.updateShader(gl, projection, disparityTop, disparityBottom, fieldMask, 1);

    // gl.glDepthFunc(GL.GL_NEVER); // 512
    // gl.glDepthFunc(GL.GL_LESS); // 513
    // gl.glDepthFunc(GL.GL_EQUAL); // 514
    // gl.glDepthFunc(GL.GL_LEQUAL); // 515
    // gl.glDepthFunc(GL.GL_GREATER); // 516
    // gl.glDepthFunc(GL.GL_NOTEQUAL); // 517
    // gl.glDepthFunc(GL.GL_GEQUAL); // 518
    // gl.glDepthFunc(GL.GL_ALWAYS); // 519
    gl.glDepthFunc(currentGlComparison);

    gl.glEnable(GL.GL_DEPTH_TEST);
    gl.glClear(GL.GL_DEPTH_BUFFER_BIT);

    gl.glDepthMask(true);
    gl.glDepthRange(0, 0.01);

    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getVertexBufferObject());
    gl.glBufferData(GL.GL_ARRAY_BUFFER, getNoOfVertices() * 3 * 4, getVertices(), GL.GL_STREAM_DRAW);
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);

    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getTexCoordBufferObject());
    gl.glBufferData(GL.GL_ARRAY_BUFFER, getNoOfVertices() * 2 * 4, getTexCoords(), GL.GL_STREAM_DRAW);
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);

    gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, getIndicesBufferObject());
    gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, getNoOfIndices() * 4, getIndices(), GL.GL_STREAM_DRAW);
    gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);

    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getColorBufferObject());
    gl.glBufferData(GL.GL_ARRAY_BUFFER, getNoOfVertices() * 4 * 4, getColors(), GL.GL_STREAM_DRAW);
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);

    gl.glEnable(GL.GL_TEXTURE_2D);
    gl.glActiveTexture(GL.GL_TEXTURE0);

    layerTextureShader.use(gl);

   gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getVertexBufferObject());
    gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);

    gl.glEnableClientState(GL.GL_COLOR_ARRAY);
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, mask ? getMaskColorBufferObject() : getColorBufferObject());
    gl.glColorPointer(4, GL.GL_FLOAT, 0, 0);

    gl.glClientActiveTexture(GL.GL_TEXTURE0);

    gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getTexCoordBufferObject());
    gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0);

    gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, getIndicesBufferObject());

    final int count = getNoOfIndices();
    gl.glDrawElements(GL.GL_TRIANGLES, count, GL.GL_UNSIGNED_INT, 0);

    gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);

    gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
    gl.glDisableClientState(GL.GL_COLOR_ARRAY);
    gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);

    layerTextureShader.release(gl);

    gl.glDisable(GL.GL_TEXTURE_2D);

    gl.glDisable(GL.GL_DEPTH_TEST);
    gl.glEnable(GL.GL_BLEND);
    gl.glPopMatrix();

Спасибо всем за любую помощь, это поставило меня в тупик уже несколько дней.


person Sonoman    schedule 25.01.2011    source источник
comment
обычно вы бы использовали МЕНЬШЕ, но из изображений видно, что матрица проекции сглаживает модель, поэтому все вершины находятся на одной глубине. потребуется дополнительная информация о том, как настроена проекция, чтобы действительно ответить на этот вопрос.   -  person Shezan Baig    schedule 25.01.2011
comment
Спасибо за понимание, не могли бы вы предложить мне выполнить некоторые вычисления (например, GL_Projection * GL_ModelView * GameProjectionMatrix * PointXYZ), чтобы увидеть, что на самом деле печатается?   -  person Sonoman    schedule 25.01.2011
comment
Моя матрица GL_Projection представляет собой орто2D-матрицу, созданную с помощью вызова gluOrtho2d(0, 1920, 0, 1080);, а матрица GameProjection нечетная, как я уже упоминал, со значениями [192, 2807, 7, -2.4e7; -825, 49, -2869, -1.2e7; 0.9, -0.06, -0.29, 68059; 0, 0, 1.49e-8, -0.9]. Я знаю, что это нечетно, но это необходимо, и другие элементы отображаются правильно с ее использованием (т.е. не модель Таким образом, я не могу понять, как это приведет к сглаживанию всех значений Z, но я слышу, что упускаю что-то ослепительно очевидное...   -  person Sonoman    schedule 25.01.2011
comment
Вы знаете, что вы можете переключать матрицу проекции и модели в любое время в процессе рендеринга? Если вы используете эти значения для компенсации HUD или чего-то подобного: просто установите соответствующую проекцию только для HUD и используйте разумные значения для модели.   -  person datenwolf    schedule 25.01.2011


Ответы (1)


Похоже, матрица проекции установлена ​​​​таким образом:

gluPerspective ( 90, (GLint)width/ (GLint)height, 0.0, 200.0 );  

Видите ошибку? - Значение 0,0 недопустимо. Хороши только положительные значения Используйте что-то вроде 0,01 вместо 0,0 в качестве третьего аргумента.

person Andrew    schedule 25.01.2011
comment
Спасибо за помощь. К сожалению, матрица задается с помощью glFrustrum с использованием всех положительных значений. gl.glFrustum(-960, 960, -540, 540, 0.01, 100); это то, что я использую. - person Sonoman; 25.01.2011
comment
Ближняя плоскость отсечения, если далеко или близко к исходной точке. Кроме того, эти значения в glFrustum не имеют смысла, это дало бы вам аффинное поле зрения почти на 180 °, а это вряд ли то, что вам нужно. - person datenwolf; 25.01.2011