Tenho alguns problemas para entender como o glTranslate funciona. No começo, pensei que seria simplesmente adicionar valores ao eixo para fazer a transformação.
No entanto, criei dois objetos que carregariam bitmaps, um tem matriz definida como GL_TEXTURE:
public class Background
{
float[] vertices = new float[]
{ 0f, -1f, 0.0f,
4f, -1f, 0.0f,
0f, 1f, 0.0f,
4f, 1f, 0.0f };
....
private float backgroundScrolled = 0;
public void scrollBackground(GL10 gl)
{
gl.glLoadIdentity();
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glTranslatef(0f, 0f, 0f);
gl.glPushMatrix();
gl.glLoadIdentity();
gl.glMatrixMode(GL10.GL_TEXTURE);
gl.glTranslatef(backgroundScrolled, 0.0f, 0.0f);
gl.glPushMatrix();
this.draw(gl);
gl.glPopMatrix();
backgroundScrolled += 0.01f;
gl.glLoadIdentity();
}
}
e outra para GL_MODELVIEW:
public class Box
{
float[] vertices = new float[]
{ 0.5f, 0f, 0.0f,
1f, 0f, 0.0f,
0.5f, 0.5f, 0.0f,
1f, 0.5f, 0.0f };
....
private float boxScrolled = 0;
public void scrollBackground(GL10 gl)
{
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0f, 0f, 0f);
gl.glPushMatrix();
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(boxScrolled, 0.0f, 0.0f);
gl.glPushMatrix();
this.draw(gl);
gl.glPopMatrix();
boxScrolled+= 0.01f;
gl.glLoadIdentity();
}
}
Agora eles são desenhados no Renderer.OnDraw. No entanto, o plano de fundo se move exatamente 5 vezes mais rápido. Se eu multiplicar boxScrolled por 5, eles serão sinc e moverão juntos. Se eu modificar os vértices de segundo plano para
float[] vertices = new float[]
{ 1f, -1f, 0.0f,
0f, -1f, 0.0f,
1f, 1f, 0.0f,
0f, 1f, 0.0f };
Também estará em sintonia com a caixa. Então, o que está acontecendo com o glTranslate?
Respostas:
Aqui está a minha resposta completa:
Sua contagem de glPushMatrix e glPopMatrix deve ser igual. É o primeiro problema.
Mas o principal problema está no modo matriz. No primeiro caso (plano de fundo), você está usando a matriz de textura, que é modificada pelo glTranslate. Isso significa que em cada etapa as coordenadas da textura serão multiplicadas por essa tradução.
Como as coordenadas da textura estão no intervalo <0,1> e o retângulo do plano de fundo tem 4 unidades, ele não será traduzido por 0,01 a cada quadro, mas será traduzido por 0,04 unidades no mundo.
No segundo caso (caixa), você está alterando a matriz modelview. O que fará com que sua caixa seja traduzida em 0,01 unidades a cada quadro no mundo.
Quando você altera o retângulo de segundo plano para novas coordenadas (as coordenadas x são 0 e 1), todas as coordenadas da textura do quadro são realmente convertidas por 0,01 unidades.
fonte
glTranslatef
glTranslatef
converte (um caso especial de "transformação") a matriz correspondente ao modo de matriz atualmente selecionado. Então, chamá-lo depoisglMatrixMode(GL_MODELVIEW)
significa que você transforma a matriz de visualização de modelo e depois deglMatrixMode(GL_TEXTURE)
transformar a matriz de textura. Consulte o artigo da Wikipedia sobre matrizes de tradução para saber mais sobre isso.A matriz de visualização de modelo é aplicada às coordenadas do objeto para obter as coordenadas oculares, o que significa que as coordenadas absolutas do mundo são transformadas em coordenadas relativas à "câmera". (Antes que o objeto seja renderizado, suas coordenadas são transformadas várias vezes extras, os detalhes estão nas perguntas frequentes do OpenGL sobre transformações , mas não são importantes no momento.)
A matriz de textura faz algo completamente diferente; é aplicada às coordenadas da textura antes de serem mapeadas. Utilizá-lo permitirá obter um efeito de textura de rolagem, rotação, redimensionamento ou distorção de perspectiva.
Espero que você veja agora que essas duas matrizes não são intercambiáveis da maneira que você pensa que são. Eles são aplicados em diferentes estágios do processo de renderização. Quando os resultados da transformação de ambas as matrizes se alinham na tela, é pura coincidência que também depende das posições e coordenadas de textura dos objetos, entre outros.
Algumas pequenas observações extras
Além disso, os comentaristas estão certos ao dizer que você deve equilibrar suas ligações para
glPush/PopMatrix
. Sem ver o resto do seu código e sem saber o que outros objetos estão sendo renderizados, é difícil dizer, mas é possível que parte do efeito que você está enfrentando (a conversão da escala por um fator de 5) seja devido à visualização do modelo matriz de um objeto que está sendo aplicada incorretamente a outro objeto porque ainda está na pilha da matriz.Além disso:
glMatrixMode
em sucessão com os mesmos argumentos não mudará nada, pois o estado OpenGL permanece o mesmo.glLoadIdentity
carrega a matriz de identidade: uma matriz que retorna exatamente as mesmas coordenadas às quais foi aplicada. Pode ser visto como um "reset" da matriz atual. Chamar várias vezes não terá efeito (a menos que você faça algo com a matriz atual).glTranslatef(0f, 0f, 0f)
não terá nenhum efeito.fonte
O que exatamente o glTranslate faz? Antes de tudo, ele calcula uma matriz de conversão - essa é apenas uma matriz de identidade com os valores de conversão nos slots 3 (para x), 7 (para y) e 11 (para z) (assumindo a coluna maior). Em seguida, multiplica a matriz atual por essa matriz de conversão para obter uma nova matriz, na qual substitui a matriz atual. É basicamente isso.
fonte