Μάθημα 3ο

Τρίτο Μάθημα Γραφικών - OpenGL

Τη θεωρία και τον κώδικα του μαθήματος μπορείτε να τα βρείτε εδώ.
Τις θεωρητικές και πρακτικές ασκήσεις του μαθήματος μπορείτε να τις βρείτε εδώ.

1ο βήμα


Κάντε compile το πρόγραμμα. Θα πρέπει να βλέπετε ένα torus (ένα στερεό που μοιάζει με λουκουμά).

2ο βήμα

Βρείτε και σχολιάστε το κομμάτι κώδικα (00) και ξεσχολιάστε το κομμάτι κώδικα “(01)-pumpkin”. Αυτό που κάνει ο κώδικας αυτός είναι να σχεδιάζει 9 tori (ο πληθυντικός του torus), το κάθε ένα περιστρεμμένο κατά 20 μοίρες γύρω από τον άξονα Ψ σε σχέση με το προηγούμενο. Έτσι σχηματίζεται μια κολοκύθα.

3ο βήμα

Ξεσχολιάστε και το κομμάτι κώδικα (02a). Με την εντολή που μόλις ξεσχολιάσατε, η κολοκύθα μεταφέρεται κατά 100 μονάδες μακριά μας. Θα παρατηρήσετε όμως ότι πάλι φαίνεται το ίδιο μεγάλη με πριν. Το ίδιο θα συνέβαινε όσες μονάδες μακριά σας και αν το μεταφέρετε. Μπορείτε να δοκιμάσετε. Μόνο να έχετε υπόψη σας ότι αν υπερβείτε το «far clipping plane»-«μακρινό επίπεδο αποκοπής», η κολοκύθα θα σταματήσει να φαίνεται στην οθόνη σας.

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


Αυτό επιτυγχάνεται στο πρόγραμμα με την εντολή:
gluPerspective(60.0, (float)w/(float)h, 1.0, 500.0);
Οι παράμετροι της εντολής αυτής είναι οι εξής:
gluPerspective(θ, aspect, near, far);
Στην Resize() αλλάξτε την υπάρχουσα glOrtho() στην παραπάνω gluPerspective() , κομμάτι κώδικα (02b).
Οι παράμετροι επεξηγούνται στην εικόνα 1.
Free Image Hosting
Εικόνα 1 Προοπτική Προβολή – Επεξήγηση Παραμέτρων

Αυτό που κάνει σε γενικές γραμμές η προοπτική προβολή είναι ότι διαιρεί τις Χ,Ψ συντεταγμένες ενός αντικειμένου με το Ζ .
Αν τώρα «παίξετε» με διάφορες τιμές απομάκρυνσης της κολοκύθας θα τη δείτε να αλλάζει μέγεθος ανάλογα με την απόστασή της από τον παρατηρητή.

4ο βήμα

Ξανασχολιάστε το κομμάτι κώδικα (01) και ξεσχολιάστε το κομμάτι κώδικα (03). Αυτό που κάνει ο κώδικας αυτός είναι να ζωγραφίζει, σε απόσταση 100 μονάδες από εμάς, δύο tori. Το πρώτο ζωγραφίζεται 30 μονάδες προς τα δεξιά και το δεύτερο 30 μονάδες προς τα αριστερά.
Θα παρατηρήσετε όμως ότι το δεύτερο σχεδιάζεται στο κέντρο του παραθύρου.

Όπως θα θυμάστε το OpenGL είναι μια μηχανή καταστάσεων. Όταν χρησιμοποιούμε την εντολή
glTranslatef(30.0, 0.0, 0.0);
βάζουμε το OpenGL σε μια νέα κατάσταση όπου ο πίνακας μετασχηματισμών μετακινεί όλα τα ακόλουθα αντικείμενα κατά 30 μονάδες προς την κατεύθυνση του θετικού άξονα Χ (προς τα δεξιά). Οταν εκτελεσθεί η εντολή
glTranslatef(-30.0, 0.0, 0.0);
ο καινούριος πίνακας μετασχηματισμού που προκύπτει από τη σύνθεση των δύο μετασχηματισμών (30 δεξιά και 30 αριστερά) θα αφήνει τα αντικείμενα στο κέντρο του παραθύρου. Για να βάλουμε το δεύτερο torus 30 μονάδες στα αριστερά του κέντρου του παραθύρου θα πρέπει, αντί για την τελευταία, να χρησιμοποιήσουμε την εντολή
glTranslatef(-60.0, 0.0, 0.0);

