栅格上的正交单位转换不匹配(例如64像素转换不正确)


14

我正在寻找一些有关网格上单位翻译的小问题的见解。

更新并解决

我解决了自己的问题。有关详情,请参见下文。帖子的这一部分中的所有内容都证明是正确的。如果有的话,它可以作为下一个人的微型教程/示例/帮助。

设定

  • FBO,VAO,VBO
  • 512x448窗口
  • 64x64格
  • gl_Position = projection * world * position;
  • projection由定义。ortho(-w/2.0f, w/2.0f, -h/2.0f, h/2.0f);这是一本教科书正交投影函数。
  • world 由摄像机在(0,0)的固定位置定义
  • position 由子画面的位置定义。

问题

在下面的屏幕截图(1:1缩放)中,网格间距为64x64,我在(64,64)处绘制了单位,但是该单位在错误的位置绘制了大约10px。我尝试过使用统一的窗口尺寸来防止像素大小出现任何失真,但是现在我在提供1:1像素到世界单位的投影时失去了正确的方式。无论如何,这里有一些有助于解决问题的快速图像。

512x448窗口上的64x64切片

我决定在什么引擎认为是64个偏移超级强加一堆精灵。

叠加64个偏移

当这似乎过的地方,我去约,做了1个单位的基本情况。似乎按预期排列。黄色显示移动差异为1px。

1个单位的基本情况

我想要的是

理想情况下,在任何方向上移动64个单位将输出以下内容(叠加的单位):

所需的输出

顶点

看来进入顶点着色器的顶点是正确的。例如,参考第一个图像,数据在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

为了完整起见,以下是与上述动作相对应的实际数组:

      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.

投影矩阵

512x448窗口的投影矩阵如下所示:

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

并使用教科书正交投影函数构造:

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

世界观矩阵

相机的位置只是一个平移矩阵,在这种情况下,我仅将-w / 2和-h / 2相对于中心偏移了零。

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

我尝试过的解决方案

  1. player.moveRight()会将纵横比已考虑在内的比例移动1个单位。因此:gridWidth = 64 / 1.14f。移动不适合网格。

  2. 强制使用匹配的正交投影的512x512窗口。

  3. 尝试了各种魔术数字,并试图在两者之间建立关联。

话虽如此,我只能相信我正在想出自己的实际预测。因此,我正在寻找维持1:1像素到世界单位投影的任何见解。


5
结构合理的问题,但也许我们可以看到您的投影和世界矩阵。您在上面提到了它们,但没有包括它们的内容。问题将出在那些矩阵之一上。
2012年

@Ken完全没有问题。我添加了投影和世界空间视图矩阵。我还包括了所需的输出以及我自己对问题的尝试。
贾斯汀·范·霍恩

您的矩阵看起来不错(我将它们与glOrtho和glTranslate生成的矩阵进行了比较。在这里抓稻草,但是opengl希望其矩阵按列的主要顺序排列,您是否也这样做?
2012年

嗯,它们是按列主要顺序存储的。
贾斯汀·范·霍恩

Answers:


5

我解决了自己的问题-而不是简单地解释它,我想描述我调试问题的步骤。我忽略了我只使用一个FBO来产生特殊效果。

首先,事实证明上述所有内容实际上都是正确的,而我遗漏的步骤就是问题所在。

  • 我彻底验证了我的正交矩阵。
  • 验证所有内容的字节顺序。
  • 创建一个正方形纹理。<-这是魔术
  • 创建正方形纹理时,我注意到它在屏幕上不是正方形,而是正方形进入顶点着色器。
  • 这是我的第一条线索,出了点问题。屏幕上我的纹理的尺寸与顶点着色器的尺寸不匹配。
  • 我忘记了我在使用FBO(这是愚蠢的事情)。
  • 出于任何愚蠢的原因,FBO纹理大小与我的视口纹理大小都不匹配。
  • 禁用FBO,结果匹配。
  • 修复了定义我的纹理大小和哇音的逻辑。

傻傻

很抱歉,如果这占用了任何人的时间。对于那些可能在不知不觉中遇到相同问题的人,我将把它留作一个很好的解决方案。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.