// // Computergraphik I // Prof. Dr. Juergen Doellner // Sommersemester 2001 // // Rahmenprogramm fuer Aufgabenzettel 6 // #include "cgapplication.h" // Diese Variable enthaelt einen Zeiger auf die aktive Anwendung. static CGApplication* activeApplication_ = 0; // Drag'n'Drop static int lastDragDropX_ = 0; static int lastDragDropY_ = 0; CGApplication::CGApplication() { assert(!activeApplication_); // Es ist nur eine aktive Anwendung erlaubt!!! activeApplication_ = this; } CGApplication::~CGApplication() { activeApplication_ = 0; } // Auf diese Ereignisse wird default-maessig nicht reagiert: void CGApplication::onInit() { } void CGApplication::onButton(MouseButton button, int x, int y) { } void CGApplication::onMove(int x, int y) { } void CGApplication::onDrag(double dx, double dy) { } void CGApplication::onKey(unsigned char key) { } void CGApplication::onIdle() { } // glut-Callback fuer den Zeichenaufruf static void displayFunc() { assert(activeApplication_); activeApplication_->onDraw(); } // glut-Callback fuer die Aenderung der Fenstergroesse static void reshapeFunc(int newWidth, int newHeight) { assert(activeApplication_); activeApplication_->onSize(newWidth, newHeight); } // glut-Callback fuer das Druecken einer Maustaste static void mouseFunc(int button, int state, int x, int y) { assert(activeApplication_); if(state == GLUT_DOWN) { y = glutGet(GLenum(GLUT_WINDOW_HEIGHT)) - y; // Koordinaten-Ursprung: links unten!!! if(button == GLUT_LEFT_BUTTON) { activeApplication_->onButton(CGApplication::LeftMouseButton, x, y); } else { activeApplication_->onButton(CGApplication::RightMouseButton, x, y); } lastDragDropX_ = x; lastDragDropY_ = y; } } // glut-Callback fuer das Ziehen bei gedrueckter Maustaste static void motionFunc(int x, int y) { assert(activeApplication_); y = glutGet(GLenum(GLUT_WINDOW_HEIGHT)) - y; // Koordinaten-Ursprung: links unten!!! double distanceX = x - lastDragDropX_; double distanceY = y - lastDragDropY_; activeApplication_->onMove(x, y); double relativeX = distanceX / GLenum(GLUT_WINDOW_WIDTH); double relativeY = distanceY / GLenum(GLUT_WINDOW_HEIGHT); cout << "Dragging the line: " << relativeX << "/" << relativeY << endl; activeApplication_->onDrag(relativeX, relativeY); lastDragDropX_ = x; lastDragDropY_ = y; } // glut-Callback fuer einen Tastendruck static void keyboardFunc(unsigned char key, int x, int y) { assert(activeApplication_); activeApplication_->onKey(key); } // glut-Callback fuer einen Tastendruck static void idleFunc() { assert(activeApplication_); activeApplication_->onIdle(); } void CGApplication::start(const char* windowTitle, bool doubleBuffering, unsigned long width, unsigned long height) { // Fordert ein OpenGL-Fenster im RGB-Format mit oder ohne Double-Buffering an: glutInitDisplayMode(GLUT_RGB | (doubleBuffering ? GLUT_DOUBLE : GLUT_SINGLE)); // Legt die Fenstergroesse fest: glutInitWindowSize(width, height); // Erzeugt das OpenGL-Fenster mit dem entsprechenden Namen: glutCreateWindow(windowTitle); // Registriere die oben definierten Callbacks fuer die // entsprechenden glut-Ereignisse: glutDisplayFunc(displayFunc); glutReshapeFunc(reshapeFunc); glutMouseFunc(mouseFunc); glutMotionFunc(motionFunc); glutKeyboardFunc(keyboardFunc); glutIdleFunc(idleFunc); // Zeige das OpenGL-Fenster auf dem Bildschirm an glutShowWindow(); // Rufe die Methode zur Initialisierung von OpenGL auf: onInit(); // Starte die Verarbeitung der glut-Ereignisse: glutMainLoop(); } void CGApplication::swapBuffers() { glutSwapBuffers(); }