Μάθημα 4ο

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

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

1ο βήμα


Κάντε compile το πρόγραμμα. Θα πρέπει να βλέπετε δύο τσαγιέρες.

Βρείτε και ξεσχολιάστε το κομμάτι κώδικα (01) στη setup και αλλάξτε το χρώμα της δεύτερης τσαγιέρας σε glColor4f(0.3, 0.2, 0.9, 0.5) (δηλαδή την μετονομάζουμε από 3f σε 4f και προσθέτουμε άλλη μια τιμή στο τέλος).
Παρατηρήστε τον κώδικα (01) που ξεσχολιάσατε στη setup. Ήταν οι εντολές.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Με την πρώτη εντολή ενεργοποιούμε τη διαφάνεια στο OpenGL. Με τη δεύτερη εντολή λέμε στο OpenGL πώς να τη χειριστεί. Στην περίπτωσή μας πολλαπλασιάζουμε το χρώμα που βρίσκεται ήδη στον buffer με 1-α (όπου α, η τέταρτη τιμή στην glColor4f, όπως εξηγείται παρακάτω), πολλαπλασιάζουμε με α το χρώμα του αντικειμένου που είναι διαφανές, και τα προσθέτουμε. Δηλαδή ο τύπος είναι:
Free Image Hosting
όπου: src = το αντικείμενο που ζωγραφίζουμε και
dest = τα αντικείμενα που βρίσκονται ήδη στον buffer

Όσον αφορά την glColor4f(0.3, 0.2, 0.9, 0.5); η τέταρτη παράμετρος είναι ο παράγοντας α που αναφέρεται παραπάνω. Παίρνει τιμές από 0.0 εώς 1.0, με το 0.0 να είναι πλήρης διαφάνεια και το 1.0 πλήρης αδιαφάνεια (για τον τύπο που χρησιμοποιούμε).

2ο βήμα


Βάλτε σε σχόλια τον κώδικα 02 και στην setup και στην render. Έως τώρα το OpenGL έβαζε σωστά τα πολύγωνα ως προς το βάθος. Αυτό συνέβαινε επειδή χρησιμοποιούσε τον αλγόριθμο z-buffer (glEnable(GL_DEPTH_TEST);).

Με τις εντολές
glDepthFunc(GL_LEQUAL);
glClearDepth(1.0);
αρχικoποιούμε το z-buffer ώστε οι αρχικές τιμές του να είναι το z του πίσω (far) επιπέδου αποκοπής (1.0) και ορίζουμε να σχεδιάζονται τα αντικείμενα με τη μικρότερη z τιμή (GL_EQUAL - πιο κοντά σε «εμάς»).

Με την εντολή
glClear(GL_DEPTH_BUFFER_BIT);
σε κάθε καρέ ξανα-αρχικοποιούμε τις τιμές του z-buffer.

3ο βήμα

Μέχρι τώρα στο OpenGL δεν κάναμε διάκριση μεταξύ των πολυγώνων που κοιτάνε προς τον παρατηρητή (έμπροσθεν, front-facing) και αυτών που δεν κοιτάνε (όπισθεν, back-facing). Στην πραγματικότητα όμως μπορούμε να τα χειριστούμε διαφορετικά. Πρώτα ορίζουμε με ποια φορά είναι δηλωμένες οι κορυφές για τα έμπροσθεν πολύγωνα με την εντολή glFrontFace που παίρνει σαν όρισμα τα GL_CCW/GL_CW (Counter-ClockWise,ClockWise). Στο κομμάτι κώδικα 03 αλλάζουμε το CW σε CCW. Με αυτόν τον τρόπο βλέπουμε τα πίσω τρίγωνα στις τσαγιέρες (τα αντικείμενα του GLUT ακολουθούν από default την σύμβαση CW). Στο κομμάτι 03 πάλι, σχολιάζουμε το glEnable(GL_CULL_FACE). Αυτό επιτρέπει και στα μπροστινά και στα πίσω τρίγωνα να ζωγραφίζονται, οπότε αχρηστεύει την χρήση του glFrontFace. Με αυτόν τον τρόπο όμως ζωγραφίζουμε πάντα όλα τα τρίγωνα οπότε η σκηνή θα θέλει περίπου τον διπλάσιο χρόνο για να ζωγραφιστεί, οπότε για λόγους απόδοσης το αφήνουμε ενεργοποιημένο.
Στο κομμάτι 04 αλλάξτε το GL_FILL με GL_LINE. Αυτό ορίζει στο OpenGL να ζωγραφίζει μόνο τις ακμές από κάθε τρίγωνο και όχι ολόκληρο.

