私はこれでしばらく苦労してきました。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 は固定小数点表記を使用して内部的に動作するため、それを double に変換して動作させる必要があります。画面に面しているフラットクワッドを使用している場合、ピクセルは完全に変換されますが、回転は不安定です。また、投影行列 (画面の幅/高さを説明するもの) を使用しているため、使用する必要がある最後の手順はまったく正しくないようです。プロジェクション マトリックスは、画面解像度へのステップアップを達成するべきではありませんか?
私はこれらすべてにかなり慣れていません。行列の数学についてはかなり理解していますが、3D グラフィックスに携わりたいほどのスキルはありません。モデルの頂点の 3D の変換されていない座標と、それに適用される行列を考慮して、OpenGL の gluProject 関数を使用せずに実際に画面座標を取得する方法を知っている人はいますか? 私のコードに欠けていることが露骨に明らかなものを見ることができますか? (可能であれば明確にします。大雑把であることは承知しています。これは私が取り組んでいるプロトタイプであり、清潔さは優先事項ではありません)
本当にありがとう!
PS: 私が理解しているように、DS のレジスタから取得した currentMatrix は、DS 自身の変換に使用される正確な行列である必要があるため、結合された投影、変換、および回転行列を提供する必要があります。ハードウェア、少なくとも GBATEK の仕様によると。実際には、実際には投影座標が適用されていないようです。これは私の問題と関係があると思います。しかし、自分で投影を計算しても異なる結果が得られないため、よくわかりません。