Проблемы со слоями, глубиной и смешиванием в openGL
Мне нужно наложить некоторые текстуры на видео в многослойной форме (то есть первая текстура должна появиться под, вторая текстура, когда они оба полупрозрачны и т. Д.). Все текстуры имеют разные значения Z, поэтому здесь не должно быть конфликтов. Изображения говорят тысячу слов, поэтому я приложил одно ниже:
Как видите, стрелки полупрозрачные, пересекаются друг с другом. Однако, похоже, что взаимодействуют только синие и красные стрелки. В качестве аргумента, скажем, красные стрелки имеют значение a z (вертикальное в данном случае) 4, синий цвет 6 и белый 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 ответ
Для альфа-смешивания необходимо убедиться, что вы рисуете их в правильном порядке или рисуете с помощью аддитивного смешивания.
Обычный подход для этого состоит в том, чтобы отделить ваши альфа-смешанные элементы от не-альфа-смешанных элементов. Рендеринг всех ваших стандартных элементов, сортировка ваших альфа-смешанных элементов сзади и вперед и рендеринг их в таком порядке. Если частота кадров является проблемой (скажем, если у вас есть много элементов для сортировки), вы можете сортировать по нескольким кадрам.