#ifndef ATS_GLUTXX_H #define ATS_GLUTXX_H #include #include "ats_component.h" #include /******************************************************** * class Glutxx * GLUTのラッパークラス。細かい指定はできない。 * staticなメンバ関数はC言語のcallbackに呼ばせるため。( * thisポインタがない。) ********************************************************/ // floatからdoubleへの切りつめを解除 #pragma warning(disable : 4305) namespace ats { template class Glutxx { protected: static int m_button, m_state, m_x, m_y; static GLfloat m_scale; static GLfloat m_rot_x, m_rot_y, m_rot_z; static GLfloat m_rot_matrix[16]; static Glutxx* m_instance; static GLenum m_front, m_back; Glutxx(int* argc, char** argv, int x, int y); Glutxx(const Glutxx&) {}; static void DrawText(); static void OnAnimation(); static void OffAnimation(); static void idle(); static void menu(int value); static void display(); static void reshape(int, int); static void keyboard(unsigned char, int, int); static void mouse(int, int, int, int); static void motion(int, int); public: /******************************************************* * コンストラクタを隠し、instance()からのみオブジェクトを * 生成することでインスタンスの数を制御する。 *******************************************************/ static Glutxx* instance(int* argc, char** argv, int x, int y); virtual ~Glutxx(); static std::list*> m_draw_list; void loop(); }; // スタティック変数 --------------------------------------------------- template std::list*> Glutxx::m_draw_list; template Glutxx* Glutxx::m_instance = 0; template int Glutxx::m_button = 0; template int Glutxx::m_state = 0; template int Glutxx::m_x = 0; template int Glutxx::m_y = 0; template GLfloat Glutxx::m_rot_x = 0; template GLfloat Glutxx::m_rot_y = 0; template GLfloat Glutxx::m_rot_z = 0; template GLfloat Glutxx::m_rot_matrix[16] = {0}; template GLfloat Glutxx::m_scale = 1; template GLenum Glutxx::m_front = GL_FILL; template GLenum Glutxx::m_back = GL_LINE; // コンストラクタ ------------------------------------------------------ template Glutxx::Glutxx(int* argc, char** argv, int x, int y) { const int WINDOWSYSTEM_POSITION = -1; glutInit(argc, argv); glutInitWindowSize(x, y); glutInitWindowPosition(WINDOWSYSTEM_POSITION, WINDOWSYSTEM_POSITION); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutCreateWindow("3DViewer"); glutDisplayFunc (display); glutReshapeFunc (reshape); glutMouseFunc (mouse); glutMotionFunc (motion); glutKeyboardFunc(keyboard); glutCreateMenu (menu); glutAddMenuEntry("OnAnimation", 1); glutAddMenuEntry("OffAnimation", 2); glutAddMenuEntry("Exit ESC", 3); glutAttachMenu (GLUT_RIGHT_BUTTON); glClearColor(0, 0, 0, 0); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); static GLfloat spec[] = { 0.5, 0.5, 0.5, 1 }; static GLfloat shin[] = { 0.5 }; static GLfloat diff[] = { 1, 1, 1, 0 }; static GLfloat ambi[] = { 0.1, 0.1, 0.1, 1 }; static GLfloat l_pos[] = { 20, 20, 20, 0 }; glShadeModel(GL_SMOOTH); glLightfv(GL_LIGHT0, GL_POSITION, l_pos); glLightfv(GL_LIGHT0, GL_DIFFUSE, diff); glLightfv(GL_LIGHT0, GL_AMBIENT, ambi); glLightfv(GL_LIGHT0, GL_SPECULAR, spec); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); } // 単一インスタンスの生成 --------------------------------------------- template Glutxx* Glutxx::instance(int* argc, char** argv, int x, int y) { if(m_instance == 0){ m_instance = new Glutxx(argc, argv, x, y); return m_instance; } else { return m_instance; } } // デストラクタ -------------------------------------------------------- template Glutxx::~Glutxx() { if(m_instance != 0){ delete m_instance; m_instance = 0; for( std::list*>::iterator itr = m_draw_list.begin(); itr != m_draw_list.end(); itr++){ delete *itr; } } } // テキスト描画関数 ---------------------------------------------------- template void Glutxx::DrawText() { glDisable(GL_LIGHTING); glColor3f(1,1,1); char str_menu[] = "left drag : rotate"; char str_menu2[] = "right click : exit"; glRasterPos2f(0, 1.6); int i; for(i=0; str_menu[i]; i++){ glutBitmapCharacter(GLUT_BITMAP_8_BY_13, str_menu[i]); } glRasterPos2f(0, 1.4); for(i=0; str_menu[i]; i++){ glutBitmapCharacter(GLUT_BITMAP_8_BY_13, str_menu2[i]); } } // 描画関数 ------------------------------------------------------------ template void Glutxx::display() { using namespace std; glMatrixMode(GL_MODELVIEW); glGetFloatv(GL_MODELVIEW_MATRIX, m_rot_matrix); glLoadIdentity(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); DrawText(); glEnable(GL_LIGHTING); // 視点の回転を反映 glRotatef(m_rot_y, 1, 0, 0); glRotatef(m_rot_x, 0, 1, 0); glMultMatrixf(m_rot_matrix); glPushMatrix(); static GLfloat l_pos[] = { 100, 100, 100, 0 }; // 保持しているオブジェクトを描画 for(list*>::iterator itr = m_draw_list.begin(); itr != m_draw_list.end(); itr++){ (*itr)->Draw(); } glutWireCube(3); glPopMatrix(); // 描画バッファ交換 glutSwapBuffers(); } // メインループ -------------------------------------------------------- template void Glutxx::loop() { glutMainLoop(); } template void Glutxx::reshape(int w, int h) { glViewport(0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 0.001, 1000.0); gluLookAt(0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } // メニュールーチン ---------------------------------------------------- template void Glutxx::menu(int value) { switch(value){ case 1: OnAnimation(); break; case 2: OffAnimation(); break; case 3: exit(0); break; default: break; } } template void Glutxx::keyboard(unsigned char key, int x, int y) { const int ESC = 27; if(key == ESC){ exit(0); } } template void Glutxx::mouse(int button, int state, int x, int y) { m_button = button; m_state = state; m_x = x; m_y = y; } template void Glutxx::motion(int x, int y) { if(GLUT_DOWN == m_state){ switch(m_button){ case GLUT_LEFT_BUTTON: m_rot_y = y - m_y; m_rot_x = x - m_x; break; case GLUT_RIGHT_BUTTON: //if(m_scale <= 0){ m_scale = 0.000000001; } m_scale += 0.1; break; case GLUT_MIDDLE_BUTTON: m_scale -= 0.1; default: break; } m_x = x; m_y = y; glutPostRedisplay(); } } template void Glutxx::idle() { for(std::list*>::iterator itr = m_draw_list.begin(); itr != m_draw_list.end(); itr++){ (*itr)->UpdateTime(0); } glutPostRedisplay(); } template void Glutxx::OnAnimation() { glutIdleFunc(Glutxx::idle); } template void Glutxx::OffAnimation() { glutIdleFunc(0); } } #endif // #ifndef ATS_GLUTXX_H