Εικονική κάμερα. Προοπτική προβολή. Βαθμονόμηση εσωτερικής κάμερας. Το απλούστερο μοντέλο προοπτικής προβολής

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

1. Πίνακες, γενικές έννοιες

Τι είναι οι πίνακες; Ας θυμηθούμε τα ανώτερα μαθηματικά: ένας πίνακας είναι ένα σύνολο αριθμών με μια προηγουμένως γνωστή διάσταση γραμμών και στηλών.

Μπορούν να προστεθούν πίνακες, να πολλαπλασιαστούν με έναν αριθμό, να πολλαπλασιαστούν μεταξύ τους και πολλά άλλα ενδιαφέροντα πράγματα, αλλά θα παραλείψουμε αυτή τη στιγμή, γιατί περιγράφεται με επαρκείς λεπτομέρειες σε οποιοδήποτε εγχειρίδιο ανώτερων μαθηματικών (μπορείτε να αναζητήσετε τα σχολικά βιβλία στο google.com). Θα χρησιμοποιήσουμε πίνακες ως προγραμματιστές, τους συμπληρώνουμε και τους λέμε τι να κάνουν με αυτούς, όλοι οι υπολογισμοί θα εκτελεστούν από τη μαθηματική βιβλιοθήκη Direct3D, επομένως πρέπει να συμπεριλάβουμε τη μονάδα κεφαλίδας d3dx9.h (και τη βιβλιοθήκη d3dx9.lib) στο έργο.

Το καθήκον μας είναι να δημιουργήσουμε ένα αντικείμενο, δηλ. γεμίστε τον πίνακα με τις συντεταγμένες των κορυφών του αντικειμένου. Κάθε κορυφή είναι ένα διάνυσμα (Χ, Υ, Ζ) στον τρισδιάστατο χώρο. Τώρα, για να εκτελέσουμε κάποια ενέργεια, πρέπει να πάρουμε το αντικείμενο μας (δηλαδή τον πίνακα) και να το πολλαπλασιάσουμε με τον πίνακα μετασχηματισμού, το αποτέλεσμα αυτής της πράξης είναι νέο αντικείμενο, που προσδιορίζεται ως μήτρα.

Το Direct3D ορίζει και χρησιμοποιεί τρεις κύριους πίνακες: τον παγκόσμιο πίνακα, τον πίνακα προβολής και τον πίνακα προβολής. Ας τους ρίξουμε μια πιο προσεκτική ματιά.

World Matrix- σας επιτρέπει να περιστρέφετε, να μετασχηματίζετε και να κλιμακώνετε ένα αντικείμενο, και επίσης δίνει σε καθένα από τα αντικείμενα το δικό του τοπικό σύστημα συντεταγμένων.