Για την αποφυγή τέτοιων καταστάσεων το OpenGL μας παρέχει δύο εντολές, τις glPushMatrix και glPopMatrix. Η δομή της στοίβας είναι χρήσιμη για την εύκολη πραγματοποίηση ιεραρχικών μετασχηματισμών (όπως θα δούμε αμέσως πιο κάτω). Με τις εντολές glPushMatrix, glPopMatrix ελέγχουμε ποιος πίνακας είναι ενεργός. Η εντολή glPushMatrix τοποθετεί αντίγραφο του τρέχοντα μετασχηματισμού στην κορυφή της στοίβας. Ο μετασχηματισμός που εφαρμόζεται στα αντικείμενά μας είναι αυτός που προκύπτει από τη σύνθεση όλων των μετασχηματισμών που βρίσκονται στη στοίβα μετά την εντολή glLoadIdentity(). Αντίστοιχα η εντολή glPopMatrix αφαιρεί από τη στοίβα τον πίνακα που βρίσκεται στην κορυφή της. Με απλά λόγια η εντολή glPushMatrix σημαίνει «θυμήσου που ήσουν» και η εντολή glPopMatrix σημαίνει «πήγαινε εκεί που ήσουν». Αυτό φαίνεται και στην παρακάτω εικόνα. Το OpenGL χρησιμοποιεί τρία είδη μετασχηματισμών: αντικειμένων (GL_MODELVIEW), προβολής (GL_PROJECTION) και υφής (GL_TEXTURE). Συνήθως πρώτα επιλέγουμε το είδος του μετασχηματισμού με την glMatrixMode();, μετά τον αρχικοποιούμε με την glLoadIdentity(); και τέλος προσθέτουμε τη σειρά μετασχηματισμών που θέλουμε.
Free Image Hosting
Εικόνα 2 glPushMatrix , glPopMatrix

Στο κομμάτι κώδικα (04) μπορείτε να δείτε το παράδειγμα (03) γραμμένο με glPushMatrix, glPopMatrix. Αντικαταστήστε και τρέξτε το.

5ο βήμα


Κάντε compile το πρόγραμμα αφού ξεσχολιάσετε το 05 και τον κώδικα της Idle() και σχολιάσετε τα υπόλοιπα. Θα πρέπει να βλέπετε ένα μικρό «καροτσάκι» να αναπηδά στην οθόνη σας με σταθερή ταχύτητα.

Η κίνησή του υλοποιείται στην idle. Το καροτσάκι ξεκινάει με ταχύτητα v ίση με 0.0 (στην αρχή του αρχείου visuals.cpp). Όσο το καροτσάκι δεν έχει πέσει κάτω από το επίπεδο ΧΖ (Υ<=0), η ταχύτητά του αυξάνεται κατά g ίσο με 0.1 και αυτό (αρνητικό) προστίθεται στη θέση του στον άξονα Υ. Άρα είναι σαν να πέφτει με «ομαλά επιταχυνόμενη» κίνηση (με υποθετικό dt=1). Όταν κάποια στιγμή πέσει κάτω από το επίπεδο ΧΖ, τότε η ταχύτητά του αντιστρέφεται και γίνεται θετική, ενώ ο μηχανισμός με το g παραμένει ο ίδιος. Άρα τώρα το καροτσάκι ανεβαίνει με «ομαλά επιβραδυνόμενη» κίνηση (με υποθετικό dt=1). Ώσπου σε κάποια στιγμή η ταχύτητά του θα μηδενιστεί και θα γίνει αρνητική και το καροτσάκι θα αρχίσει να πέφτει πάλι, ακριβώς όπως πριν. Όσον αφορά το σχεδιασμό του τώρα, στη Render αρχικά σχεδιάζεται το καροτσάκι με τη χρήση ενός κλιμακωμένου κύβου και τεσσάρων tori.












Το αποτέλεσμα της πρακτικής άσκησης θα πρέπει να είναι αυτής της μορφής.

Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου