OpenGL Η OpenGL είναι ένα χαμηλού επίπεδου API(application programmer interface) που μας επιτρέπει μια διεπαφή με graphics hardware. Το πλεονέκτημα της OpenGL σε σύγκριση με άλλα API είναι ό,τι είναι cross-platform δηλαδή τρέχει σε Linux,Windows,MacOS κ.α
OpenGL Σαν API χρησιμοποιείται αρκετά απο CAD εφαρμογές,παιχνίδια (πχ. Doom3) και επιστημονικές εφαρμογές για 3D Visualization. Το όνομα της προκύπτει απο τις λέξεις “Open Graphics Library”.
Αρχιτεκτονική OpenGL Η αρχιτεκτονική της OpenGL δουλέυει κυρίως με καταστάσεις (states). Δήλαδη ο προγραμματιστής ορίζει μια κατάσταση και η OpenGL κάνει render με βάση αυτη την κατάσταση μέχρι να γίνει αλλαγή κατάστασης. Πχ.Εάν θέλω να κάνω render με κόκκινο χρώμα,θέτω το χρώμα κόκκινο και κάνω render τα αντικειμένα που θέλω κτλ.
Αρχιτεκτονική OpenGL Αυτου του είδους η λογική ονομάζεται fixed-function. Βέβαια τα τελευταία χρόνια έχουν αρχίσει να στρέφονται σε λίγοτερο fixed-function λογικές και να υλοποιούν shaders.
OpenGL εφαρμογές Για να δημιουργήσουμε μια εφαρμογή OpenGL πρέπει πρώτα να κατασκευάσουμε την οθονή στην οποία θα γίνονται όλα τα draws. Οι βασικές συναρτήσεις για να το πετύχουμε αυτο είναι: glutInit glutInitDisplayMode glutInitWindowSize glutCreateWindow glutMainLoop
glutInit Η πρώτη συνάρτηση που θα δούμε είναι η glutInit(int * argcp,char **argvp). Ως ορίσματα παίρνει τα ορίσματα που παιρνάμε σε μια συνάρτηση main: τα argc και argv. Αυτο που κάνει η glutInit είναι να αρχικοποιεί την glut(OpenGL) και να φτιάχνει με την βοήθεια του συστήματος ένα παράθυρο. Επίσης διαχειρίζετε και ορίσματα απο την κονσόλα,αλλα τα ορισματα αυτα είναι window system dependent.
glutInitDisplayMode Η δευτέρη συνάρτηση που βλέπουμε είναι η glutInitDisplayMode(unsigned int mode). Στην ουσία αυτο που κάνει η συνάρτηση είναι να περνάει επιλογές για το παραθυρο μας. Οι επιλογές αυτες είναι καθορισμένες σε είδος και πλήθος απο την OpenGL.
glutInitWindowSize Αμέσως μετα ακολουθεί η συνάρτηση void glutInitWindowSize(int width, int height); Αυτη η συνάρτηση διαμορφώνει το μέγεθος του παραθύρου μας ανάλογα με τα ορίσματα width,height που θα περάσουμε.
glutCreateWindow int glutCreateWindow(char *name); H παραπάνω συνάρτηση δημιουργεί ένα top-level window με unique name για το σύστημα το ονόμα που περάσαμε σαν ορίσμα. Η τίμη που επιστρέφει είναι ένας μοναδικός ακέραιος window identifier.
glutMainLoop void glutMainLoop(void); Με την βοήθεια της συνάρτησης glutMainLoop μπαίνουμε στο event processing loop της GLUT. Η συνάρτηση πρέπει να κληθεί τουλάχιστον 1 φόρα σε ένα GLUT πρόγραμμα και δεν επιστρέφει ποτε.....
glEnable,glDisable Οπώς αναφέραμε πριν η OpenGL λειτουργεί με την λογική των states. Για να θέσουμε ένα OpenGL state χρησιμοποιούμε την συνάρτηση glEnable(GLenum cap) Για να το απενεργοποιήσουμε χρησιμοποιούμε την συνάρτηση glDisable(GLenum cap) Στην OpenGL υπάρχουν πάνω απο 40 προκαθορισμένα states οπως το GL_BLEND,GL_LIGHTING κ.α
OpenGL Primitives Οταν λέμε primitives εννοούμε διάφορες γεωμετρικές οντότητες οπως points,lines,triangles κ.α. Η OpenGL έχει πολλούς μηχανισμούς για την διαχείρηση των primitives οπώς VertexPointers,VBO(Vertex Buffer Objects) κ.α. Εμείς θα εξετάσουμε την Immediate Mode διαχείρηση.
glBegin,glEnd Για να αρχίσεις το rendering σε immediate mode πρέπει πρώτα να πεις στην OpenGL οτι κάνεις render ένα primitive. Για να το πετύχουμε αυτο χρησιμοποιούμε την συνάρτηση void glBegin( GLenum mode ) Aυτη η συνάρτηση λέει 2 πράγματα στην OpenGL 1)Ο,τι θες να αρχίσεις το drawing 2)Τι είδους primitives θες να κάνεις draw. Τα είδη των primitives είναι καθορισμένα απο την OpenGL.
glBegin,glEnd
glBegin,glEnd Εφόσον έχουμε ολοκληρώσει το draw πρεπει να προιδοποιήσουμε στην OpenGL. Αυτο το κανει η συνάρτηση glEnd(). Οτι υπάρχει ανάμεσα στις συναρτήσεις glBegin() & glEnd() είναι ο κώδικας του drawing.
OpenGL Colors Τις καταστάσεις των χρωμάτων στην OpenGL μπορούμε να τις αλλάξουμε με την βοήθεια μιας οικογένειας συναρτήσεων void glColor{3,4}{bsifd ubusui}(T compoments) void glColor{3,4}{bsifd ubusui}v(T compoments) Η συναρτήσεις με κατάληξη v δέχονται έναν πίνακα απο στοιχεία.
OpenGL Colors Aυτές οι συναρτήσεις καθορίζουν την κατάσταση των χρωμάτων red,green,blue(RGB) και alpha value. Οι αριθμοί που παίρνουν ως όρισμα είναι οι αντίστοιχες τίμες των χρωμάτων RBGA ανάλογα την συνάρτηση. Πχ. Αμα διαλέξουμε την glColor3f() θα πέρασουμε 3 αριθμούς ως όρισματα για τις τιμές των Red,Green,Blue αντίστοιχα. Η κλήση αυτων των συναρτήσεων γίνεται μόνο σε immediate mode ανάμεσα στις συναρτήσεις glBegin & glEnd για να έχουν το αντίστοιχο αποτελέσματα.
glVertex Ενα vertex είναι ένα σημείο στον χώρο το οποίο είναι μια κορυφή ενός πολυγώνου. Για να ζωγραφίσουμε ένα πολύγωνο πρέπει να δώσουμε στην OpenGL τις συντεταγμένες των κορυφών του. Αυτο το πετυχαίνουμε με την βοήθεια μιας οικογένειας συναρτήσεων: void glVertex {2,3,4}{d,f,i,s}() void glVertex {2,3,4}{d,f,i,s}v() Aυτες οι συναρτήσεις μας βοηθάνε να καθορίσουμε στην OpenGL τις συντεταγμένες των κορυφών ενός πολυγώνου.
glVertex Η κλήση αυτων των συναρτήσεων γίνεται μόνο σε immediate mode ανάμεσα στις συναρτήσεις glBegin & glEnd για να έχουν αποτελέσματα. Ως ορίσματα δέχονται τις συντεταγμένες μιας κορυφής στους αντίστοιχους άξονες(x,y,z). Ο αριθμός των ορισμάτων καθορίζετε απο την συνάρτηση που θα επιλέξουμε. Πχ. Αμα διαλέξουμε την συνάρτηση glVertex3f() τοτε θα περάσουμε 3 αριθμούς ως ορίσματα κτλ.
Matrices Oταν μετακινούμε ένα αντικείμενο στον χώρο στην πραγματικότητα το μεταφέρουμε απο το δικό του σύστημα αξόνων σε αλλο. Οταν κάνουμε render ένα 3D αντικείμενο τοτε αυτο περνάει απο 4 “μεταφορές” Αυτες ονομαστικά είναι: Modeling Tranformation Viewing Transformation Projection Transformation Viewport Transformation
Matrices
Matrices Στημ OpenGL έχουμε την συγχώνευση 2 matrix του Model & Viewing σε Modelview. Στην OpenGL υπάρχουν 4 matrices: Modelview Projection Color Texture Για να μετακινηθούμε ανάμεσα σε αυτά η OpenGL μας παρέχει την συνάρτηση: void glMatrixMode( GLenum mode)
Projections Στην OpenGL έχουμε 2 είδη projection: Orthographic(or parallel) Perspective Οταν καθορίζουμε ένα είδος projection εξυπηρετούμε 2 σκοπούς 1)Θέτουμε στον κόσμο μας κάποια όρια και οτι είναι έξω απο αυτα δεν θα κάνει render. 2)Θέτουμε το τρόπο με τον οποίο θα φαίνονται τα αντικείμενα μας. Για να θέσουμε ένα είδος projection πρώτα διαλέγουμε το projection matrix με την συνάρτηση glMatrixMode.
Orthographic Projection Χρησιμοποιείτε συνήθως σε CAD εφαρμογές και 2D games.
Orthographic Projection void glOrtho(GLdouble left, GLdouble right, GLdouble bottom,GLdouble top, GLdouble nearVal, GLdouble farVal) Οι τιμές left-right καθορίζουν τις συντεταγμένες στον άξονα x. Αντίστοιχα οι τιμές bottom-top και nearVal-farVal καθορίζουν τις τιμές στους άξονες y,z. Επειδή όμως την Orthographic προβολή την χρησιμοποιούμε κυρίως για 2D εφαρμογές η OpenGL μας παρέχει την συνάρτηση: void gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)
Perspective Projection Αυτο οφείλεται γιατί στην perspective υπάρχει ένα frustum. Το frustum στην ουσία είναι μια πυραμίδα με κομμένη κορυφή.Η κομένη κορυφή είναι προς την κάμερα. Αυτο μας βοηθάει γιατί ανάλογα την θέση στο frustum τοση παραμόρφωση θα έχει το αντικείμενο.
Perspective Projection
Perspective Projection H ΟpenGL μας παρέχει συναρτήσεις να δημιουργήσουμε ένα ασύμετρο frustum void glFrustum (GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble nearVal,GLdouble farVal). Eπίσης όμως μας παρέχει συνάρτηση και για την δημιουργία μιας προβολής και υπολογίζει αυτομάτα το frustum για εμάς. glPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar). H παράμετρος fovy είναι η γωνία της προβολής στον άξονα y και η παράμετρος aspect στην ουσία είναι η προβολη στον άξονα x που ισούται με x(width)/y(height).
Keyboard Events Με την χρήση της OpenGL μπορούμε να χειριστούμε keyboard events. Η OpenGL δεν μας προσφέρει συνάρτησεις για Keyboard Events Μας παρέχει εργαλεία για την κατασκευή μιας συνάρτησης απο τον χρήστη.
Keyboard Events H συναρτήσεις που φτιάχνει ο χρήστης πρέπει να είναι σε ένα συγκεκριμένο μοτίβο. void Keyboardfunc (unsigned char key, int x, int y) Αυτο συμβαίνει γιατί περνάμε στην OpenGL με την χρήση δεικτών σε συνάρτηση την δική μας συνάρτηση. void glutKeyboardFunc(void (*func) (unsigned char key, int x, int y));
Keyboard Events void processNormalKeys(unsigned char key, int x, int y) { if (key == 27) exit(0); } Η OpenGL όμως μας δίνει την δυνατότητα να διαχειριστούμε και τα “special keys”(F1,F2,PAGE_UP κτλ.) Αυτο που κάνουμε οταν θέλουμε να δημιουργήσουμε μια τέτοια συνάρτηση είναι ακριβώς το ίδιο με πριν όμως δίνω ως όρισμα την συνάρτηση μου στην συνάρτηση : void glutSpecialFunc(void (*func) (int key, int x, int y));