Λειτουργίες για εργασία με τον παγκόσμιο πίνακα:

  • D3DXMatrixRotationX(), D3DXMatrixRotationY(), D3DXMatrixRotationZ() - περιστροφή ενός σημείου σε σχέση με έναν από τους άξονες.
  • D3DXMatrixTranslation() - μετακίνηση ενός σημείου σε άλλη θέση.
  • D3DXMatrixScale() - κλιμάκωση.

    Προβολή Matrix- καθορίζει τη θέση της κάμερας προβολής σκηνής και μπορεί να αποτελείται από οποιονδήποτε συνδυασμό μετάδοσης και περιστροφής.
    Τα D3DXMatrixLookAtLH() και D3DXMatrixLookAtRH() καθορίζουν τη θέση της κάμερας και τη γωνία θέασης για αριστερόχειρα και δεξιόχειρα συστήματα συντεταγμένων, αντίστοιχα.

    Μήτρα προβολής- δημιουργεί μια προβολή μιας τρισδιάστατης σκηνής στην οθόνη της οθόνης. Με τη βοήθειά του, το αντικείμενο μετασχηματίζεται, η προέλευση των συντεταγμένων μεταφέρεται στο μπροστινό μέρος και καθορίζονται τα μπροστινά και πίσω επίπεδα αποκοπής.

    Συμπληρώνοντας αυτούς τους πίνακες και κάνοντας μετασχηματισμούς, δημιουργείτε μια τρισδιάστατη σκηνή στην οποία μπορείτε να μετακινήσετε, να περιστρέψετε, να μεγεθύνετε, να αφαιρέσετε και να εκτελέσετε άλλες ενέργειες σε αντικείμενα, ανάλογα με τις ανάγκες σας.

    2. Δημιουργία αντικειμένου

    Δημιουργούμε νέο έργο, παρόμοιο με το πρώτο. Πριν συνεχίσουμε να περιπλέκουμε τον κώδικά μας, ας τον χωρίσουμε σε μέρη για καλύτερη αναγνωσιμότητα κώδικα. Το έργο μας μπορεί λογικά να χωριστεί σε τρία μέρη:
    1. Παράθυρο των Windows (αρχικοποίηση παραθύρου, μηνύματα, ...)
    2. Τρισδιάστατη προετοιμασία (φόρτωση συντεταγμένων αντικειμένων, διαγραφή πόρων, ...)
    3. Απόδοση σκηνής (μήτρες, πρωτόγονα σχέδια, ...)
    Ως αποτέλεσμα, θα έχουμε 3 αρχεία - window.cpp, init3d.h, render.h με το ακόλουθο περιεχόμενο: init3d.h- μεταφορά καθολικών μεταβλητών και δομών, δηλώσεων συναρτήσεων, συναρτήσεων InitDirectX(), InitBufferVertex(), Destroy3D() αποδίδω.η- μετακινήστε τη συνάρτηση RenderScene() το μόνο που απομένει αφορά το κύριο παράθυρο, αυτό θα είναι ένα αρχείο - window.cpp.

    Προσθήκη αρχείο κεφαλίδαςκαι μια βιβλιοθήκη για τη χρήση συναρτήσεων μήτρας

    #περιλαμβάνω //ή C:\DXSDK\Include\d3dx9.h #pragma comment(lib, "d3dx9.lib") //ή C:\\DXSDK\\Lib\\d3dx9.lib

    Θα χρειαστούμε επίσης τυποποιημένα χαρακτηριστικάλειτουργούν με την πάροδο του χρόνου, επομένως συμπεριλαμβάνουμε το αντίστοιχο αρχείο κεφαλίδας:

    #περιλαμβάνω

    Ας αλλάξουμε τη μορφή αναπαράστασης κορυφής:

    #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ/D3DFVF_DIFFUSE) struct CUSTOMVERTEX ( ΦΛΟΤΕΡ x, y, z; DWORDχρώμα; )

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

    PDirectDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

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

    PDirectDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

    Ας απλοποιήσουμε την καρδιά μας φαντάζοντάς την με τη μορφή τριών τριγώνων. Θα χρησιμοποιήσουμε ένα τοπικό σύστημα συντεταγμένων.


    CUSTOMVERTEX stVertex= ( ( -1.0f, 0.5f, 0.0f, 0x00ff0000 ), ( -0.5f, 1.0f, 0.0f, 0x00ff0000 ), ( 0.0f, 0.5f, 0.0f, 0.0f, 0x. f, 0.0f, 0x000000ff ), ( 0.5f, 1.0f, 0.0f, 0x000000ff ), ( 1.0f, 0.5f, 0.0f, 0x000000ff ), ( -1.0f, 0.5f (0.5f, 0.5f, 0.5f) f, 0,5f, 0,0f, 0x0000ff00 ), ( 0,0f, -1,0f, 0,0f, 0x0000ff00 ), );

    3. Δημιουργία πινάκων μετασχηματισμού

    Ας γράψουμε στο αρχείο render.h τη συνάρτηση SetupMatrix() στην οποία θα πραγματοποιούνται όλες οι ενέργειες στους πίνακες.

    Ας δημιουργήσουμε πίνακες:

  • D3DXMATRIX MatrixWorld; - παγκόσμια μήτρα
  • D3DXMATRIX MatrixView; - μήτρα της φόρμας
  • D3DXMATRIX MatrixProjection; - μήτρα προβολής
    Ρύθμιση του παγκόσμιου πίνακα

    Για να περιστραφεί ένα αντικείμενο, πρέπει να πάρετε ώρα συστήματοςκαι κάθε «στιγμιαία» αλλάζει τη γωνία μεταξύ του τοπικού συστήματος συντεταγμένων και του παγκόσμιου συστήματος συντεταγμένων. Θα περιστραφούμε σε σχέση με τον άξονα Χ, επομένως χρησιμοποιούμε τη συνάρτηση D3DXMatrixRotationX. Αφού υπολογίσετε τον παγκόσμιο πίνακα, πρέπει να εφαρμόσετε τις τιμές του χρησιμοποιώντας τη συνάρτηση SetTransform:

    UINT iTime=timeGetTime()%5000; FLOAT fAngle=iTime*(2.0f*D3DX_PI)/5000.0f; D3DXMatrixRotationX(&MatrixWorld, fAngle); pDirectDevice->SetTransform(D3DTS_WORLD, &MatrixWorld); Ρύθμιση πίνακα προβολής

    Εγκαθιστούμε την κάμερα στη σωστή θέση και την κατευθύνουμε προς το αντικείμενο

  • D3DXMatrixLookAtLH(&MatrixView, - το αποτέλεσμα της συνάρτησης
  • &D3DXVECTOR3(0.0f, 0.0f, -8.0f), - το σημείο όπου βρίσκεται η κάμερα
  • &D3DXVECTOR3(0.0f, 0.0f, 0.0f), - το σημείο στο οποίο κοιτάμε
  • &D3DXVECTOR3(0.0f, 1.0f, 0.0f)); - κορυφή του αντικειμένου

    Μετά τον υπολογισμό, είναι απαραίτητο να εφαρμοστούν οι λαμβανόμενες τιμές.

  • Κάποια στιγμή, οποιοσδήποτε προγραμματιστής στον τομέα γραφικά υπολογιστήΤίθεται το ερώτημα: πώς λειτουργούν αυτοί οι πολλά υποσχόμενοι πίνακες; Μερικές φορές η απάντηση είναι πολύ δύσκολο να βρεθεί και, όπως συμβαίνει συνήθως, η πλειονότητα των προγραμματιστών εγκαταλείπει τα μισά της εργασίας.

    Αυτή δεν είναι λύση στο πρόβλημα! Ας το καταλάβουμε μαζί!

    Ας είμαστε ρεαλιστές με μια πρακτική προκατάληψη και ας πάρουμε το OpenGL έκδοση 3.3 ως θέμα δοκιμής. Ξεκινώντας από αυτήν την έκδοση, κάθε προγραμματιστής πρέπει να εφαρμόσει ανεξάρτητα τη λειτουργική μονάδα matrix. Μπράβο, αυτό χρειαζόμαστε. Ας αποσυνθέσουμε το δύσκολο έργο μας και ας επισημάνουμε τα κύρια σημεία. Μερικά στοιχεία από την προδιαγραφή OpenGL:

    • Οι πίνακες αποθηκεύονται σε στήλες (στήλη-μείζονα).
    • Ομοιογενείς συντεταγμένες;
    • Κανονικός όγκος αποκοπής (CVV) σε αριστερόστροφο σύστημα συντεταγμένων.
    Υπάρχουν δύο τρόποι αποθήκευσης πινάκων: μείζονος στήλης και μείζονος σειράς. Σε διαλέξεις για τη γραμμική άλγεβρα, χρησιμοποιείται το σχήμα μείζονος σειράς. Με σε μεγάλο βαθμόΗ αναπαράσταση πινάκων στη μνήμη δεν έχει σημασία, γιατί ένας πίνακας μπορεί πάντα να μετατραπεί από μια αναπαράσταση σε άλλη με απλή μεταφορά. Και επειδή δεν υπάρχει διαφορά, τότε για όλους τους επόμενους υπολογισμούς θα χρησιμοποιήσουμε κλασικούς πίνακες μείζονος σειράς. Κατά τον προγραμματισμό του OpenGL υπάρχει μικρό κόλπο, το οποίο σας επιτρέπει να αρνηθείτε να μεταφέρετε πίνακες διατηρώντας παράλληλα τους κλασικούς υπολογισμούς μείζονος σειράς. Ο πίνακας πρέπει να μεταφερθεί στο πρόγραμμα shader ως έχει, και στον shader ο πολλαπλασιασμός δεν πρέπει να πραγματοποιείται μεταξύ ενός διανύσματος και ενός πίνακα, αλλά μεταξύ ενός πίνακα και ενός διανύσματος.

    Οι ομοιογενείς συντεταγμένες δεν είναι πολύ καλές πονηρό σύστημαδίπλα στο απλούς κανόνεςσχετικά με τη μετατροπή συμβατικών καρτεσιανών συντεταγμένων σε ομοιογενείς συντεταγμένες και αντίστροφα. Μια ομοιογενής συντεταγμένη είναι ένας πίνακας σειράς διάστασης. Για να μετατραπεί μια καρτεσιανή συντεταγμένη σε ομοιογενή, είναι απαραίτητο Χ, yΚαι zπολλαπλασιάστε με οποιοδήποτε πραγματικός αριθμός w(εκτός 0). Στη συνέχεια, πρέπει να γράψετε το αποτέλεσμα στα τρία πρώτα στοιχεία και το τελευταίο στοιχείο θα είναι ίσο με τον πολλαπλασιαστή w. Με άλλα λόγια:
    - Καρτεσιανές συντεταγμένες
    w– πραγματικός αριθμός όχι ίσος με 0

    - ομοιογενείς συντεταγμένες

    Ένα μικρό κόλπο: Αν wισούται με ένα, τότε το μόνο που χρειάζεται για τη μετάφραση είναι η μεταφορά των στοιχείων Χ, yΚαι zκαι αντιστοιχίστε ένα στο τελευταίο στοιχείο. Δηλαδή, πάρτε έναν πίνακα σειρών:

    Λίγα λόγια για τη μηδενική ποιότητα w. Από την άποψη των ομοιογενών συντεταγμένων, αυτό είναι αρκετά αποδεκτό. Οι ομοιογενείς συντεταγμένες σας επιτρέπουν να διακρίνετε μεταξύ σημείων και διανυσμάτων. Σε ένα καρτεσιανό σύστημα συντεταγμένων, μια τέτοια διαίρεση είναι αδύνατη.

    - σημείο όπου ( x, y, z) - Καρτεσιανές συντεταγμένες

    - διάνυσμα, όπου ( x, y, z) – διάνυσμα ακτίνας

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

    - ομοιογενείς συντεταγμένες
    - Καρτεσιανές συντεταγμένες

    Το κύριο πράγμα που πρέπει να γνωρίζετε είναι ότι όλοι οι αλγόριθμοι αποκοπής και ραστεροποίησης OpenGL λειτουργούν σε καρτεσιανές συντεταγμένες, αλλά πριν από αυτό όλοι οι μετασχηματισμοί εκτελούνται σε ομοιογενείς συντεταγμένες. Η μετάβαση από ομοιογενείς συντεταγμένες στις καρτεσιανές συντεταγμένες πραγματοποιείται σε υλικό.

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


    Ρύζι. 1. Κανονικός τόμος αποκοπής OpenGL (CVV)

    Αριστερόστροφο σύστημα συντεταγμένων; Πώς μπορεί να συμβεί αυτό, αφού η προδιαγραφή για το OpenGL 1.0 δηλώνει ξεκάθαρα ότι το σύστημα συντεταγμένων που χρησιμοποιείται είναι δεξιόχειρας; Ας το καταλάβουμε.


    Ρύζι. 2. Συστήματα συντεταγμένων

    Όπως φαίνεται από το Σχ. Τα 2 συστήματα συντεταγμένων διαφέρουν μόνο ως προς την κατεύθυνση του άξονα Ζ. Το OpenGL 1.0 χρησιμοποιεί στην πραγματικότητα δεξιόχειρες σύστημα χρήστησυντεταγμένες Αλλά το σύστημα συντεταγμένων CVV και το σύστημα συντεταγμένων χρήστη είναι δύο εντελώς διαφορετικά πράγματα. Επιπλέον, από την έκδοση 3.3, δεν υπάρχει πλέον κάτι τέτοιο τυπικό σύστημαΣυντεταγμένες OpenGL. Όπως αναφέρθηκε προηγουμένως, ο ίδιος ο προγραμματιστής υλοποιεί την ενότητα λειτουργιών μήτρας. Σχηματισμός πινάκων περιστροφής, σχηματισμός πινάκων προβολής, αναζήτηση αντίστροφου πίνακα, πολλαπλασιασμός πίνακα είναι ελάχιστο σετλειτουργίες που περιλαμβάνονται στη λειτουργική μονάδα μήτρας. Προκύπτουν δύο λογικά ερωτήματα. Εάν ο όγκος ορατότητας είναι ένας κύβος με μήκος άκρης ίσο με δύο, τότε γιατί η σκηνή έχει μέγεθος αρκετές χιλιάδες; συμβατικές μονάδεςορατό στην οθόνη; Σε ποιο σημείο το σύστημα συντεταγμένων χρήστη μετατρέπεται σε σύστημα συντεταγμένων CVV; Οι πίνακες προβολής είναι ακριβώς η οντότητα που ασχολείται με αυτά τα ζητήματα.

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

    Ένας από τους πιο συνηθισμένους και δύσκολους στην κατανόηση πίνακες είναι ο πίνακας μετασχηματισμού προοπτικής. Πώς σχετίζεται λοιπόν με το CVV και το σύστημα συντεταγμένων του χρήστη; Γιατί τα αντικείμενα γίνονται μικρότερα όσο αυξάνεται η απόστασή τους από τον παρατηρητή; Για να κατανοήσουμε γιατί τα αντικείμενα συρρικνώνονται καθώς αυξάνεται η απόσταση, ας δούμε τους μετασχηματισμούς μήτρας ενός τρισδιάστατου μοντέλου βήμα προς βήμα. Δεν είναι μυστικό ότι οποιοδήποτε τρισδιάστατο μοντέλο αποτελείται από μια πεπερασμένη λίστα κορυφών που υφίστανται μετασχηματισμούς μήτρας εντελώς ανεξάρτητα η μία από την άλλη. Για να προσδιορίσετε τη συντεταγμένη μιας τρισδιάστατης κορυφής σε μια οθόνη δισδιάστατης οθόνης, πρέπει:

    1. Μετατροπή καρτεσιανής συντεταγμένης σε ομοιογενή συντεταγμένη.
    2. Πολλαπλασιάστε την ομοιογενή συντεταγμένη με τον πίνακα του μοντέλου.
    3. Το αποτέλεσμα πολλαπλασιάζεται με τον πίνακα προβολής.
    4. Πολλαπλασιάστε το αποτέλεσμα με τον πίνακα προβολής.
    5. Μετατρέψτε το αποτέλεσμα από ομοιογενείς συντεταγμένες σε καρτεσιανές συντεταγμένες.
    Η μετατροπή των καρτεσιανών συντεταγμένων σε ομοιογενείς συντεταγμένες συζητήθηκε νωρίτερα. Γεωμετρική σημασίαμήτρα μοντέλου είναι η μετάφραση του μοντέλου από τοπικό σύστημασυντεταγμένες σε παγκόσμιο σύστημασυντεταγμένες Ή, όπως λένε, μετακινήστε τις κορυφές από το χώρο του μοντέλου στον παγκόσμιο χώρο. Ας το θέσω απλά, ένα τρισδιάστατο αντικείμενο που φορτώνεται από ένα αρχείο βρίσκεται στο χώρο του μοντέλου, όπου οι συντεταγμένες μετρώνται σε σχέση με το ίδιο το αντικείμενο. Στη συνέχεια, χρησιμοποιώντας τη μήτρα του μοντέλου, το μοντέλο τοποθετείται, κλιμακώνεται και περιστρέφεται. Ως αποτέλεσμα, όλες οι κορυφές του τρισδιάστατου μοντέλου λαμβάνουν πραγματικές ομοιογενείς συντεταγμένες στην τρισδιάστατη σκηνή. Ο χώρος του μοντέλου σε σχέση με τον παγκόσμιο χώρο είναι τοπικός. Από το χώρο του μοντέλου, οι συντεταγμένες μεταφέρονται στον παγκόσμιο χώρο (από τοπικό σε παγκόσμιο). Για το σκοπό αυτό, χρησιμοποιείται ένας πίνακας μοντέλων.

    Τώρα ας προχωρήσουμε στο τρίτο βήμα. Εδώ παίζει ρόλο ο χώρος προβολής. Σε αυτό το χώρο, οι συντεταγμένες μετρώνται σε σχέση με τη θέση και τον προσανατολισμό του παρατηρητή σαν να ήταν το κέντρο του κόσμου. Ο χώρος προβολής είναι τοπικός σε σχέση με τον παγκόσμιο χώρο, επομένως οι συντεταγμένες πρέπει να εισαχθούν σε αυτόν (και όχι να αφαιρεθούν, όπως στην προηγούμενη περίπτωση). Ο μετασχηματισμός άμεσου πίνακα αφαιρεί συντεταγμένες από κάποιο χώρο. Για να τα εισαγάγουμε σε αυτό, αντίθετα, είναι απαραίτητο να αντιστρέψουμε τον μετασχηματισμό πίνακα, επομένως ο μετασχηματισμός τύπου περιγράφεται από τον αντίστροφο πίνακα. Πώς να το αποκτήσετε αντίστροφη μήτρα? Αρχικά, ας πάρουμε τον πίνακα άμεσου παρατηρητή. Τι χαρακτηρίζει έναν παρατηρητή; Ο παρατηρητής περιγράφεται από τη συντεταγμένη στην οποία βρίσκεται και τα διανύσματα κατεύθυνσης θέασης. Ο παρατηρητής κοιτάζει πάντα προς την κατεύθυνση του τοπικού του άξονα Ζ. Ο παρατηρητής μπορεί να κινείται γύρω από τη σκηνή και να κάνει στροφές. Από πολλές απόψεις, αυτό μοιάζει με το νόημα της μήτρας του μοντέλου. Σε γενικές γραμμές, έτσι είναι. Ωστόσο, για έναν παρατηρητή, η λειτουργία κλιμάκωσης δεν έχει νόημα, επομένως, δεν μπορεί να τεθεί πρόσημο ίσου μεταξύ της μήτρας μοντέλου του παρατηρητή και της μήτρας μοντέλου ενός τρισδιάστατου αντικειμένου. Η μήτρα του μοντέλου του παρατηρητή είναι η επιθυμητή άμεση μήτρα. Αντιστρέφοντας αυτόν τον πίνακα, λαμβάνουμε τον πίνακα προβολής. Στην πράξη, αυτό σημαίνει ότι όλες οι κορυφές σε καθολικές ομοιογενείς συντεταγμένες θα λάβουν νέες ομοιογενείς συντεταγμένες σε σχέση με τον παρατηρητή. Αντίστοιχα, αν ο παρατηρητής είδε μια ορισμένη κορυφή, τότε η τιμή της ομοιογενούς συντεταγμένης zμιας δεδομένης κορυφής στο χώρο προβολής θα είναι σίγουρα ένας θετικός αριθμός. Αν η κορυφή βρισκόταν πίσω από τον παρατηρητή, τότε η τιμή της ομοιογενούς συντεταγμένης του zο χώρος προβολής θα είναι σίγουρα αρνητικός αριθμός.

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

    Εξετάστε έναν πίνακα της φόρμας:

    Και ένα σημείο στον ομοιογενή χώρο του παρατηρητή:

    Ας πολλαπλασιάσουμε την ομοιογενή συντεταγμένη με τον εν λόγω πίνακα:

    Ας μετατρέψουμε τις ομογενείς συντεταγμένες που προκύπτουν σε καρτεσιανές συντεταγμένες:

    Ας υποθέσουμε ότι υπάρχουν δύο σημεία στο χώρο προβολής με τις ίδιες συντεταγμένες ΧΚαι y, αλλά με διαφορετικές συντεταγμένες z. Με άλλα λόγια, το ένα από τα σημεία βρίσκεται πίσω από το άλλο. Λόγω της παραμόρφωσης της προοπτικής, ο παρατηρητής πρέπει να δει και τα δύο σημεία. Πράγματι, είναι σαφές από τον τύπο ότι λόγω διαίρεσης με τη συντεταγμένη z, συμβαίνει συμπίεση στο σημείο προέλευσης. Όσο μεγαλύτερη είναι η τιμή z(όσο πιο μακριά είναι το σημείο από τον παρατηρητή), τόσο ισχυρότερη είναι η συμπίεση. Αυτή είναι η εξήγηση για το προοπτικό αποτέλεσμα.

    Η προδιαγραφή OpenGL δηλώνει ότι οι λειτουργίες αποκοπής και ραστεροποίησης εκτελούνται σε καρτεσιανές συντεταγμένες και η διαδικασία μετατροπής ομοιογενών συντεταγμένων σε καρτεσιανές συντεταγμένες εκτελείται αυτόματα.

    Ο πίνακας (1) είναι ένα πρότυπο για έναν πίνακα προοπτικής προβολής. Όπως αναφέρθηκε προηγουμένως, η εργασία του πίνακα προβολής αποτελείται από δύο σημεία: ρύθμιση ενός συστήματος συντεταγμένων χρήστη (αριστερόχειρας ή δεξιόχειρας), μεταφορά του όγκου ορατότητας του παρατηρητή στο CVV. Ας εξαγάγουμε έναν πίνακα προοπτικής για ένα σύστημα συντεταγμένων αριστερόχειρα χρήστη.

    Ο πίνακας προβολής μπορεί να περιγραφεί χρησιμοποιώντας τέσσερις παραμέτρους (Εικ. 3):

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


    Ρύζι. 3. Προοπτικός όγκος ορατότητας

    Ας εξετάσουμε την προβολή ενός σημείου στο χώρο του παρατηρητή στο μπροστινό άκρο της αποκοπής του προοπτικού όγκου ορατότητας. Για μεγαλύτερη σαφήνεια, στο Σχ. 4 δείχνει μια πλάγια όψη. Θα πρέπει επίσης να ληφθεί υπόψη ότι το σύστημα συντεταγμένων του χρήστη συμπίπτει με το σύστημα συντεταγμένων CVV, δηλαδή το αριστερό σύστημα συντεταγμένων χρησιμοποιείται παντού.


    Ρύζι. 4. Προβολή αυθαίρετου σημείου

    Με βάση τις ιδιότητες όμοιων τριγώνων, ισχύουν οι ακόλουθες ισότητες:

    Ας εκφράσουμε τα yꞌ και xꞌ:

    Κατ' αρχήν, οι εκφράσεις (2) επαρκούν για να ληφθούν οι συντεταγμένες των σημείων προβολής. Ωστόσο, για να ελέγξετε σωστά τα τρισδιάστατα αντικείμενα, πρέπει να γνωρίζετε το βάθος κάθε θραύσματος. Με άλλα λόγια, είναι απαραίτητο να αποθηκεύσετε την τιμή του στοιχείου z. Αυτή είναι η τιμή που χρησιμοποιείται για τις δοκιμές βάθους OpenGL. Στο Σχ. 3 είναι σαφές ότι η τιμή zꞌδεν είναι κατάλληλο ως βάθος θραύσματος, επειδή όλες οι σημειακές προβολές έχουν την ίδια τιμή zꞌ. Η διέξοδος από αυτή την κατάσταση είναι να χρησιμοποιήσετε το λεγόμενο ψευδο-βάθος.

    Ιδιότητες ψευδοβάθους:

    1. Το ψευδο-βάθος υπολογίζεται με βάση την τιμή z;
    2. Όσο πιο κοντά είναι το σημείο στον παρατηρητή, τόσο λιγότερη τιμή έχει το ψευδό βάθος.
    3. Όλα τα σημεία που βρίσκονται στο μπροστινό επίπεδο του όγκου ορατότητας έχουν τιμή ψευδοβάθους -1.
    4. Όλα τα σημεία που βρίσκονται στο μακρινό επίπεδο κοπής του όγκου ορατότητας έχουν τιμή ψευδοβάθους 1.
    5. Όλα τα θραύσματα που βρίσκονται μέσα στον όγκο ορατότητας έχουν μια τιμή ψευδοβάθους στην περιοχή [-1 1].
    Ας εξαγάγουμε τον τύπο με τον οποίο θα υπολογιστεί το ψευδοβάθος. Ας πάρουμε ως βάση την ακόλουθη έκφραση:

    Πιθανότητα έναΚαι σιπρέπει να υπολογιστεί. Για να το κάνουμε αυτό, χρησιμοποιούμε τις ιδιότητες των ψευδο-βαθών 3 και 4. Λαμβάνουμε ένα σύστημα δύο εξισώσεων με δύο άγνωστα:

    Ας προσθέσουμε και τα δύο μέρη του συστήματος και ας πολλαπλασιάσουμε το αποτέλεσμα με το γινόμενο στ, όπου φάΚαι nδεν μπορεί να είναι ίσο με μηδέν. Παίρνουμε:

    Ας ανοίξουμε τις αγκύλες και ας αναδιατάξουμε τους όρους έτσι ώστε μόνο το τμήμα με ΕΝΑ, και στα δεξιά μόνο με σι:

    Ας αντικαταστήσουμε το (6) στο (5). Ας μετατρέψουμε την έκφραση σε απλό κλάσμα:

    Πολλαπλασιάστε και τις δύο πλευρές κατά -2fn, όπου φάΚαι nδεν μπορεί να είναι ίσο με μηδέν. Ας παρουσιάσουμε παρόμοια, ας αναδιατάξουμε τους όρους και ας εκφράσουμε σι:

    Ας αντικαταστήσουμε το (7) σε (6) και ας εκφράσουμε ένα:

    Αντίστοιχα τα εξαρτήματα έναΚαι σιείναι ίσα:

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

    Αφήστε την απόσταση από το μπροστινό επίπεδο κοπής nισούται με 2 και η απόσταση από το μακρινό επίπεδο αποκοπής φάισούται με 10. Θεωρήστε πέντε σημεία στον ομοιογενή χώρο του παρατηρητή:

    Η σχετική θέση του σημείου και ο όγκος ορατότητας
    Τελεία Εννοια Περιγραφή
    1 1 Το σημείο βρίσκεται μπροστά από το μπροστινό επίπεδο κοπής του όγκου ορατότητας. Δεν περνάει από ραστεροποίηση.
    2 2 Το σημείο βρίσκεται στο μπροστινό άκρο της αποκοπής όγκου ορατότητας. Υποβάλλεται σε ραστεροποίηση.
    3 5 Το σημείο βρίσκεται μεταξύ της μπροστινής ακμής αποκοπής και της μακρινής άκρης αποκοπής της έντασης ορατότητας. Υποβάλλεται σε ραστεροποίηση.
    4 10 Το σημείο βρίσκεται στο μακρινό άκρο της αποκοπής όγκου ορατότητας. Υποβάλλεται σε ραστεροποίηση.
    5 20 Το σημείο βρίσκεται πέρα ​​από το μακρινό άκρο της αποκοπής όγκου ορατότητας. Δεν περνάει από ραστεροποίηση.

    Ας πολλαπλασιάσουμε όλα τα σημεία με τον πίνακα (8) και στη συνέχεια μετατρέψουμε τις ομοιογενείς συντεταγμένες που προκύπτουν σε καρτεσιανές συντεταγμένες . Για να γίνει αυτό, πρέπει να υπολογίσουμε τις τιμές των νέων ομοιογενών συστατικών Και .
    Σημείο 1:

    Σημειώστε ότι η ομογενής συντεταγμένη είναι απολύτως σωστά τοποθετημένο στο CVV, και το πιο σημαντικό, η δοκιμή βάθους OpenGL είναι πλέον δυνατή, επειδή το ψευδο-βάθος ικανοποιεί πλήρως τις απαιτήσεις δοκιμής.

    Με συντεταγμένη zΤο καταλάβαμε, ας περάσουμε στις συντεταγμένες ΧΚαι y. Όπως αναφέρθηκε προηγουμένως, ολόκληρος ο όγκος της προοπτικής ορατότητας πρέπει να ταιριάζει στο CVV. Το μήκος της άκρης CVV είναι δύο. Αντίστοιχα, το ύψος και το πλάτος του προοπτικού όγκου ορατότητας πρέπει να συμπιέζονται σε δύο συμβατικές μονάδες.

    Έχουμε στη διάθεσή μας μια γωνιά βούτυροκαι μέγεθος άποψη. Ας εκφράσουμε το ύψος και το πλάτος χρησιμοποιώντας αυτές τις τιμές.


    Ρύζι. 5. Όγκος ορατότητας

    Από το Σχ. 5 είναι σαφές ότι:

    Τώρα μπορούμε να πάρουμε την τελική άποψη του πίνακα προβολής προοπτικής για ένα προσαρμοσμένο σύστημα συντεταγμένων με αριστερόστροφο που λειτουργεί με το CVV OpenGL:

    Αυτό ολοκληρώνει την παραγωγή πινάκων.

    Λίγα λόγια για το DirectX - τον κύριο ανταγωνιστή του OpenGL. Το DirectX διαφέρει από το OpenGL μόνο ως προς τις διαστάσεις του CVV και τη θέση του. Στο DirectX, ένα CVV είναι ένα ορθογώνιο παραλληλεπίπεδο με μήκη κατά μήκος των αξόνων του ΧΚαι yίσο με δύο, και κατά μήκος του άξονα zτο μήκος είναι ίσο με ένα. Εύρος ΧΚαι yείναι [-1 1] και το εύρος zίσο με . Όσο για το σύστημα συντεταγμένων CVV, το DirectX, όπως και το OpenGL, χρησιμοποιεί ένα αριστερόστροφο σύστημα συντεταγμένων.

    Για απόσυρση πολλά υποσχόμενοι πίνακεςγια ένα προσαρμοσμένο δεξιόστροφο σύστημα συντεταγμένων, πρέπει να σχεδιάσετε ξανά το σχήμα. 2, Σχ. 3 και Σχ. 4 λαμβάνοντας υπόψη τη νέα κατεύθυνση του άξονα Ζ. Οι περαιτέρω υπολογισμοί είναι εντελώς παρόμοιοι, μέχρι το πρόσημο. Για πίνακες DirectX, οι ιδιότητες ψευδοβάθους 3 και 4 τροποποιούνται για να ταιριάζουν στο εύρος.

    Σε αυτό το σημείο, το θέμα των υποσχόμενων πινάκων μπορεί να θεωρηθεί κλειστό.

    Η αξονομετρία είναι μια παράλληλη προβολή. Ο Πίνακας 3.3 καταγράφει πρώτα τους πίνακες των ορθογραφικών προβολών σε επίπεδα συντεταγμένων που λαμβάνονται από τους ορισμούς τους.

    Πίνακας 3.3.Μήτρες σχεδιαστικών μετασχηματισμών και προβολής

    Ορθογραφική προβολή σε XOY

    Ορθογραφική προβολή σε YOZ

    Ορθογραφική προβολή σε XOZ

    Ορθογραφική προβολή στο επίπεδο x=p

    Τριμετρικός πίνακας μετασχηματισμού στο επίπεδο XOY

    Ισομετρικός πίνακας μετασχηματισμού στο επίπεδο XOY

    Ισομετρική μήτρα προβολής στο επίπεδο XOY

    Πλάγια μήτρα προβολής σε XOY

    Δωρεάν μήτρα προβολής στο XOY

    Πίνακας προβολής ντουλαπιού σε XOY

    Πίνακας μετασχηματισμού προοπτικής με ένα σημείο φυγής (το επίπεδο της εικόνας είναι κάθετο στον άξονα x)

    Πίνακας μετασχηματισμού προοπτικής με ένα σημείο φυγής (το επίπεδο της εικόνας είναι κάθετο στον άξονα y)

    Πίνακας μετασχηματισμού προοπτικής με ένα σημείο φυγής (το επίπεδο της εικόνας είναι κάθετο στον άξονα εφαρμογής)

    Πίνακας μετασχηματισμού προοπτικής με δύο σημεία εξαφάνισης (το επίπεδο της εικόνας είναι παράλληλο στον άξονα y)

    Πίνακας μετασχηματισμού προοπτικής με τρία σημεία εξαφάνισης (εικόνα επίπεδο αυθαίρετης θέσης)

    Η ισομετρία, η διμετρία και η τριμετρία λαμβάνονται με συνδυασμό περιστροφών που ακολουθούνται από προβολή από το άπειρο. Εάν πρέπει να περιγράψετε την προβολή στο επίπεδο XOY, τότε πρέπει πρώτα να πραγματοποιήσετε έναν μετασχηματισμό περιστροφής κατά γωνία σε σχέση με τον άξονα των τεταγμένων και μετά στη γωνία σε σχέση με τον άξονα της τετμημένης. Ο Πίνακας 3.3 δείχνει τον τριμετρικό πίνακα μετασχηματισμού. Για να ληφθεί ένας διμετρικός πίνακας μετασχηματισμού στον οποίο, για παράδειγμα, οι συντελεστές παραμόρφωσης κατά μήκος των αξόνων τετμημένης και τεταγμένης θα είναι ίσοι, η σχέση μεταξύ των γωνιών περιστροφής πρέπει να υπακούει στη σχέση

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

    Ο πίνακας 3.3 δείχνει τον ισομετρικό πίνακα μετασχηματισμού, καθώς και τον ισομετρικό πίνακα προβολής στο επίπεδο XOY. Η ανάγκη για πίνακες του πρώτου τύπου έγκειται στη χρήση τους σε αλγόριθμους για την αφαίρεση αόρατων στοιχείων.

    Στις πλάγιες προβολές, οι προεξέχουσες ευθείες σχηματίζουν μια γωνία με το επίπεδο προβολής που είναι διαφορετική από 90 μοίρες. Ο Πίνακας 3.3 δείχνει τη γενική μήτρα της λοξής προβολής στο επίπεδο XOY, καθώς και πίνακες ελεύθερων προβολών και προβολών ντουλαπιού, στους οποίους:

    Οι προοπτικές προβολές (Πίνακας 3.3) αντιπροσωπεύονται επίσης από μετασχηματισμούς προοπτικής και προοπτικές προβολές στο επίπεδο XOY. Τα V X, V Y και V Z είναι κέντρα προβολής - σημεία στους αντίστοιχους άξονες. –V X, -V Y, -V Z θα είναι τα σημεία στα οποία συγκλίνουν δέσμες ευθειών παράλληλων προς τους αντίστοιχους άξονες.

    Το σύστημα συντεταγμένων του παρατηρητή είναι αριστεράσύστημα συντεταγμένων (Εικ. 3.3), στο οποίο ο άξονας z e κατευθύνεται από την οπτική γωνία προς τα εμπρός, ο άξονας x e κατευθύνεται προς τα δεξιά και ο άξονας y e κατευθύνεται προς τα πάνω. Αυτός ο κανόνας υιοθετείται για να διασφαλιστεί ότι οι άξονες x e και y e συμπίπτουν με τους άξονες x s και y s στην οθόνη. Ο προσδιορισμός των τιμών των συντεταγμένων της οθόνης x s και y s για το σημείο P οδηγεί στην ανάγκη διαίρεσης με τη συντεταγμένη z e. Για την κατασκευή μιας ακριβούς προοπτικής εικόνας, είναι απαραίτητο να διαιρεθεί με τη συντεταγμένη βάθους κάθε σημείου.

    Ο Πίνακας 3.4 δείχνει τις τιμές του περιγραφέα κορυφής S(X,Y,Z) του μοντέλου (Εικ. 2.1) που υποβάλλεται σε μετασχηματισμούς περιστροφής και ισομετρικό μετασχηματισμό.

    Πίνακας 3.4. Περιγραφείς κορυφής μοντέλου

    Πρωτότυπο μοντέλο

    M(R(z,90))xM(R(y,90))

    Η έξοδος γραφικών παρέχεται συνήθως σε μια ορθογώνια περιοχή της οθόνης ή του παραθύρου. Στην απόδοση OpenGL, αυτή η περιοχή ονομάζεται θύρα εξόδου. Σε αυτήν την ορθογώνια περιοχή η βιβλιοθήκη θα τοποθετήσει την εικόνα που δημιουργείται. Οι διαστάσεις του καθορίζονται σε σχέση με την επάνω αριστερή γωνία του παραθύρου και μετρώνται σε pixel. Για να προσδιορίσει τη θύρα εξόδου, η εφαρμογή πρέπει να ακούσει το συμβάν αλλαγής μεγέθους παραθύρου και να καθορίσει τη θύρα εξόδου χρησιμοποιώντας τη συνάρτηση:

    void glViewport(GLint x, GLint y, GLsizei πλάτος, GLsizei ύψος);

    Τα ορίσματα (x, y) καθορίζουν τη θέση της επάνω αριστερής γωνίας της θύρας εξόδου και το πλάτος και το ύψος είναι οι διαστάσεις της. Από προεπιλογή, η βιβλιοθήκη επεκτείνει τη θύρα εξόδου για να καλύψει ολόκληρο το παράθυρο OpenGL.

    Σύστημα συντεταγμένων

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

    Αρχικά, η κορυφή μετατρέπεται σε έναν πίνακα 1Χ4 στον οποίο τα τρία πρώτα στοιχεία αντιπροσωπεύουν τις συντεταγμένες x, y, z. Ο τέταρτος αριθμός είναι ο συντελεστής κλίμακας w, ο οποίος είναι συνήθως 1,0. Η κορυφή πολλαπλασιάζεται με τον πίνακα προβολής, ο οποίος περιγράφει τον μετασχηματισμό του συστήματος συντεταγμένων προβολής. Παίρνουμε την κορυφή στις συντεταγμένες προβολής. Αυτό, με τη σειρά του, πολλαπλασιάζεται με τον πίνακα προβολής και λαμβάνουμε την κορυφή σε συντεταγμένες προβολής. Σε αυτό το στάδιο, ορισμένες κορυφές απορρίπτονται (λόγω του ότι δεν εμπίπτουν στον τόμο οπτικοποίησης). Οι κορυφές στη συνέχεια κανονικοποιούνται για να μεταφέρουν την προοπτική (εκτός εάν η συντεταγμένη w είναι 1,0). Η τελική προβολή της κορυφής στην επιφάνεια της δισδιάστατης οθόνης εκτελείται από την ίδια τη βιβλιοθήκη OpenGL και δεν μπορεί να παρέμβει σε αυτή τη διαδικασία.

    Μήτρα προβολής

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

    Στο προοπτική προβολήΧρησιμοποιείται το γεγονός ότι το ανθρώπινο μάτι λειτουργεί με ένα απομακρυσμένο αντικείμενο του οποίου οι διαστάσεις έχουν γωνιακές διαστάσεις. Όσο πιο μακριά είναι ένα αντικείμενο, τόσο πιο μικρό μας φαίνεται. Έτσι, ο όγκος του χώρου που απεικονίζεται είναι μια πυραμίδα.

    Ο πίνακας προοπτικής προβολής ορίζεται χρησιμοποιώντας τη συνάρτηση:

    void glFrustum(GLδιπλό αριστερά, GLδιπλό δεξιά, GLδιπλό κάτω, GLδιπλό επάνω, GLδιπλό κοντά, GLδιπλό μακριά);

    (αριστερά, κάτω, -κοντά) και (δεξιά, πάνω, -κοντά) ορίζουν τις συντεταγμένες του πλησιέστερου πλαισίου αποκοπής. το κοντινό και το μακρινό έχουν πάντα θετικές τιμές και καθορίζουν την απόσταση από την οπτική γωνία μέχρι τα κοντινά και μακρινά πλαίσια αποκοπής.

    Για να ορίσετε τον πίνακα προβολής προοπτικής, μπορείτε επίσης να χρησιμοποιήσετε τη συνάρτηση gluPerspective(), η οποία έχει διαφορετικά ορίσματα

    void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far);

    Το όρισμα fovy (πεδίο προβολής) καθορίζει το οπτικό πεδίο και η πτυχή είναι ο λόγος του πλάτους του κουτιού αποκοπής προς το ύψος του. το κοντινό και το μακρινό έχουν πάντα θετικές τιμές και καθορίζουν την απόσταση από την οπτική γωνία μέχρι τα κοντινά και μακρινά πλαίσια αποκοπής.

    Η προβολή προοπτικής χρησιμοποιείται συνήθως σε παιχνίδια και εφαρμογές όπου είναι απαραίτητο να επιτευχθούν εξαιρετικά ρεαλιστικά αντικείμενα που μπορούν να οραματιστούν με το μάτι. Για την απεικόνιση 2D και 3D επιστημονικών και τεχνικών δεδομένων, χρησιμοποιείται συνήθως ορθογραφική προβολή. Ας δούμε πρώτα τη ρύθμιση της ορθογραφικής προβολής για δισδιάστατη απόδοση. Με την ορθογραφική προβολή, ο όγκος του χώρου που απεικονίζεται είναι ένας παραλληλεπίπεδος:

    Η ιδιαιτερότητα της ορθογραφικής προβολής είναι ότι η απόσταση από την κάμερα σε αντικείμενα δεν επηρεάζει την τελική εικόνα.

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

    void glOrtho(GLδιπλό αριστερά, GLδιπλό δεξιά, GLδιπλό κάτω, GLδιπλό επάνω, GLδιπλό κοντά, GLδιπλό μακριά);

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

    //Λειτουργία αλλαγής μεγέθους και ρύθμισης συντεταγμένων
    Void Reshape (int πλάτος, int ύψος)
    {
    //Ρύθμιση θύρας εξόδου
    glViewport(0, 0, πλάτος, ύψος);

    //Λειτουργία μήτρας προβολής
    glMatrixMode(GL_PROJECTION);
    //Μήτρα ταυτότητας
    glLoadIdentity();

    //Ρύθμιση ενός δισδιάστατου ορθογραφικού συστήματος συντεταγμένων
    glOrtho(-50., 50., -50., 50., -1., 1.);

    //Προβολή λειτουργίας matrix
    glMatrixMode(GL_MODELVIEW);
    }

    Ειδικά για την απόδοση 2D, μπορείτε να χρησιμοποιήσετε μια συνάρτηση που έχει το ακόλουθο πρωτότυπο:

    void gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top);

    Αυτή η συνάρτηση είναι παρόμοια με τη glOrtho(), η οποία καλεί το όρισμα near=-1.0 και far=1.0. Κατά τη δισδιάστατη απόδοση, η συντεταγμένη z στις κορυφές έχει τιμή 0, που σημαίνει ότι τα αντικείμενα βρίσκονται στο μεσαίο επίπεδο.

    Εάν είναι απαραίτητο να διατηρηθούν οι αναλογίες, το σύστημα συντεταγμένων πρέπει να ρυθμιστεί λαμβάνοντας υπόψη την αναλογία του πλάτους και του ύψους του παραθύρου.

    //Ρύθμιση του ορθογραφικού συστήματος συντεταγμένων
    διπλή όψη=πλάτος/διπλό(ύψος);
    if(πλάτος>=ύψος)
    {
    gluOrtho2D(-50.*aspect, 50.*aspect, -50., 50.);
    }
    αλλού
    {
    gluOrtho2D(-50., 50., -50./aspect, 50./aspect);
    }

    Προβολή μήτρας

    Ο πίνακας προβολής είναι υπεύθυνος για το σύστημα συντεταγμένων του δημιουργημένου τρισδιάστατου μοντέλου. Κατά τη διαδικασία δημιουργίας ενός μοντέλου, ο πίνακας προβολής μπορεί να αλλάξει πολλές φορές προκειμένου να τροποποιηθεί η εικόνα μεμονωμένων γραφικών πρωτόγονων (μετατρέψτε ένα τετράγωνο σε ορθογώνιο, έναν κύβο σε παραλληλεπίπεδο, μια σφαίρα σε ελλειψοειδές). Για να εγκαταστήσετε και στη συνέχεια να αλλάξετε τη μήτρα προβολής, εκτελέστε τη συνάρτηση glMatrixMode(GL_MODELVIEW). Πρώτα πρέπει επίσης να ακυρώσετε τα πάντα προηγούμενες εγκαταστάσειςκαι μετασχηματισμούς, κάνοντας τον πίνακα προβολής ενικό χρησιμοποιώντας τη συνάρτηση glLoadIdentity(). Εάν οι συντεταγμένες των κορυφών ενός αντικειμένου καθορίζονται κατά τη δημιουργία του, τότε δεν απαιτούνται πρόσθετοι μετασχηματισμοί του συστήματος συντεταγμένων. Ωστόσο, αυτό είναι συχνά δύσκολο ή απλά αδύνατο.

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

    ΜΕΤΑΦΟΡΑ

    Εάν το όρισμα είναι μεγαλύτερο από 0, τότε το αντικείμενο θα μετατοπιστεί προς θετικές τιμές κατά μήκος του άξονα όταν εμφανίζεται. Εάν το όρισμα είναι μικρότερο από 0, τότε το αντικείμενο θα μετατοπιστεί προς αρνητικές τιμές κατά μήκος του άξονα όταν εμφανίζεται.

    Απολέπιση

    Αυτό γίνεται χρησιμοποιώντας μια συνάρτηση που έχει το ακόλουθο πρωτότυπο:

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

    Στροφή

    Αυτό γίνεται χρησιμοποιώντας μια συνάρτηση που έχει το ακόλουθο πρωτότυπο:

    void glRotated (διπλή γωνία, διπλό x, διπλό y, διπλό z); glRotated(30.,0.,0.,1.); //Περιστροφή γύρω από το z
    glBegin(GL_LINE_LOOP);
    //Ρύθμιση κορυφών
    glVertex2d(-2., 2.);
    glVertex2d(2., 2.);
    glVertex2d(2., -2.);
    glVertex2d(-2., -2.);
    glEnd();

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

    Στοίβα μήτρας

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

    Εμφάνιση λιστών

    Ένας ενδιαφέρον και πολύ αποτελεσματικός μηχανισμός για τη δημιουργία σκηνής είναι οι λίστες. Αυτός είναι ένας μηχανισμός που σας επιτρέπει να θυμάστε ακολουθίες εντολών OpenGL και να τις εκτελέσετε ξανά. Αυτό μπορεί να βελτιώσει σημαντικά την απόδοση της απεικόνισης μεγάλες ποσότητεςπανομοιότυπα αντικείμενα.

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

    GLuint glGenLists (εύρος GLsizei);

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

    Για να ξεκινήσετε τη δημιουργία μιας λίστας, πρέπει να καλέσετε τη συνάρτηση

    void glNewList(λίστα GLuint, λειτουργία GLenum);

    Το πρώτο όρισμα καθορίζει το αναγνωριστικό της λίστας που δημιουργείται και το δεύτερο καθορίζει εάν η λίστα θα δημιουργηθεί μόνο (GL_COMPILE) ή θα εμφανιστεί αμέσως (GL_COMPILE_AND_EXECUTE). Στη συνέχεια μπορεί να είναι εντολές OpenGL που πρέπει να αποθηκευτούν στη λίστα. Δεν μπορούν να συμπεριληφθούν όλες οι εντολές σε αυτό.

    Ο σχηματισμός της λίστας τελειώνει με τη συνάρτηση:

    void glEndList(void);

    Μόλις δημιουργηθούν, οι λίστες εμφάνισης αποθηκεύονται στην εσωτερική δομή δεδομένων του παραθύρου OpenGL και θα διαγραφούν όταν το παράθυρο κλείσει ή καταστραφεί.

    Για να εκτελέσετε τη λίστα εμφάνισης, χρησιμοποιήστε την εντολή:

    void glCallList(λίστα GLuint);

    που παίρνει το αναγνωριστικό λίστας ως όρισμα.

    Η συνάρτηση glCallList() μπορεί να κληθεί σε οποιοδήποτε πρόγραμμα memte όταν πρέπει να εκτελεστούν οι εντολές που είναι αποθηκευμένες στη λίστα.

    Ας δούμε ένα παράδειγμα:

    void Draw (άκυρο)
    {
    //Εκκαθάριση της προσωρινής μνήμης χρώματος

    glColor3d(1.0, 1.0, 0.0);

    glBegin(GL_LINES);
    glVertex2d(-50., .0);
    glVertex2d(50., .0);

    Για(int i=-50; i<50; i++)
    {
    glVertex2d(i, .0);
    if(i % 5)
    {
    glVertex2d(i, -1.);
    }
    αλλιώς if(i % 10)
    {
    glVertex2d(i, -2.);
    }
    αλλού
    {
    glVertex2d(i, -3.);
    }
    }
    glEnd();

    glBegin(GL_LINES);
    glVertex2d(.0, -50.);
    glVertex2d(.0, 50.);
    for(int j=-50; j<50; j++)
    {
    glVertex2d(.0, j);
    if(j % ​​5)
    {
    glVertex2d(-1., j);
    }
    αλλιώς εάν (j % 10)
    {
    glVertex2d(-2., j);
    }
    αλλού
    {
    glVertex2d(-3., j);
    }
    }
    glEnd();
    //Τέλος εκτέλεσης εντολής
    glFlush();
    }

    void Draw (άκυρο)
    {
    //Εκκαθάριση της προσωρινής μνήμης χρώματος
    glClear(GL_COLOR_BUFFER_BIT);
    //Ρύθμιση χρώματος οθόνης
    glColor3d(1.0, 1.0, 0.0);

    //Σχηματισμός του άξονα
    int axis = glGenLists(1);
    αν (άξονας != 0)
    {
    glNewList(άξονας, GL_COMPILE);
    glBegin(GL_LINES);
    glVertex2d(0., .0);
    glVertex2d(100., .0);

    Για(int i=0.; i<97; i++)
    {
    glVertex2d(i, .0);
    if(i % 5)
    {
    glVertex2d(i, 1.);
    }
    αλλιώς if(i % 10)
    {
    glVertex2d(i, 2.);
    }
    αλλού
    {
    glVertex2d(i, 3.);
    }
    }
    glEnd();
    //Ο σχηματισμός βέλους μπορεί να προστεθεί αργότερα
    glBegin(GL_LINE_STRIP);
    glVertex2d(97., 1.);
    glVertex2d(100.,.0);
    glVertex2d(97., -1.);
    glEnd();
    glEndList();
    }
    //Σχεδίαση του οριζόντιου άξονα
    glPushMatrix();
    glTranslated(-50.,0.,0.);
    glRotated(180.,1.,0.,0.);
    glCallList(άξονας);
    glPopMatrix();

    //Σχεδίαση του κατακόρυφου άξονα
    glPushMatrix();
    glTranslated(0.,-50.,0.);
    glRotated(90.,0.,0.,1.);
    glCallList(άξονας);
    glPopMatrix();

    //Τέλος εκτέλεσης εντολής
    glFlush();
    }

    Σε κάποιο σημείο, οποιοσδήποτε προγραμματιστής στον τομέα των γραφικών υπολογιστών έχει μια ερώτηση: πώς λειτουργούν αυτοί οι πολλά υποσχόμενοι πίνακες; Μερικές φορές η απάντηση είναι πολύ δύσκολο να βρεθεί και, όπως συμβαίνει συνήθως, η πλειονότητα των προγραμματιστών εγκαταλείπει τα μισά της εργασίας.

    Αυτή δεν είναι λύση στο πρόβλημα! Ας το καταλάβουμε μαζί!

    Ας είμαστε ρεαλιστές με μια πρακτική προκατάληψη και ας πάρουμε το OpenGL έκδοση 3.3 ως θέμα δοκιμής. Ξεκινώντας από αυτήν την έκδοση, κάθε προγραμματιστής πρέπει να εφαρμόσει ανεξάρτητα τη λειτουργική μονάδα matrix. Μπράβο, αυτό χρειαζόμαστε. Ας αποσυνθέσουμε το δύσκολο έργο μας και ας επισημάνουμε τα κύρια σημεία. Μερικά στοιχεία από την προδιαγραφή OpenGL:

    • Οι πίνακες αποθηκεύονται σε στήλες (στήλη-μείζονα).
    • Ομοιογενείς συντεταγμένες;
    • Κανονικός όγκος αποκοπής (CVV) σε αριστερόστροφο σύστημα συντεταγμένων.
    Υπάρχουν δύο τρόποι αποθήκευσης πινάκων: μείζονος στήλης και μείζονος σειράς. Σε διαλέξεις για τη γραμμική άλγεβρα, χρησιμοποιείται το σχήμα μείζονος σειράς. Σε γενικές γραμμές, η αναπαράσταση των πινάκων στη μνήμη δεν έχει σημασία, επειδή ένας πίνακας μπορεί πάντα να μετατραπεί από έναν τύπο αναπαράστασης σε άλλο με απλή μεταφορά. Και επειδή δεν υπάρχει διαφορά, τότε για όλους τους επόμενους υπολογισμούς θα χρησιμοποιήσουμε κλασικούς πίνακες μείζονος σειράς. Κατά τον προγραμματισμό του OpenGL, υπάρχει ένα μικρό κόλπο που σας επιτρέπει να αποφύγετε τη μεταφορά πινάκων διατηρώντας παράλληλα τους κλασικούς υπολογισμούς μείζονος σειράς. Ο πίνακας πρέπει να μεταφερθεί στο πρόγραμμα shader ως έχει, και στον shader ο πολλαπλασιασμός δεν πρέπει να πραγματοποιείται μεταξύ ενός διανύσματος και ενός πίνακα, αλλά μεταξύ ενός πίνακα και ενός διανύσματος.

    Οι ομογενείς συντεταγμένες δεν είναι ένα πολύ δύσκολο σύστημα με έναν αριθμό απλών κανόνων για τη μετατροπή γνωστών καρτεσιανών συντεταγμένων σε ομοιογενείς συντεταγμένες και αντίστροφα. Μια ομοιογενής συντεταγμένη είναι ένας πίνακας σειράς διάστασης. Για να μετατραπεί μια καρτεσιανή συντεταγμένη σε ομοιογενή, είναι απαραίτητο Χ, yΚαι zπολλαπλασιάστε με οποιονδήποτε πραγματικό αριθμό w(εκτός 0). Στη συνέχεια, πρέπει να γράψετε το αποτέλεσμα στα τρία πρώτα στοιχεία και το τελευταίο στοιχείο θα είναι ίσο με τον πολλαπλασιαστή w. Με άλλα λόγια:
    - Καρτεσιανές συντεταγμένες
    w– πραγματικός αριθμός όχι ίσος με 0

    - ομοιογενείς συντεταγμένες

    Ένα μικρό κόλπο: Αν wισούται με ένα, τότε το μόνο που χρειάζεται για τη μετάφραση είναι η μεταφορά των στοιχείων Χ, yΚαι zκαι αντιστοιχίστε ένα στο τελευταίο στοιχείο. Δηλαδή, πάρτε έναν πίνακα σειρών:

    Λίγα λόγια για τη μηδενική ποιότητα w. Από την άποψη των ομοιογενών συντεταγμένων, αυτό είναι αρκετά αποδεκτό. Οι ομοιογενείς συντεταγμένες σας επιτρέπουν να διακρίνετε μεταξύ σημείων και διανυσμάτων. Σε ένα καρτεσιανό σύστημα συντεταγμένων, μια τέτοια διαίρεση είναι αδύνατη.

    - σημείο όπου ( x, y, z) - Καρτεσιανές συντεταγμένες

    - διάνυσμα, όπου ( x, y, z) – διάνυσμα ακτίνας

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

    - ομοιογενείς συντεταγμένες
    - Καρτεσιανές συντεταγμένες

    Το κύριο πράγμα που πρέπει να γνωρίζετε είναι ότι όλοι οι αλγόριθμοι αποκοπής και ραστεροποίησης OpenGL λειτουργούν σε καρτεσιανές συντεταγμένες, αλλά πριν από αυτό όλοι οι μετασχηματισμοί εκτελούνται σε ομοιογενείς συντεταγμένες. Η μετάβαση από ομοιογενείς συντεταγμένες στις καρτεσιανές συντεταγμένες πραγματοποιείται σε υλικό.

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


    Ρύζι. 1. Κανονικός τόμος αποκοπής OpenGL (CVV)

    Αριστερόστροφο σύστημα συντεταγμένων; Πώς μπορεί να συμβεί αυτό, αφού η προδιαγραφή για το OpenGL 1.0 δηλώνει ξεκάθαρα ότι το σύστημα συντεταγμένων που χρησιμοποιείται είναι δεξιόχειρας; Ας το καταλάβουμε.


    Ρύζι. 2. Συστήματα συντεταγμένων

    Όπως φαίνεται από το Σχ. Τα 2 συστήματα συντεταγμένων διαφέρουν μόνο ως προς την κατεύθυνση του άξονα Ζ. Το OpenGL 1.0 χρησιμοποιεί ένα δεξιόστροφο σύστημα συντεταγμένων χρήστη. Αλλά το σύστημα συντεταγμένων CVV και το σύστημα συντεταγμένων χρήστη είναι δύο εντελώς διαφορετικά πράγματα. Επιπλέον, από την έκδοση 3.3, δεν υπάρχει πλέον τυπικό σύστημα συντεταγμένων OpenGL. Όπως αναφέρθηκε προηγουμένως, ο ίδιος ο προγραμματιστής υλοποιεί την ενότητα λειτουργιών μήτρας. Σχηματισμός πινάκων περιστροφής, σχηματισμός πινάκων προβολής, αναζήτηση αντίστροφου πίνακα, πολλαπλασιασμός πινάκων - αυτό είναι το ελάχιστο σύνολο πράξεων που περιλαμβάνεται στην ενότητα λειτουργιών μήτρας. Προκύπτουν δύο λογικά ερωτήματα. Εάν ο όγκος ορατότητας είναι ένας κύβος με μήκος άκρης ίσο με δύο, τότε γιατί μια σκηνή σε μέγεθος αρκετών χιλιάδων είναι ορατή στην οθόνη; Σε ποιο σημείο το σύστημα συντεταγμένων χρήστη μετατρέπεται σε σύστημα συντεταγμένων CVV; Οι πίνακες προβολής είναι ακριβώς η οντότητα που ασχολείται με αυτά τα ζητήματα.

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

    Ένας από τους πιο συνηθισμένους και δύσκολους στην κατανόηση πίνακες είναι ο πίνακας μετασχηματισμού προοπτικής. Πώς σχετίζεται λοιπόν με το CVV και το σύστημα συντεταγμένων του χρήστη; Γιατί τα αντικείμενα γίνονται μικρότερα όσο αυξάνεται η απόστασή τους από τον παρατηρητή; Για να κατανοήσουμε γιατί τα αντικείμενα συρρικνώνονται καθώς αυξάνεται η απόσταση, ας δούμε τους μετασχηματισμούς μήτρας ενός τρισδιάστατου μοντέλου βήμα προς βήμα. Δεν είναι μυστικό ότι οποιοδήποτε τρισδιάστατο μοντέλο αποτελείται από μια πεπερασμένη λίστα κορυφών που υφίστανται μετασχηματισμούς μήτρας εντελώς ανεξάρτητα η μία από την άλλη. Για να προσδιορίσετε τη συντεταγμένη μιας τρισδιάστατης κορυφής σε μια οθόνη δισδιάστατης οθόνης, πρέπει:

    1. Μετατροπή καρτεσιανής συντεταγμένης σε ομοιογενή συντεταγμένη.
    2. Πολλαπλασιάστε την ομοιογενή συντεταγμένη με τον πίνακα του μοντέλου.
    3. Το αποτέλεσμα πολλαπλασιάζεται με τον πίνακα προβολής.
    4. Πολλαπλασιάστε το αποτέλεσμα με τον πίνακα προβολής.
    5. Μετατρέψτε το αποτέλεσμα από ομοιογενείς συντεταγμένες σε καρτεσιανές συντεταγμένες.
    Η μετατροπή των καρτεσιανών συντεταγμένων σε ομοιογενείς συντεταγμένες συζητήθηκε νωρίτερα. Η γεωμετρική έννοια του πίνακα του μοντέλου είναι να μεταφέρει το μοντέλο από ένα τοπικό σύστημα συντεταγμένων σε ένα παγκόσμιο σύστημα συντεταγμένων. Ή, όπως λένε, μετακινήστε τις κορυφές από το χώρο του μοντέλου στον παγκόσμιο χώρο. Ας το θέσω απλά, ένα τρισδιάστατο αντικείμενο που φορτώνεται από ένα αρχείο βρίσκεται στο χώρο του μοντέλου, όπου οι συντεταγμένες μετρώνται σε σχέση με το ίδιο το αντικείμενο. Στη συνέχεια, χρησιμοποιώντας τη μήτρα του μοντέλου, το μοντέλο τοποθετείται, κλιμακώνεται και περιστρέφεται. Ως αποτέλεσμα, όλες οι κορυφές του τρισδιάστατου μοντέλου λαμβάνουν πραγματικές ομοιογενείς συντεταγμένες στην τρισδιάστατη σκηνή. Ο χώρος του μοντέλου σε σχέση με τον παγκόσμιο χώρο είναι τοπικός. Από το χώρο του μοντέλου, οι συντεταγμένες μεταφέρονται στον παγκόσμιο χώρο (από τοπικό σε παγκόσμιο). Για το σκοπό αυτό, χρησιμοποιείται ένας πίνακας μοντέλων.

    Τώρα ας προχωρήσουμε στο τρίτο βήμα. Εδώ παίζει ρόλο ο χώρος προβολής. Σε αυτό το χώρο, οι συντεταγμένες μετρώνται σε σχέση με τη θέση και τον προσανατολισμό του παρατηρητή σαν να ήταν το κέντρο του κόσμου. Ο χώρος προβολής είναι τοπικός σε σχέση με τον παγκόσμιο χώρο, επομένως οι συντεταγμένες πρέπει να εισαχθούν σε αυτόν (και όχι να αφαιρεθούν, όπως στην προηγούμενη περίπτωση). Ο μετασχηματισμός άμεσου πίνακα αφαιρεί συντεταγμένες από κάποιο χώρο. Για να τα εισαγάγουμε σε αυτό, αντίθετα, είναι απαραίτητο να αντιστρέψουμε τον μετασχηματισμό πίνακα, επομένως ο μετασχηματισμός τύπου περιγράφεται από τον αντίστροφο πίνακα. Πώς να αποκτήσετε αυτόν τον αντίστροφο πίνακα; Αρχικά, ας πάρουμε τον πίνακα άμεσου παρατηρητή. Τι χαρακτηρίζει έναν παρατηρητή; Ο παρατηρητής περιγράφεται από τη συντεταγμένη στην οποία βρίσκεται και τα διανύσματα κατεύθυνσης θέασης. Ο παρατηρητής κοιτάζει πάντα προς την κατεύθυνση του τοπικού του άξονα Ζ. Ο παρατηρητής μπορεί να κινείται γύρω από τη σκηνή και να κάνει στροφές. Από πολλές απόψεις, αυτό μοιάζει με το νόημα της μήτρας του μοντέλου. Σε γενικές γραμμές, έτσι είναι. Ωστόσο, για έναν παρατηρητή, η λειτουργία κλιμάκωσης δεν έχει νόημα, επομένως, δεν μπορεί να τεθεί πρόσημο ίσου μεταξύ της μήτρας μοντέλου του παρατηρητή και της μήτρας μοντέλου ενός τρισδιάστατου αντικειμένου. Η μήτρα του μοντέλου του παρατηρητή είναι η επιθυμητή άμεση μήτρα. Αντιστρέφοντας αυτόν τον πίνακα, λαμβάνουμε τον πίνακα προβολής. Στην πράξη, αυτό σημαίνει ότι όλες οι κορυφές σε καθολικές ομοιογενείς συντεταγμένες θα λάβουν νέες ομοιογενείς συντεταγμένες σε σχέση με τον παρατηρητή. Αντίστοιχα, αν ο παρατηρητής είδε μια ορισμένη κορυφή, τότε η τιμή της ομοιογενούς συντεταγμένης zμιας δεδομένης κορυφής στο χώρο προβολής θα είναι σίγουρα ένας θετικός αριθμός. Αν η κορυφή βρισκόταν πίσω από τον παρατηρητή, τότε η τιμή της ομοιογενούς συντεταγμένης του zο χώρος προβολής θα είναι σίγουρα αρνητικός αριθμός.

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

    Εξετάστε έναν πίνακα της φόρμας:

    Και ένα σημείο στον ομοιογενή χώρο του παρατηρητή:

    Ας πολλαπλασιάσουμε την ομοιογενή συντεταγμένη με τον εν λόγω πίνακα:

    Ας μετατρέψουμε τις ομογενείς συντεταγμένες που προκύπτουν σε καρτεσιανές συντεταγμένες:

    Ας υποθέσουμε ότι υπάρχουν δύο σημεία στο χώρο προβολής με τις ίδιες συντεταγμένες ΧΚαι y, αλλά με διαφορετικές συντεταγμένες z. Με άλλα λόγια, το ένα από τα σημεία βρίσκεται πίσω από το άλλο. Λόγω της παραμόρφωσης της προοπτικής, ο παρατηρητής πρέπει να δει και τα δύο σημεία. Πράγματι, είναι σαφές από τον τύπο ότι λόγω διαίρεσης με τη συντεταγμένη z, συμβαίνει συμπίεση στο σημείο προέλευσης. Όσο μεγαλύτερη είναι η τιμή z(όσο πιο μακριά είναι το σημείο από τον παρατηρητή), τόσο ισχυρότερη είναι η συμπίεση. Αυτή είναι η εξήγηση για το προοπτικό αποτέλεσμα.

    Η προδιαγραφή OpenGL δηλώνει ότι οι λειτουργίες αποκοπής και ραστεροποίησης εκτελούνται σε καρτεσιανές συντεταγμένες και η διαδικασία μετατροπής ομοιογενών συντεταγμένων σε καρτεσιανές συντεταγμένες εκτελείται αυτόματα.

    Ο πίνακας (1) είναι ένα πρότυπο για έναν πίνακα προοπτικής προβολής. Όπως αναφέρθηκε προηγουμένως, η εργασία του πίνακα προβολής αποτελείται από δύο σημεία: ρύθμιση ενός συστήματος συντεταγμένων χρήστη (αριστερόχειρας ή δεξιόχειρας), μεταφορά του όγκου ορατότητας του παρατηρητή στο CVV. Ας εξαγάγουμε έναν πίνακα προοπτικής για ένα σύστημα συντεταγμένων αριστερόχειρα χρήστη.

    Ο πίνακας προβολής μπορεί να περιγραφεί χρησιμοποιώντας τέσσερις παραμέτρους (Εικ. 3):

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


    Ρύζι. 3. Προοπτικός όγκος ορατότητας

    Ας εξετάσουμε την προβολή ενός σημείου στο χώρο του παρατηρητή στο μπροστινό άκρο της αποκοπής του προοπτικού όγκου ορατότητας. Για μεγαλύτερη σαφήνεια, στο Σχ. 4 δείχνει μια πλάγια όψη. Θα πρέπει επίσης να ληφθεί υπόψη ότι το σύστημα συντεταγμένων του χρήστη συμπίπτει με το σύστημα συντεταγμένων CVV, δηλαδή το αριστερό σύστημα συντεταγμένων χρησιμοποιείται παντού.


    Ρύζι. 4. Προβολή αυθαίρετου σημείου

    Με βάση τις ιδιότητες όμοιων τριγώνων, ισχύουν οι ακόλουθες ισότητες:

    Ας εκφράσουμε τα yꞌ και xꞌ:

    Κατ' αρχήν, οι εκφράσεις (2) επαρκούν για να ληφθούν οι συντεταγμένες των σημείων προβολής. Ωστόσο, για να ελέγξετε σωστά τα τρισδιάστατα αντικείμενα, πρέπει να γνωρίζετε το βάθος κάθε θραύσματος. Με άλλα λόγια, είναι απαραίτητο να αποθηκεύσετε την τιμή του στοιχείου z. Αυτή είναι η τιμή που χρησιμοποιείται για τις δοκιμές βάθους OpenGL. Στο Σχ. 3 είναι σαφές ότι η τιμή zꞌδεν είναι κατάλληλο ως βάθος θραύσματος, επειδή όλες οι σημειακές προβολές έχουν την ίδια τιμή zꞌ. Η διέξοδος από αυτή την κατάσταση είναι να χρησιμοποιήσετε το λεγόμενο ψευδο-βάθος.

    Ιδιότητες ψευδοβάθους:

    1. Το ψευδο-βάθος υπολογίζεται με βάση την τιμή z;
    2. Όσο πιο κοντά είναι το σημείο στον παρατηρητή, τόσο λιγότερη τιμή έχει το ψευδό βάθος.
    3. Όλα τα σημεία που βρίσκονται στο μπροστινό επίπεδο του όγκου ορατότητας έχουν τιμή ψευδοβάθους -1.
    4. Όλα τα σημεία που βρίσκονται στο μακρινό επίπεδο κοπής του όγκου ορατότητας έχουν τιμή ψευδοβάθους 1.
    5. Όλα τα θραύσματα που βρίσκονται μέσα στον όγκο ορατότητας έχουν μια τιμή ψευδοβάθους στην περιοχή [-1 1].
    Ας εξαγάγουμε τον τύπο με τον οποίο θα υπολογιστεί το ψευδοβάθος. Ας πάρουμε ως βάση την ακόλουθη έκφραση:

    Πιθανότητα έναΚαι σιπρέπει να υπολογιστεί. Για να το κάνουμε αυτό, χρησιμοποιούμε τις ιδιότητες των ψευδο-βαθών 3 και 4. Λαμβάνουμε ένα σύστημα δύο εξισώσεων με δύο άγνωστα:

    Ας προσθέσουμε και τα δύο μέρη του συστήματος και ας πολλαπλασιάσουμε το αποτέλεσμα με το γινόμενο στ, όπου φάΚαι nδεν μπορεί να είναι ίσο με μηδέν. Παίρνουμε:

    Ας ανοίξουμε τις αγκύλες και ας αναδιατάξουμε τους όρους έτσι ώστε μόνο το τμήμα με ΕΝΑ, και στα δεξιά μόνο με σι:

    Ας αντικαταστήσουμε το (6) στο (5). Ας μετατρέψουμε την έκφραση σε απλό κλάσμα:

    Πολλαπλασιάστε και τις δύο πλευρές κατά -2fn, όπου φάΚαι nδεν μπορεί να είναι ίσο με μηδέν. Ας παρουσιάσουμε παρόμοια, ας αναδιατάξουμε τους όρους και ας εκφράσουμε σι:

    Ας αντικαταστήσουμε το (7) σε (6) και ας εκφράσουμε ένα:

    Αντίστοιχα τα εξαρτήματα έναΚαι σιείναι ίσα:

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

    Αφήστε την απόσταση από το μπροστινό επίπεδο κοπής nισούται με 2 και η απόσταση από το μακρινό επίπεδο αποκοπής φάισούται με 10. Θεωρήστε πέντε σημεία στον ομοιογενή χώρο του παρατηρητή:

    Η σχετική θέση του σημείου και ο όγκος ορατότητας
    Τελεία Εννοια Περιγραφή
    1 1 Το σημείο βρίσκεται μπροστά από το μπροστινό επίπεδο κοπής του όγκου ορατότητας. Δεν περνάει από ραστεροποίηση.
    2 2 Το σημείο βρίσκεται στο μπροστινό άκρο της αποκοπής όγκου ορατότητας. Υποβάλλεται σε ραστεροποίηση.
    3 5 Το σημείο βρίσκεται μεταξύ της μπροστινής ακμής αποκοπής και της μακρινής άκρης αποκοπής της έντασης ορατότητας. Υποβάλλεται σε ραστεροποίηση.
    4 10 Το σημείο βρίσκεται στο μακρινό άκρο της αποκοπής όγκου ορατότητας. Υποβάλλεται σε ραστεροποίηση.
    5 20 Το σημείο βρίσκεται πέρα ​​από το μακρινό άκρο της αποκοπής όγκου ορατότητας. Δεν περνάει από ραστεροποίηση.

    Ας πολλαπλασιάσουμε όλα τα σημεία με τον πίνακα (8) και στη συνέχεια μετατρέψουμε τις ομοιογενείς συντεταγμένες που προκύπτουν σε καρτεσιανές συντεταγμένες . Για να γίνει αυτό, πρέπει να υπολογίσουμε τις τιμές των νέων ομοιογενών συστατικών Και .
    Σημείο 1:

    Σημειώστε ότι η ομογενής συντεταγμένη είναι απολύτως σωστά τοποθετημένο στο CVV, και το πιο σημαντικό, η δοκιμή βάθους OpenGL είναι πλέον δυνατή, επειδή το ψευδο-βάθος ικανοποιεί πλήρως τις απαιτήσεις δοκιμής.

    Με συντεταγμένη zΤο καταλάβαμε, ας περάσουμε στις συντεταγμένες ΧΚαι y. Όπως αναφέρθηκε προηγουμένως, ολόκληρος ο όγκος της προοπτικής ορατότητας πρέπει να ταιριάζει στο CVV. Το μήκος της άκρης CVV είναι δύο. Αντίστοιχα, το ύψος και το πλάτος του προοπτικού όγκου ορατότητας πρέπει να συμπιέζονται σε δύο συμβατικές μονάδες.

    Έχουμε στη διάθεσή μας μια γωνιά βούτυροκαι μέγεθος άποψη. Ας εκφράσουμε το ύψος και το πλάτος χρησιμοποιώντας αυτές τις τιμές.


    Ρύζι. 5. Όγκος ορατότητας

    Από το Σχ. 5 είναι σαφές ότι:

    Τώρα μπορούμε να πάρουμε την τελική άποψη του πίνακα προβολής προοπτικής για ένα προσαρμοσμένο σύστημα συντεταγμένων με αριστερόστροφο που λειτουργεί με το CVV OpenGL:

    Αυτό ολοκληρώνει την παραγωγή πινάκων.

    Λίγα λόγια για το DirectX - τον κύριο ανταγωνιστή του OpenGL. Το DirectX διαφέρει από το OpenGL μόνο ως προς τις διαστάσεις του CVV και τη θέση του. Στο DirectX, ένα CVV είναι ένα ορθογώνιο παραλληλεπίπεδο με μήκη κατά μήκος των αξόνων του ΧΚαι yίσο με δύο, και κατά μήκος του άξονα zτο μήκος είναι ίσο με ένα. Εύρος ΧΚαι yείναι [-1 1] και το εύρος zίσο με . Όσο για το σύστημα συντεταγμένων CVV, το DirectX, όπως και το OpenGL, χρησιμοποιεί ένα αριστερόστροφο σύστημα συντεταγμένων.

    Για να εμφανίσετε προοπτικούς πίνακες για ένα προσαρμοσμένο δεξιόστροφο σύστημα συντεταγμένων, είναι απαραίτητο να επανασχεδιάσετε το Σχ. 2, Σχ. 3 και Σχ. 4 λαμβάνοντας υπόψη τη νέα κατεύθυνση του άξονα Ζ. Οι περαιτέρω υπολογισμοί είναι εντελώς παρόμοιοι, μέχρι το πρόσημο. Για πίνακες DirectX, οι ιδιότητες ψευδοβάθους 3 και 4 τροποποιούνται για να ταιριάζουν στο εύρος.

    Σε αυτό το σημείο, το θέμα των υποσχόμενων πινάκων μπορεί να θεωρηθεί κλειστό.