Nota: Eu já encontrei uma resposta (que postarei após esta pergunta) - estava me perguntando se estava fazendo o certo ou se há uma maneira melhor.
Estou criando um jogo isométrico "2.5D" usando o OpenGL ES (JOGL). Com "2.5D", quero dizer que o mundo é 3D, mas é renderizado usando blocos isométricos 2D.
O problema original que tive que resolver era que minhas texturas tinham que ser processadas em ordem (de trás para frente), de modo que os ladrilhos se sobrepusessem adequadamente para criar o efeito adequado. Após algumas leituras, percebi rapidamente que essa é a abordagem 2D do "velho chapéu". Isso ficou difícil de ser feito com eficiência, já que o mundo 3D pode ser modificado pelo player (para que as coisas apareçam em qualquer lugar no espaço 3D) - parecia lógico que eu aproveitasse o buffer de profundidade. Isso significava que não precisava me preocupar em renderizar as coisas na ordem correta.
No entanto, eu enfrentei um problema. Se você usar GL_DEPTH_TEST
e GL_BLEND
juntos, ele cria um efeito onde os objetos são misturados com o fundo antes de serem "ordenadas" por ordem z (o que significa que você obtenha um tipo estranho de sobreposição onde a transparência deve ser).
Aqui estão alguns pseudo-códigos que ilustram o problema (aliás, estou usando a libgdx para Android).
create() {
// ...
// some other code here
// ...
Gdx.gl.glEnable(GL10.GL_DEPTH_TEST);
Gdx.gl.glEnable(GL10.GL_BLEND);
}
render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
Gdx.gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
// ...
// bind texture and create vertices
// ...
}
Portanto, a pergunta é: como resolver o problema de sobreposição de transparência?
Respostas:
OK, então aqui está a minha solução (comente se isso pode ser feito melhor) ...
Acontece que eu deveria, de fato, usar o teste alfa (no entanto, descobri isso por acidente, por isso não tenho muita certeza do por que ele funciona).
Observe o uso de
GL_ALPHA_TEST
, eglAlphaFunc
.fonte
O teste alfa é usado para parar o renderizador que desenha pixels para qualquer buffer, incluindo o buffer z. A mistura alfa é apenas uma coisa visual - os valores ainda são gravados no zbuffer, o que pode resultar em problemas como este - pixels invisíveis ficam na frente dos pixels renderizados subseqüentemente, o que significa que eles falharão no ztest quando você desenhar os novos pixels. Isto é o que você pode ver na imagem que você deu, uma falha no ztest.
Desativar a gravação z também alcançará os mesmos fins, mas você deve garantir que desenha tudo de volta à ordem inicial. Isso deve ser fácil o suficiente no seu jogo isométrico.
fonte