Izgarada ortografik birim çeviri uyuşmazlığı (örn. 64 piksel yanlış çeviriyor)


14

Bir ızgara üzerinde birim çevirileri ile ilgili küçük bir sorun hakkında bir fikir arıyorum.

Güncelleme ve Çözme

Kendi sorunumu çözdüm. Ayrıntılar için aşağıya bakın. Gönderinin bu bölümündeki her şeyin doğru olduğu ortaya çıktı. Bir şey varsa, bir sonraki kişi için minyatür bir öğretici / örnek / yardım görevi görebilir.

Kurmak

  • FBO, VAO, VBO
  • 512x448 pencere
  • 64x64 ızgara
  • gl_Position = projection * world * position;
  • projectiontarafından tanımlanır ortho(-w/2.0f, w/2.0f, -h/2.0f, h/2.0f);Bu ders kitabı dik izdüşüm fonksiyonudur.
  • world (0, 0) konumunda sabit kamera konumu ile tanımlanır
  • position hareketli grafiğin konumu ile tanımlanır.

Sorun

Aşağıdaki ekran görüntüsünde (1: 1 ölçeklendirme) ızgara aralığı 64x64'tür ve birimi (64, 64) olarak çiziyorum, ancak birim yaklaşık ~ 10 piksel yanlış konumda çiziyor. Piksel boyutunda herhangi bir bozulmayı önlemek için tek tip pencere boyutları denedim, ancak şimdi 1: 1 piksel-dünya birimi projeksiyonu sağlamada uygun şekilde biraz kayboldum. Her neyse, burada soruna yardımcı olacak bazı hızlı resimler var.

512x448 pencere üzerinde 64x64 Fayans

Motorun 64x ofset olduğuna inandığı bir sürü sprite empoze etmeye karar verdim.

64 ofset süper empoze

Bu yerde görünüyordu, hakkında gitti ve 1 birim temel durum yaptım. Bu beklendiği gibi sıraya gibiydi. Sarı, harekette 1 piksellik bir fark gösterir.

1 adet taban kutusu

İstediğim

İdeal olarak herhangi bir yöne doğru 64-birimin hareket etmesi aşağıdakileri (süper empoze edilmiş birimler) verir:

Istenilen çıktı

Tepe Noktaları

Köşe gölgelendiriciye giren köşelerin doğru olduğu anlaşılıyor. Örneğin, ilk resme referans olarak veriler VBO'da şöyle görünür:

      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

Tamlık uğruna, yukarıdaki hareketlere karşılık gelen gerçek dizi şöyledir:

      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.

Projeksiyon Matrisi

512x448 penceresinin projeksiyon matrisi şöyle görünür:

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

ve bir ders kitabı dikey projeksiyon fonksiyonu ile yapılmıştır:

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

Dünya Görünümü Matrisi

Kameranın konumu sadece bir çeviri matrisidir, bu durumda -w / 2 ve -h / 2 ile merkeze göre sıfır olarak dengeledim.

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

Denediğim çözümler

  1. player.moveRight()en-boy oranı denklemi hesaba katarak 1 birimi hareket ettirir. Yani: gridWidth = 64 / 1.14f. Hareket şebekeye sığmadı.

  2. 512x512 penceresini eşleşen dikey bir projeksiyona zorladı.

  3. Çeşitli sihirli sayılar denedim ve ikisi arasında korelasyonlar yapmaya çalıştı.

Bununla birlikte, inandığım tek şey gerçek projeksiyonumu munging olduğum. Bu yüzden, 1: 1 pikselden dünya birimine projeksiyonun sürdürülmesi konusunda herhangi bir fikir arıyorum.


5
İyi yapılandırılmış bir soru, ama belki projeksiyonunuzu ve dünya matrislerinizi görebiliriz. Onlardan yukarıda bahsettiniz, ancak içeriklerini dahil etmediniz. Sorun bu matrislerden birisinde olacak.
Ken

@Ken Hiç sorun değil. Projeksiyon ve dünya-uzay görünüm matrislerimi ekledim. İstediğim çıktıyı ve soruna kendi girişimlerimi de ekledim.
Justin Van Horne

Matrisler iyi görünüyor (glOrtho ve glTranslate tarafından üretilenleri karşılaştırdım. Burada payetlerde grapsing, ancak opengl matrislerini sütun-büyük sırada düzenlenmiş olarak bekliyor, aynı mı yapıyorsunuz?
Ken

Hm, sütun-büyük düzende saklanıyorlar.
Justin Van Horne

Yanıtlar:


5

Kendi sorunumu çözdüm - ve basit bir açıklama olarak patlatmak yerine, sorunu ayıklamak için attığım adımları tanımlamak istiyorum. Özel efektler için tek bir FBO kullandığımı fark ettim.

Birincisi, yukarıdaki her şeyin aslında doğru olduğu ve dışarıda bıraktığım bir adımın sorun olduğu ortaya çıktı.

  • Ortogonal matrislerimi baştan sona doğruladım.
  • Her şeyin bayt sırasını doğruladı.
  • Kare bir doku oluşturdu. <- İşte sihir
  • Kare bir doku oluşturduğumda, bunun ekranda kare olmadığını, kare tepe gölgelendiriciye girdiğini fark ettim.
  • Bu benim bir şeylerin yanlış olduğuna dair ilk ipucumdu. Ekrandaki dokularımın boyutları köşe gölgeleyiciye giden boyutlarla eşleşmedi.
  • Bir FBO kullandığımı unuttum (işte saçma geliyor).
  • FBO doku boyutu, aptal bir nedenden ötürü görünüm alanı doku boyutumla eşleşmedi.
  • FBO'yu devre dışı bıraktı ve sonuçlar eşleşti.
  • Doku boyutumu ve wah-lah'ı tanımlayarak mantık düzeltildi.

Sillyness

Bu kimsenin zamanını aldığında üzgünüm. Soruyu bilmeden aynı problemle karşılaşabilecek herkes için iyi bir önlem olarak bırakacağım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.