#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 DrawScreenFrustum(double Left,double Top,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(); //行列を戻す DrawScreenFrustum(-1,1,eye[0],eye[1],eye[2],2); //スクリーン描画(left,top,znearをわたす) glColor3d(1,1,1); //色のリセット glutSwapBuffers(); } void reshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); //行列モード切替 glLoadIdentity(); //行列初期化 glFrustum(-1,1,-1,1,2,200); 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 DrawScreenFrustum(double Top,double Left,double eyeX,double eyeY,double eyeZ,double znear) { 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); }