最終更新: mikk_ni3_92 2008年11月12日(水) 15:31:01履歴
現在地 >> メニュー >> サンプルコード::OpenGL >> スクリーンの描画
gluPerspective()関数で設定したスクリーンがOpenGL上でどこにあるのかを計算し、
3次元空間上にスクリーンを描画せよ。
その他条件
gluPerspective()関数で設定したスクリーンがOpenGL上でどこにあるのかを計算し、
3次元空間上にスクリーンを描画せよ。
その他条件
- ある視点(x,y,z)から(0,0,0)を見ていて、+y軸が上。
#include <iostream> #include <cmath> #include <GL/glut.h> //マウスの状態 struct _MOUSE { int Xstart,Ystart; bool flag; double weight; }; _MOUSE MouseStatus={0,0,false,0.5}; //回転関係 struct _ObjectRotate { double xAngle,yAngle; }; _ObjectRotate ObjRot={0,0}; //視点情報 double eye[3]={3,4,5}; /********** プロトタイプ宣言 ************/ void display(); void reshape(int w, int h); void myMouseFunc(int button,int state,int x,int y); void myMouseMotion(int x,int y); void keyboard(unsigned char key, int x, int y); void DRAW_XYZ(); void DRAW_TRI(); void DrawScreen(double fovy,double eyeX,double eyeY,double eyeZ,double znear); //----------- OpenGLの初期設定 ---------------// void GLUT_INIT() { glutInitDisplayMode(GLUT_RGBA| GLUT_DOUBLE | GLUT_DEPTH); //ダブルバッファ、Zバッファ glutInitWindowSize(640,480); glutCreateWindow("Draw Screen"); } void GLUT_CALL_FUNC() { glutDisplayFunc(display); glutReshapeFunc(reshape); glutMouseFunc(myMouseFunc); glutMotionFunc(myMouseMotion); glutKeyboardFunc(keyboard); } void MY_INIT() { glClearColor(1.0, 1.0, 1.0, 1.0); glEnable(GL_DEPTH_TEST); //Zバッファ有効化 } /********[メイン関数]********/ int main(int argc, char **argv) { glutInit(&argc,argv); GLUT_INIT(); GLUT_CALL_FUNC(); MY_INIT(); glutMainLoop(); return 0; } /********[ここからコールバック]****************************************/ void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(eye[0],eye[1],eye[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glRotated(ObjRot.xAngle,1,0,0); glRotated(ObjRot.yAngle,0,1,0); DRAW_XYZ(); //XYZ軸の描画 glPushMatrix(); //行列退避 glTranslated(1,0,0); //[1].並行移動 glColor3d(0,1,0); DRAW_TRI(); glPopMatrix(); //行列を戻す DrawScreen(30,eye[0],eye[1],eye[2],2); //スクリーン描画(fovy,znearをわたす) glColor3d(1,1,1); //色のリセット glutSwapBuffers(); } void reshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); //行列モード切替 glLoadIdentity(); //行列初期化 gluPerspective(30.0, static_cast<double>(w)/h, 2.0, 100.0); glMatrixMode(GL_MODELVIEW); //行列モード切替 } void timer(int t) { glutPostRedisplay(); glutTimerFunc(t,timer,17); //タイマー関数 } void myMouseFunc(int button,int state,int x,int y) { if(button == GLUT_LEFT_BUTTON &&state == GLUT_DOWN) { MouseStatus.Xstart = x; MouseStatus.Ystart = y; MouseStatus.flag = true; } else { MouseStatus.flag =false; } } void myMouseMotion(int x,int y) { int xdis,ydis; if(MouseStatus.flag == false)return; xdis = x - MouseStatus.Xstart; ydis = y - MouseStatus.Ystart; ObjRot.xAngle += (double)ydis * MouseStatus.weight; ObjRot.yAngle += (double)xdis * MouseStatus.weight; MouseStatus.Xstart = x; MouseStatus.Ystart = y; display(); } void keyboard(unsigned char key, int x, int y) { switch(key) { case 'r': ObjRot.xAngle = 0; ObjRot.yAngle = 0; break; case 'q': case '\033': exit(0); break; } display(); } //----------- ここから各種関数 ----------------// void DRAW_XYZ() { glBegin(GL_LINES); glColor3d(0,1,0);//x glVertex2d(-100,0); glVertex2d(100, 0); glColor3d(1,0,0);//y glVertex2d(0,0); glVertex2d(0,100); glColor3d(0,0,1);//z glVertex3d(0,0,-100); glVertex3d(0,0, 100); glEnd(); } void DRAW_TRI() { glBegin(GL_TRIANGLES); glVertex2d(0,1); glVertex2d(-0.5, 0); glVertex2d(0.5, 0); glEnd(); } void DrawScreen(double fovy,double eyeX,double eyeY,double eyeZ,double znear) { static int viewport[4];//ビューポート取得 glGetIntegerv(GL_VIEWPORT, viewport); static double top = znear * tan(0.0174532925*fovy/2.0); static double left = static_cast<double>(viewport[2])/viewport[3] * top; static double theta = atan2(eyeX,eyeZ)/0.0174532925; static double fai = atan2(eyeY,sqrt(eyeX*eyeX+eyeZ*eyeZ))/0.0174532925; static double length = sqrt(eyeX*eyeX+eyeY*eyeY+eyeZ*eyeZ);//原点からの距離 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); glColor3f(1,0,1); glPushMatrix(); glRotated(theta,0,1,0); glRotated(fai,-1,0,0); glTranslatef(0,0,length-znear); glRectd(-left,top,left,-top); glPopMatrix(); glColor3f(1,1,1); glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); }