Mancata corrispondenza della traduzione delle unità ortografiche sulla griglia (ad es. 64 pixel tradotti in modo errato)


14

Sto cercando alcune informazioni su un piccolo problema con le traduzioni delle unità su una griglia.

Aggiornamento e risolto

Ho risolto il mio problema. Vedi sotto per i dettagli. Tutto in questa parte del post si è rivelato corretto. Semmai può fungere da tutorial / esempio / aiuto in miniatura per la persona successiva.

Impostare

  • FBO, VAO, VBO
  • Finestra 512x448
  • Griglia 64x64
  • gl_Position = projection * world * position;
  • projectionè definito da ortho(-w/2.0f, w/2.0f, -h/2.0f, h/2.0f);Questa è una funzione di proiezione ortogonale da manuale.
  • world è definito da una posizione fissa della telecamera su (0, 0)
  • position è definito dalla posizione dello sprite.

Problema

Nella schermata seguente (ridimensionamento 1: 1) la spaziatura della griglia è 64x64 e sto disegnando l'unità a (64, 64), tuttavia l'unità disegna approssimativamente ~ 10px nella posizione sbagliata. Ho provato dimensioni della finestra uniformi per evitare qualsiasi distorsione sulla dimensione dei pixel, ma ora mi sono perso un po 'nel modo corretto nel fornire una proiezione da 1: 1 pixel a unità del mondo. Ad ogni modo, ecco alcune immagini rapide per aiutare il problema.

Piastrelle 64x64 su una finestra 512x448

Ho deciso di imporre un mucchio di sprite a ciò che il motore ritiene siano offset 64x.

64 offset super-imposti

Quando questo sembrava fuori posto, sono andato in giro e ho fatto il caso base di 1 unità. Che sembrava allineare come previsto. Il giallo mostra una differenza di 1px nel movimento.

Custodia base di 1 unità

Quello che voglio

Idealmente, muoversi in qualsiasi direzione di 64 unità produrrebbe quanto segue (unità super-imposte):

Uscita desiderata

vertici

Sembrerebbe che i vertici che vanno nello shader di vertice siano corretti. Ad esempio, in riferimento alla prima immagine i dati si presentano così nel 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

Per completezza ecco la matrice attuale corrispondente ai movimenti sopra:

      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.

Matrice di proiezione

La matrice di proiezione per la finestra 512x448 è simile alla seguente:

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

ed è costruito con una funzione di proiezione ortogonale da manuale:

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

Matrice di visione del mondo

La posizione della telecamera è solo una matrice di traduzione che in questo caso ho solo spostato di -w / 2 e -h / 2 per essere zero rispetto al 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

Soluzioni che ho tentato

  1. player.moveRight()si sposterà di 1 unità con le proporzioni fattorizzate nell'equazione. Quindi: gridWidth = 64 / 1.14f. Il movimento non rientrava nella griglia.

  2. Costringe una finestra 512x512 con una proiezione ortogonale corrispondente.

  3. Ho provato vari numeri magici e ho provato a disegnare correlazioni tra i due.

Detto questo, tutto ciò che mi resta da credere è che sto inventando la mia vera proiezione. Quindi, sto cercando qualsiasi intuizione per mantenere la proiezione 1: 1 da pixel a unità mondiale.


5
Domanda ben costruita, ma forse potremmo vedere la tua proiezione e le matrici del mondo. Li hai menzionati sopra, ma non ne hai incluso il contenuto. Il problema sarà con una di quelle matrici.
Ken,

@Ken Nessun problema. Ho aggiunto le mie matrici di proiezione e vista dello spazio del mondo. Ho anche incluso l'output desiderato e i miei tentativi di risolvere il problema.
Justin Van Horne,

Le tue matrici sembrano buone (le ho confrontate con quelle prodotte da glOrtho e glTranslate. In questo caso afferrando le cannucce, ma Opengl si aspetta che le sue matrici siano disposte in ordine di colonna maggiore, stai facendo lo stesso?
Ken,

Hm, vengono archiviati nell'ordine principale della colonna.
Justin Van Horne,

Risposte:


5

Ho risolto il mio problema - e piuttosto che risolverlo come una semplice spiegazione, voglio descrivere i passi che ho intrapreso per eseguire il debug del problema. Ho lasciato fuori che stavo usando un singolo FBO per effetti speciali.

Innanzitutto, risulta che tutto quanto sopra è in realtà corretto e un passo che ho lasciato fuori era il problema.

  • Ho verificato le mie matrici ortogonali in tutto e per tutto.
  • Verificato l'ordine dei byte di tutto.
  • Creato una trama quadrata. <- Ecco la magia
  • Quando ho creato una trama quadrata, ho notato che non era quadrata sullo schermo, ma quadrata che entrava nello shader di vertice.
  • Questo è stato il mio primo indizio che qualcosa non andava. Le dimensioni delle mie trame sullo schermo non corrispondevano a quelle che stavano per lo shader di vertice.
  • Ho dimenticato che stavo usando un FBO (ecco che arriva la sciocchezza).
  • Le dimensioni della trama FBO non corrispondevano alle dimensioni della trama del mio viewport per qualsiasi motivo stupido.
  • Disabilitato l'FBO e i risultati corrispondenti.
  • Risolto il problema con la definizione delle dimensioni della trama e wah-lah.

sillyness

Mi dispiace se questo ha impiegato il tempo di qualcuno. Lascerò la domanda come buona misura per chiunque possa imbattersi nello stesso problema senza saperlo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.