スポンサーリンク
#include <cmath> namespace nu { typedef float real_t; //! @brief 平行投影行列を作成する //! @param [out] m 作成した行列を格納する要素数16の配列 //! @return なし inline void myortho( real_t* m, real_t left, real_t right, real_t bottom, real_t top, real_t znear, real_t zfar) { real_t tx = -(right + left) / (right - left); real_t ty = -(top + bottom) / (top - bottom); real_t tz = -(zfar + znear) / (zfar - znear); //infが出たときは単位行列を返す模様 if (std::isinf(tx) || std::isinf(ty) || std::isinf(tz)) { m[0] = m[5] = m[10] = m[15] = (real_t)1.0; m[1] = m[2] = m[3] = m[4] = m[6] = m[7] = m[8] = m[9] = m[11] = (real_t)0.0; m[12] = m[13] = m[14] = (real_t)0.0; return; } m[0] = (real_t)2.0 / (right - left); m[1] = 0.0; m[2] = 0.0; m[3] = 0.0; m[4] = 0.0; m[5] = (real_t)2.0 / (top - bottom); m[6] = 0.0; m[7] = 0.0; m[8] = 0.0; m[9] = 0.0; m[10] = (real_t)-2.0/(zfar-znear); m[11] = 0.0; m[12] = tx; m[13] = ty; m[14] = tz; m[15] = 1.0; } }
//検証用 #include <cassert> //自前実装版glortho #include "myortho.h" #pragma comment(lib,"opengl32.lib") #pragma comment(lib,"glu32.lib") #pragma comment(lib,"freeglut.lib") void display(void) { GLfloat glomat[16]; //glu関数で生成 GLfloat myomat[16]; //自分関数で生成 //glOrtho,myorthoへの入力の値を色々変える static int i = 0; static float j = 0.0f; GLdouble left=-10+i; GLdouble right=+23 + i*1.5; GLdouble bottom=-10 - i / 2.0; GLdouble top=10 - i; GLdouble znear=5+j; GLdouble zfar=30+j*2; i++; j += 0.01; glMatrixMode(GL_PROJECTION); glLoadIdentity(); //openglで計算 glOrtho(left, right, bottom, top, znear, zfar); glGetFloatv(GL_PROJECTION_MATRIX, glomat); //自前計算 nu::myortho(myomat,left, right, bottom, top, znear, zfar); puts("----------------------------------------------"); printf("** %d \n", i); for (int k = 0; k < 16; k++) { //比較 printf("m[%2d] %+5.10lf %+5.10lf \n", k,glomat[k], myomat[k]); //自前計算とglOrtho計算の値があまりにかけ離れていたらassertで落ちる assert(abs(glomat[k] - myomat[k]) < 0.00001); } puts("----------------------------------------------"); } void mouse(int button, int state, int x, int y) { display(); } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutCreateWindow(argv[0]); glutInitWindowPosition(0, 0); glutInitWindowSize(100,100); glutDisplayFunc(display); glutMouseFunc(mouse); glutMainLoop(); return 0; }