Category: Γ' Εξάμηνο: OpenGL Published: Tuesday, 16 February 2016 Written by Γεώργιος Παπαλουκάς

OpenGL: Μάθημα 7ο - Αλληλεπίδραση χρήστη (ποντίκι)

Πηγές: https://github.com/sprintr/opengl-examples και http://www.lighthouse3d.com/tutorials/glut-tutorial/the-mouse-

Ανίχνευση Mouse Clicks

Η  GLUT παρέχει τρόπο να καταχωρηθεί η συνάρτηση που είναι υπεύθυνη για το χειρισμό συμβάντων, προερχόμενων από mouse clicks. Ονομάζεται glutMouseFunc.

void glutMouseFunc(void (*func)(int button, int state, int x, int y));

 όπου 

func ? το όνομα της συνάρτησης που θα χειριστεί τα mouse click events

Η εν λόγω συνάρτηση έχει αναγκαστικά τέσσερις παραμέτρους.

Η πρώτη παράμετρος αναφέρεται στο είδος του κουμπιού που πατιέται και έχει μία από τις επόμενες τιμές:

GLUT_LEFT_BUTTON

GLUT_MIDDLE_BUTTON

GLUT_RIGHT_BUTTON

Η δεύτερη παράμετρος σχετίζεται με την κατάσταση του κουμπιού τη στιγμή που πυροδοτείται η συνάρτηση χειρισμού του συμβάντος π.χ. πατημένο ή ελευθερωμένο (ξεπατημένο). Πιθανές τιμές: 

GLUT_DOWN

GLUT_UP

Όταν πυροδοτείται (ανακαλείται) η συνάρτηση χειρισμού mouse event με κατάσταση GLUT_DOWN, η εφαρμογή θεωρεί ότι θα ακολουθήσει ένα GLUT_UP ακόμη κι αν το ποντίκι μετακινηθεί εκτός του παραθύρου.

Οι υπόλοιπες δύο παράμετροι μας πληροφορούν για τις  (x,y) συντεταγμένες του δείκτη του ποντικιού αναφορικά με το πάνω αριστερά άκρο της χρήσιμης περιοχής του παραθύρου. 

Ανίχνευση κίνησης 

Η GLUT παρέχει σε μια εφαρμογή δυνατότητες ανίχνευσης της κίνησης του ποντικιού. Υπάρχου δύο είδη κινήσεων τα οποία χειρίζεται η GLUT: ενεργητική και παθητική κίνηση. Η ενεργητική κίνηση υφίσταται όταν ο δείκτης του ποντικιού κινείται ενώ ένα κουμπί είναι πατημένο. Η παθητική κίνηση σημαίνει κίνηση του δείκτη του ποντικιού χωρίς ταυτόχρονο πάτημα κάποιου κουμπιού. Αν μια εφαρμογή καταγράφει την κίνηση του ποντικιού τότε θα δημιουργείται ένα συμβάν ανά πλαίσιο (frame) καθόλη την περίοδο κίνησης του δείκτη.

Το callback registration υλοποιείται με τη χρήση δύο συναρτήσεων:

void glutMotionFunc(void (*func) (int x,int y)); // καταγραφή ενεργητικής κίνησης

void glutPassiveMotionFunc(void (*func) (int x, int y)); // καταγραφή παθητικής κίνησης

όπου

func ? η υπεύθυνη συνάρτηση για τον αντίστοιχο τύπο κίνησης.

Οι παράμετροι (x,y) της παραπάνω συνάρτησης είναι οι συντεταγμένες του δείκτη του ποντικιού αναφορικά με το πάνω αριστερά άκρο της χρήσιμης περιοχής του παραθύρου.

Ανίχνευση εισόδου / εξόδου του δείκτη του ποντικιού στο / από το παράθυρο

Η GLUT είναι ικανή να ανιχνεύει πότε ο δείκτης του ποντικιού εισέρχεται στην περιοχή παραθύρου και πότε εξέρχεται από αυτή. Μια callback function μπορεί να καταχωρηθεί για το χειρισμό των δύο αυτών συμβάντων. Η υλοποίηση του  callback registration γίνεται με την glutEntryFunc:

void glutEntryFunc(void (*func)(int state));

όπου

func ? η συνάρτηση χειρισμού των συμβάντων.

Η παράμετρος state της παραπάνω συνάρτησης μας πληροφορεί αν ο δείκτης του ποντικιού εισήλθε ή εξήλθε του παραθύρου.

Η GLUT ορίζει δύο σταθερές για να καλύψει τις δύο αμοιβαία αποκλειόμενες καταστάσεις:

GLUT_LEFT

GLUT_ENTERED

Παράδειγμα χρήσης mouse events 

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <iostream>

using namespace std;

void init();
void display();

float a = 200.0, b= 200.0;

void setPoint(float x, float y){
    glColor3f(1.0, 0.0, 0.0);
    glBegin(GL_POINTS);
        glVertex2f(x,y);
    glEnd();
}

void init(){
    glClearColor(1.0,1.0,1.0,1.0);
    gluOrtho2D(0.0, 400.0, 0.0, 300.0);
}

void display(){
    glClear( GL_COLOR_BUFFER_BIT);
    glPointSize(10.0);

    setPoint(a,b);

    glFlush();
}

void mouse(int mouse, int state, int x, int y){
    switch(mouse){
        case GLUT_LEFT_BUTTON:
            if(state == GLUT_DOWN){
                cout << x << " -> " << y << endl;
                a = x/1.0;
                b = 300.0 - (y/1.0);

                glutPostRedisplay();
            }
        break;

    }

}

int main(int argc, char* argv[]){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowSize(400,300);
    glutInitWindowPosition(200,100);
    glutCreateWindow("OpenGL Program");

    init();
    glutDisplayFunc(display);
    glutMouseFunc(mouse);

    glutMainLoop();

    return 0;

}

 

Hits: 356