Проблемы со слоями, глубиной и смешиванием в openGL - PullRequest
1 голос
/ 11 ноября 2010

Мне нужно наложить некоторые текстуры на видео в многослойной форме (то есть первая текстура должна появиться под, вторая текстура, когда они оба полупрозрачны и т.д.). Все текстуры имеют разные значения Z, поэтому здесь не должно быть конфликтов. Изображения говорят тысячу слов, поэтому я прикрепил одно ниже:

alt text Как видите, стрелки полупрозрачные, пересекаются друг с другом. Однако, похоже, что взаимодействуют только синие и красные стрелки. В качестве аргумента, скажем, красные стрелки имеют значение z (в данном случае вертикальное), 4 - синее и 10 - белое. Функция наложения, которую я использую: gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); и GL_DEPTH_TEST включено. Я ищу, чтобы все наложенные текстуры взаимодействовали так же, как красные и синие. то есть вы можете видеть красную стрелку под белой стрелкой, и более темный красный будет показан там, где пересекаются более темные 2 красные стрелки. Кто-нибудь может указать мне правильное направление?

РЕДАКТИРОВАТЬ: Ниже приведен код, используемый для настройки openGL для каждого рендеринга кадра.

public void display(final GL gl, final GLProjection projection, final FieldMask fieldMask)
{
    layerTextureShader.updateShader(gl, projection, fieldMask);
    if (useMask)
    {
        layerMaskShader.updateShader(gl, projection, fieldMask);
    }

    gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE);

    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);

    if (useMask)
    {
        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getMaskColorBufferObject());
        gl.glBufferData(GL.GL_ARRAY_BUFFER, getNoOfVertices() * 4 * 4, getMaskColors(), GL.GL_STREAM_DRAW);
        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
    }

    gl.glEnable(GL.GL_TEXTURE_2D);
    gl.glActiveTexture(GL.GL_TEXTURE0);
    gl.glBindTexture(GL.GL_TEXTURE_2D, textureId);

    gl.glEnable(GL.GL_BLEND);
    gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);

    if (useMask)
    {
        gl.glBlendEquation(GL.GL_MIN);

        layerMaskShader.use(gl);

        display(gl, true);

        layerMaskShader.release(gl);
    }

    gl.glBlendEquation(GL.GL_MAX);

    layerTextureShader.use(gl);

    display(gl, false);

    layerTextureShader.release(gl);

    gl.glDisable(GL.GL_TEXTURE_2D);

    gl.glDepthMask(true);

    gl.glDisable(GL.GL_BLEND);
}

1 Ответ

2 голосов
/ 11 ноября 2010

Для альфа-смешивания необходимо убедиться, что вы рисуете их в правильном порядке или рисуете с помощью аддитивного смешивания.

Обычный подход для этого состоит в том, чтобы отделить ваши альфа-смешанные элементы от не-альфа-смешанных элементов. Рендеринг всех ваших стандартных элементов, сортировка ваших альфа-смешанных элементов сзади и вперед и рендеринг их в таком порядке. Если частота кадров является проблемой (скажем, если у вас есть много элементов для сортировки), вы можете сортировать по нескольким кадрам.

...