Estou procurando algumas dicas sobre um pequeno problema com traduções de unidades em uma grade.
Atualização e solução
Eu resolvi meu próprio problema. Veja abaixo para detalhes. Tudo nesta parte da postagem estava correto. Se alguma coisa pode funcionar como um tutorial em miniatura / exemplo / ajuda para a próxima pessoa.
Configuração
- FBO, VAO, VBO
- Janela de 512x448
- Grade 64x64
gl_Position = projection * world * position;
projection
é definido porortho(-w/2.0f, w/2.0f, -h/2.0f, h/2.0f);
Esta é uma função de projeção ortogonal do livro.world
é definido por uma posição fixa da câmera em (0, 0)position
é definido pela posição do sprite.
Problema
Na captura de tela abaixo (escala 1: 1), o espaçamento da grade é 64x64 e estou desenhando a unidade em (64, 64); no entanto, a unidade desenha aproximadamente ~ 10px na posição errada. Tentei dimensões uniformes da janela para evitar distorções no tamanho do pixel, mas agora estou um pouco perdido da maneira correta ao fornecer uma projeção de 1: 1 pixel para a unidade mundial. De qualquer forma, aqui estão algumas imagens rápidas para ajudar no problema.
Decidi super-impor um monte de sprites ao que o mecanismo acredita serem compensações de 64x.
Quando isso parecia fora de lugar, eu fui e fiz o caso base de 1 unidade. O que parecia alinhar como esperado. O amarelo mostra uma diferença de 1px no movimento.
O que eu quero
O movimento ideal em qualquer direção de 64 unidades produziria o seguinte (unidades superimpostas):
Vértices
Parece que os vértices que entram no sombreador de vértices estão corretos. Por exemplo, em referência à primeira imagem, os dados são assim no VBO:
x y x y
----------------------------
tl | 0.0 24.0 64.0 24.0
bl | 0.0 0.0 -> 64.0 0.0
tr | 16.0 0.0 80.0 0.0
br | 16.0 24.0 80.0 24.0
Por uma questão de completude, aqui está a matriz real correspondente aos movimentos acima:
x y z w r g b a s t
-------------------------------------------------------------
tl | 0.0 23.0 0.0 1.0 0.0 0.0 0.0 1.0 0.14210527 0.62650603
bl | 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.14210527 0.76506025
tr | 16.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.2263158 0.76506025
br | 16.0 23.0 0.0 1.0 0.0 0.0 0.0 1.0 0.2263158 0.62650603
-------------------------------------------------------------
-------------------------------------------------------------
tl | 64.0 24.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 0.21084337
bl | 64.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 0.3554217
tr | 80.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.08421053 0.3554217
br | 80.0 24.0 0.0 1.0 0.0 0.0 0.0 1.0 0.08421053 0.21084337
// side bar: I know that I have unnecessary data with having a z-axis.
// The engine flips between perspective and orthogonal and I
// haven't selectively started pruning data.
Matriz de projeção
A matriz de projeção para a janela de 512x448 é assim:
0.00390625 0.0 0.0 0.0
0.0 0.004464286 0.0 0.0
0.0 0.0 -1.0 0.0
0.0 0.0 0.0 1.0
e é construído com uma função de projeção ortogonal do livro:
ortho(-w/2.0f, w/2.0f, -h/2.0f, h/2.0f);
// explicitly: ortho(-512/2.0f, 512/2.0f, -448/2.0f, 448.0f
ortho(float left, float right, float bottom, float top)
{
projection.setIdentity();
projection.m00 = 2.0f / (right - left);
projection.m11 = 2.0f / (top - bottom);
projection.m22 = -1;
projection.m30 = -(right + left) / (right - left);
projection.m31 = -(top + bottom) / (top - bottom);
projection.m32 = 0;
}
Matriz de visão de mundo
A posição da câmera é apenas uma matriz de translação que, neste caso, apenas compenso por -w / 2 e -h / 2 como zero em relação ao centro.
1.0 0.0 0.0 -256.0
0.0 1.0 0.0 -224.0
0.0 0.0 1.0 0.0
0.0 0.0 0.0 1.0
Soluções que tentei
player.moveRight()
moveria 1 unidade com a relação de aspecto fatorada na equação. Assim:gridWidth = 64 / 1.14f
. O movimento não se encaixava na grade.Forçou uma janela de 512x512 com uma projeção ortogonal correspondente.
Tentei vários números mágicos e tentei correlacionar os dois.
Com isso dito, tudo que me resta a acreditar é que estou alterando minha projeção real. Portanto, estou procurando qualquer insight sobre como manter a projeção 1: 1 de pixel para unidade mundial.