4ο βήμα


Ο φωτισμός ενός αντικειμένου στο OpenGL κάνει ρεαλιστικότερη την παράστασή του και εξαρτάται από τέσσερις παραμέτρους. Το φωτισμό που δέχεται από το περιβάλλον του (ambient), το φωτισμό που προέρχεται από τη διάχυση του φωτός που προσπίπτει στο αντικείμενο από τις φωτεινές πηγές (diffuse), το φωτισμό που προέρχεται από την ανάκλαση του φωτός που προσπίπτει στο αντικείμενο από τις φωτεινές πηγές (specular) και το φως που εκπέμπει το αντικείμενο (emission). Στα πλαίσια του εργαστηρίου θα ασχοληθούμε μόνο με το φωτισμό περιβάλλοντος και το φωτισμό από διάχυση.

Στους πίνακες
GLfloat ambientLight[] = { 0.3, 0.3, 0.3, 1.0 };
GLfloat diffuseLight[] = { 0.7, 0.7, 0.7, 1.0 };
ορίζουμε τις δύο αυτές παραμέτρους. Τα στοιχεία των πινάκων είναι κατά σειρά η ένταση των χρώματων Red, Green, Blue και το Alpha. Οι τιμές που έχουμε δώσει στο παράδειγμά μας, κοθορίζουν ένα φωτισμό περιβάλλοντος με μικρή ένταση και ένα ελαφρώς έντονο λευκό φωτισμό από διάχυση.

Με την εντολή
GLfloat lightPos[] = { 0.0, 30.0,50.0,0.0 };
καθορίζουμε τις συντεταγμένες της φωτεινής πηγής x,y,z,w. Όταν το w είναι 0.0 τότε η φωτεινή πηγή βρίσκεται στο άπειρο, ενώ όταν είναι 1.0 βρίσκεται στο x,y,z.

Δοκιμάστε να δώσετε διάφορες τιμές στα χρώματα για να δείτε τις αλλαγές στο χρώμα του αντικειμένου από το χρώμα και την ένταση του φωτισμού. Επίσης δοκιμάστε να μετακινήσετε τη φωτεινή πηγή σε διάφορες θέσεις στο χώρο και δείτε το αποτέλεσμα.

Τέλος με τις παρακάτω εντολές δίνονται οι παραπάνω ιδιότητες στο GL_LIGHT0: glLightfv( GL_LIGHT0, GL_AMBIENT, ambientLight );
glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseLight );
glLightfv( GL_LIGHT0, GL_POSITION, lightPos );

και με τις εντολές
glEnable(GL_LIGHTING);
gEnable(GL_LIGHT0);
ενεργοποιούμε το φωτισμό και τη φωτεινή πηγή 0.
Τέλος αν ενεργοποιήσουμε το κομμάτι κώδικα 05 προσθέτουμε και specular φωτισμό.
Σαν πείραμα δοκιμάστε να κάνετε την φωτεινή πηγή να περιστρέφεται γύρω από τις τσαγιέρες.

5ο βήμα

Ξεσχολιάστε τον κώδικα 06 για να τυπωθεί κείμενο στην οθόνη. Χρησιμοποιούμε την υλοποίηση της GLUT η οποία ζωγραφίζει τα fonts με γραμμες. Η βασική συνάρτηση είναι η glutStrokeCharacter η οποία καλείται μέσα στην συνάρτηση keimeno. Οι υπόλοιπες συναρτήσεις είναι για να θέτουνε το μέγεθος των χαρακτήρων και να επαναφέρουν τους πίνακες μετασχηματισμών στην αρχική τους θέση. Ο συγκεκριμένος τύπος κειμένου δημιουργεί 3Δ γεωμετρία (γραμμές), οπότε ότι έχουμε μάθει για τους 3Δ μετασχηματισμούς ισχύει και εδώ.










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

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

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