我一直在努力解决这个问题。我正在尝试使用 devKitPro 在我的 NDS 屏幕上确定模型中顶点的屏幕坐标。该库似乎实现了 OpenGL 的一些功能,但特别是缺少 gluProject 函数,这将(我假设)允许我轻松地做到这一点。
我一直在尝试使用存储在 DS 寄存器中的投影矩阵手动计算屏幕坐标,但我运气不佳,即使尝试从头开始构建投影矩阵基于OpenGL 的文档。这是我尝试使用的代码:
void get2DPoint(v16 x, v16 y, v16 z, float &result_x, float &result_y)
{
//Wait for the graphics engine to be ready
/*while (*(int*)(0x04000600) & BIT(27))
continue;*/
//Read in the matrix that we're currently transforming with
double currentMatrix[4][4]; int i;
for (i = 0; i < 16; i++)
currentMatrix[0][i] =
(double(((int*)0x04000640)[i]))/(double(1<<12));
//Now this hurts-- take that matrix, and multiply it by the projection matrix, so we obtain
//proper screen coordinates.
double f = 1.0 / tan(70.0/2.0);
double aspect = 256.0/192.0;
double zNear = 0.1;
double zFar = 40.0;
double projectionMatrix[4][4] =
{
{ (f/aspect), 0.0, 0.0, 0.0 },
{ 0.0, f, 0.0, 0.0 },
{ 0.0, 0.0, ((zFar + zNear) / (zNear - zFar)), ((2*zFar*zNear)/(zNear - zFar)) },
{ 0.0, 0.0, -1.0, 0.0 },
};
double finalMatrix[4][4];
//Ugh...
int mx = 0; int my = 0;
for (my = 0; my < 4; my++)
for (mx = 0; mx < 4; mx++)
finalMatrix[mx][my] =
currentMatrix[my][0] * projectionMatrix[0][mx] +
currentMatrix[my][1] * projectionMatrix[1][mx] +
currentMatrix[my][2] * projectionMatrix[2][mx] +
currentMatrix[my][3] * projectionMatrix[3][mx] ;
double dx = ((double)x) / (double(1<<12));
double dy = ((double)y) / (double(1<<12));
double dz = ((double)z) / (double(1<<12));
result_x = dx*finalMatrix[0][0] + dy*finalMatrix[0][1] + dz*finalMatrix[0][2] + finalMatrix[0][3];
result_y = dx*finalMatrix[1][0] + dy*finalMatrix[1][1] + dz*finalMatrix[1][2] + finalMatrix[1][3];
result_x = ((result_x*1.0) + 4.0)*32.0;
result_y = ((result_y*1.0) + 4.0)*32.0;
printf("Result: %f, %f\n", result_x, result_y);
}
涉及很多转变,DS 在内部使用定点表示法工作,我需要将其转换为双精度才能使用。我得到的结果似乎有些正确——如果我使用面向屏幕的平面四边形,像素可以完美转换,但旋转不稳定。此外,由于我要使用投影矩阵(它考虑了屏幕宽度/高度?),我需要使用的最后一步似乎根本不正确。投影矩阵不应该为我完成提高屏幕分辨率的步骤吗?
我对这一切都很陌生,我对矩阵数学有相当的了解,但我在 3D 图形方面没有我想的那么熟练。有没有人知道一种方法,给定模型顶点的 3D、非变换坐标,以及将应用于它的矩阵,在不使用 OpenGL 的 gluProject 函数的情况下实际得出屏幕坐标?你能看到我的代码中明显缺少的东西吗?(我会尽可能澄清,我知道这很粗糙,这是我正在制作的原型,清洁度不是最重要的)
非常感谢!
PS:据我了解,我从 DS 的寄存器中提取的 currentMatrix应该给我组合的投影、平移和旋转矩阵,因为它应该是 DS 自己用于平移的确切矩阵硬件,至少根据 GBATEK 的规格。实际上,它似乎实际上并没有应用投影坐标,我想这与我的问题有关。但我不确定,因为自己计算投影不会产生不同的结果。