C# OpenGL διεπαφή
Windows για το λειτουργικό σύστημα
Colin Fahey

CSGL12Control σε Form, σημειώνοντας "fractal" pixel shader πρόγραμμα και κατάρτιση GDI+ αντιγράφεται σε υφή

Δύο περιπτώσεις CSGL12Control σε Form, δείχνοντας pixel shader προγράμματα και υφή

A 3D avatar roams ότι η επιφάνεια εργασίας και μπορούν να μετακινούνται με το δρομέα
1. Λογισμικό
CSGL12_20090725.zip
CSGL12: C# OpenGL διεπαφή για Windows, έκδοση 12
4170499 bytes
MD5: 30781a6570441785ea636f2ae1cd16ef
2. Όλα τα C# υπολογιστή κωδικό στο C# OpenGL διεπαφής (CSGL12) είναι στο "δημόσιο τομέα"
Έγραψα όλα τα C# κώδικα υπολογιστή κατά την C# OpenGL διεπαφής (CSGL12).
Δηλώνω όλων των C# κώδικα υπολογιστή κατά την C# OpenGL διεπαφής (CSGL12) να είναι στο "δημόσιο τομέα."
Επομένως, ο υπολογιστής κωδικός μπορεί να χρησιμοποιηθεί για οποιονδήποτε σκοπό (εμπορικό ή ιδιωτικό), χωρίς πληρωμή, χωρίς περιορισμούς, χωρίς υποχρεώσεις, και χωρίς την αναγνώριση του αρχικού συγγραφέα.
Ο κωδικός μπορεί να τροποποιηθεί, να επαναχρησιμοποιούνται ή μερίδων, χωρίς περιορισμούς και χωρίς υποχρεώσεις, και χωρίς την αναγνώριση του αρχικού συγγραφέα.
Το παράδειγμα προγράμματα περιλαμβάνουν ένα μικρό ποσό του κώδικα υπολογιστή (συγκεκριμένα, "shader κώδικα υπολογιστή) είναι γραμμένα από άλλους ανθρώπους." Ο κωδικός δεν είναι, κατά την ίδια διασύνδεση και επιπόλαια μπορεί να αφαιρεθεί. Ο κωδικός είναι απλώς για να αποδείξει την απλότητα της χρήσης του interface για τη δημιουργία και τη χρήση "shader" προγράμματα.
3. Εισαγωγή
"CSGL12" είναι μια συλλογή από C# υπολογιστή αρχεία κώδικα που υλοποιεί μια διασύνδεση με το OpenGL βιβλιοθήκη γραφικών (συμπεριλαμβανομένων όλων των επεκτάσεων των OpenGL μέχρι το έτος 2007) για το λειτουργικό σύστημα Windows.
Ο κωδικός C# υπολογιστή αρχεία στο "CSGL12" συλλογή μπορείτε εύκολα να προσθέσετε OpenGL κατάρτιση σε κάθε C# / .NET λογισμικό με "Form" (ένα παράδειγμα της "System.Windows.Forms.Form").
Η συλλογή των "CSGL12" κώδικα υπολογιστή αρχεία περιλαμβάνει το αρχείο με το όνομα "CSGL12Control.cs", το οποίο ορίζει μια κλάση ονομάζεται "CSGL12Control", που προέρχονται από "System.Windows.Forms.Control". Κάθε κλίμακα της "CSGL12Control" αντιπροσωπεύει ένα ανεξάρτητο OpenGL την περιοχή. Είναι πολύ εύκολο να προσθέσετε πολλαπλές εμφανίσεις του CSGL12Control σε Form (ένα παράδειγμα της System.Windows.Forms.Form).
4. Χαρακτηριστικά και απαιτήσεις του "CSGL12"
Ο κώδικας είναι μόνο για Windows τα λειτουργικά συστήματα που υποστηρίζουν την .NET 2.0 Framework (Windows 2000, Windows XP, Windows Vista, Windows 7)
Ο κωδικός μπορεί να συλλέγονται με βάση "Microsoft Visual C# 2008 Express Edition" (ένα ελεύθερο μεταγλωττιστή), ή παρόμοια C# συμβολομεταφραστές.
Ο κώδικας απαιτεί που δημιουργείται με την επιλογή "[X] Allow unsafe code" οικοδομήσουμε επιλεγεί έτσι ώστε να βελτιστοποιείται εικόνα λειτουργίες αντιγραφής δεδομένων μπορούν να χρησιμοποιηθούν. Εάν είστε εμπειρογνώμονας C# προγραμματιστής θα έχετε την δυνατότητα να εντοπίζουν εύκολα τις μερίδες του κώδικα C# που απαιτούν την "unsafe" δυνατότητα απενεργοποίησης τους και αν είναι επιθυμητό ή απαιτούνται. Αντιγραφή δεδομένων εικόνας είναι 10 φορές πιο γρήγορα χρησιμοποιώντας "unsafe" κωδικό από την εναλλακτική λύση, και γι 'αυτές τις κωδικός χρησιμοποιείται. Αν οικοδομήσουμε μια DLL που περιέχει όλα τα "unsafe" κωδικό, στη συνέχεια, ένα έργο που χρησιμοποιεί ότι DLL δεν απαιτεί που δημιουργείται με την επιλογή "unsafe", και έτσι μπορείτε να συμπεράνουμε ότι η έλλειψη της δυνατότητας "unsafe" σε ένα έργο που δεν συνεπάγεται καμία πρόσθετη ασφάλεια (γιατί πολλές DLL αρχεία που χρησιμοποιούνται, ρητά ή σιωπηρά από το πρόγραμμα περιλαμβάνει "επισφαλών" κωδικός).
Ο κωδικός μπορεί να συγκεντρώνονται και να χρησιμοποιούνται από οποιοδήποτε από τα ακόλουθα:
Microsoft Visual C# 2008 Express Edition
Microsoft Visual Studio 2008
Microsoft .NET 3.5 SDK
SharpDevelop
Mono Project
Ο κώδικας προσφέρει πλέον OpenGL επεκτάσεις (μέσω του έτους 2007), συμπεριλαμβανομένων "vertex shaders" και "pixel shaders".
Ο κώδικας προβλέπει 1570 λειτουργίες που σχετίζονται με OpenGL:
336 GL functions
51 GLU functions
19 WGL functions
1164 extensions
Ο κώδικας προσφέρει κάποια εναλλακτική λύση από τις διακυμάνσεις 1570 λειτουργίες με διαφορετικά είδη παράμετρος, για την ευκολία.
Ο κώδικας ορίζει περισσότερες από 3244 σταθερές για OpenGL.
Ο κώδικας δίνει τη δυνατότητα να έχουν πολλαπλούς OpenGL επεξεργασία πλαίσια, όλα εμψύχωση του ανεξάρτητα, σε οποιαδήποτε "Form".
Κάνοντας κλικ σε μια "CSGL12Control" δίνει "εισροών εστίαση," που επιτρέπει μεταγενέστερη πληκτρολόγιο και το ποντίκι τροχό εισροών. Δρομέας κλικ και οι κινήσεις που ελήφθη όταν ο κέρσορας βρίσκεται εντός της ζώνης ενός ορθογωνίου παράδειγμα της "CSGL12Control".
Ο κώδικας περιλαμβάνει λειτουργίες να αποδείξει πώς μπορεί να γίνει κάποια κοινή OpenGL καθήκοντα στο C# και .NET.
Ο κώδικας παραθέτει όλα OpenGL σταθερές λειτουργίες και κατ 'αλφαβητική σειρά σε "class GL" στο "GL.cs", είναι εύκολο να καθοριστεί αν υπάρχει συνεχής λειτουργία ή λείπει (το οποίο είναι απίθανο, εκτός από τις παρατάσεις που εγκρίθηκαν μετά το έτος 2007).
Το παράδειγμα προγράμματα δείχνουν πώς μπορεί να γίνει GDI+ κατάρτιση σε Bitmap και, στη συνέχεια, με την αντιγραφή που Bitmap σε OpenGL υφή.
Αυτό το κείμενο επιτρέπει και άλλες GDI+ αντλώντας δυνατότητες να συμβάλει στην OpenGL σκηνή.
Η GDI+ Bitmap θα μπορεί να ενημερώνεται και το ανέβασα σε OpenGL υφή όσο συχνά μία φορά ανά OpenGL πλαίσιο.
Το παράδειγμα προγράμματα δείχνουν πώς να επιλέξουν μεταξύ πολλών διαφορετικών "pixel shader programs", ενώ το πρόγραμμα εκτελείται.
Το παράδειγμα τα προγράμματα δείχνουν πως να γράφουν OpenGL buffers για αρχεία εικόνας (JPG, BMP, GIF, PNG).
Πατήστε Shift + 0 (στροφή-μηδέν) για να γράψετε τη OpenGL buffer για αρχεία εικόνας.
Το παράδειγμα δείχνει τον τρόπο με τον κωδικό "GL.cs" στη συγκέντρωση σε ένα DLL αρχείο και, στη συνέχεια, προσθέτοντας ότι DLL αρχείο σε ένα άλλο σχέδιο, μπορεί να αποτρέψει την Microsoft κωδικό τους συντάκτες (π.χ., Microsoft Visual C# 2008 Express Edition, κλπ) με "IntelliSense" (εκάστοτε πλαισίου κώδικα ολοκλήρωση) από το να γίνει συχνά και επίμονα αδιάφορη (επανειλημμένα παύσεις για πολλά δευτερόλεπτα, καθιστώντας το πρόγραμμα επεξεργασίας εντελώς άχρηστα). Αφού το αρχείο "GL.cs" άμεσα περιλαμβάνονται σε οποιοδήποτε σχέδιο επεξεργάζεται από ένα Microsoft κωδικό editor δεν είναι πρακτικά, αν ένα άτομο είναι πρόθυμο να αντέξει τη βραδύτητα της επεξεργασίας. Το πρόβλημα αυτό έχει επηρεάσει Microsoft Visual Studio 2003, 2005, 2008, και πιθανότατα θα επηρεάσουν την 2010 έκδοση, επίσης.
Το παράδειγμα κώδικα δείχνει τη χρήση των πολλαπλών εμφανίσεων του "CSGL12Control" σε "Form".
Το παράδειγμα κώδικα περιλαμβάνει κώδικα για να κάνω μια 3D "avatar" ότι roams την επιφάνεια εργασίας του Windows.
5. Παράδειγμα προγράμματα που περιλαμβάνονται στο "CSGL12"
5.1 "CSGL12DLL"
Το έργο ονομάζεται "CSGL12DLL" παράγει DLL αρχείο με το όνομα "CSGL12DLL.dll" το οποίο περιέχει "class GL" (που ορίζεται στο C# αρχείο "GL.cs").
Κάνοντας "class GL" σε DLL στο αρχείο και, στη συνέχεια, χρησιμοποιώντας DLL ότι σε άλλα προγράμματα που χρησιμοποιούν "class GL", βοηθά στην αποφυγή μια ακραία πρόβλημα με όλους τους συντάκτες Microsoft κωδικό με το χαρακτηριστικό IntelliSense. Χρησιμοποιώντας το C# αρχείο GL.cs άμεσα σε ένα έργο που θα προκαλέσει τυχόν Microsoft κωδικός editor με τη IntelliSense τη δυνατότητα για να γίνει εντελώς αδιάφορη και άχρηστα σχεδόν συνεχώς, λόγω της αναποτελεσματικότητας του IntelliSense τη δυνατότητα (και το γεγονός ότι το μπλοκ IntelliSense προφανώς το κύριο πρόγραμμα το νήμα του συντάκτη ).
Αν χρησιμοποιείτε έναν κωδικό C# επεξεργαστή που δεν παράγονται από Microsoft (π.χ., "SharpDevelop", "MonoDevelop", κτλ), τότε μπορείτε απλά να περιλαμβάνει το αρχείο "GL.cs" άμεσα με τα έργα σας, και σας θα είναι απίθανο να έχουν κανένα όφελος από τη χρήση "CSGL12DLL.dll".
5.2 "CSGL12Control"
Το έργο ονομάζεται "CSGL12Control" παράγει DLL αρχείο με το όνομα "CSGL12Control.dll" το οποίο περιέχει "class CSGL12Control" (που ορίζεται στο C# αρχείο "CSGL12Control.cs").
Κάνοντας "class CSGL12Control" σε DLL στο αρχείο, που επιτρέπει "Control" (δηλαδή, μια κατηγορία που προέρχονται από "System.Windows.Forms.Control") να προστεθούν στο "Toolbox" των Microsoft Visual C# 2008 Express Edition (και παρόμοια C# εκδότες). Έχοντας "CSGL12Control" στην "Toolbox" καθιστά εύκολο για ένα άτομο για να προσθέσετε ένα παράδειγμα της "CSGL12Control" σε "Form" στην "Designer" (π.χ., ένα άτομο μπορεί απλά να χρησιμοποιήσετε το δρομέα για να επιλέξετε και να σύρετε ένα παράδειγμα της "CSGL12Control" από την "Toolbox" σε "Form").
Η "CSGL12Control" αντικείμενο διαχειρίζεται μια OpenGL κατάρτιση πλαίσιο. Πολλαπλές εμφανίσεις του "CSGL12Control" μπορούν να συνυπάρξουν σε μια "Form".
5.3 "CSGL12Example1"
Το έργο ονομάζεται "CSGL12Example1" παράγει ένα εκτελέσιμο αρχείο προγράμματος (EXE) ονομάζεται "CSGL12Example1.exe". Το πρόγραμμα χρησιμοποιεί "CSGL12DLL.dll" και "CSGL12Control.dll" να εμφανίσει ένα παράδειγμα της CSGL12Control και καταλήξει σε κύβους χρησιμοποιώντας OpenGL.
Οι πρόγραμμα δείχνει τη χρήση των τεσσάρων διαφορετικών "pixel shaders" "(fractal, τούβλο, ξύλο," και "σκίτσο)."
Το πρόγραμμα δείχνει επίσης τη χρήση των "GDI+", μια .NET την βιβλιοθήκη, να καταρτίσει σχέδιο και άλλα σχήματα σε ένα αντικείμενο "Bitmap" (α "GDI+" αντικείμενο) και, στη συνέχεια, αντίγραφο των δεδομένων από την εικόνα που "Bitmap" σε "texture" στο OpenGL, επιτρέποντας έτσι την εικόνα που από "GDI+" να εμφανιστεί στο OpenGL κατάρτιση. Αυτή η δυνατότητα είναι πολύ χρήσιμη, διότι στερείται OpenGL πολλά από τα χαρακτηριστικά 2D κατάρτιση που βρέθηκαν στο "GDI+" και παρόμοια 2D κατάρτιση libaries.
5.4 "CSGL12Example2"
Το έργο ονομάζεται "CSGL12Example2" παράγει ένα εκτελέσιμο αρχείο προγράμματος (EXE) ονομάζεται "CSGL12Example2.exe". Το πρόγραμμα χρησιμοποιεί "CSGL12DLL.dll" και "CSGL12Control.dll" για την απεικόνιση των CSGL12Control δύο περιπτώσεις, κάθε μία από τις οποίες αντλεί ένας κύβος χρησιμοποιώντας OpenGL.
Το πρόγραμμα έχει "SplitContainer" "Control" για την "Form". Κάθε μία από τις δύο περιοχές της "SplitContainer" περιέχει ένα παράδειγμα της CSGL12Control. Έτσι, ένα άτομο μπορεί να προσαρμόσει τη θέση του διαχωρισμού μεταξύ των δύο εμφανίσεις του CSGL12Control. Αυτό αποδεικνύει την ευελιξία του CSGL12Control.
Μία από τις εμφανίσεις του CSGL12Control στέλνει μια σειρά εκδηλώσεων για την περίπτωση της εξυπηρέτησης σε ένα παράδειγμα του "CSGL12Example2Handler1.cs", η οποία χρησιμοποιεί τον ίδιο κωδικό όπως "CSGL12Example1Handler.cs" στην "CSGL12Example1" παράδειγμα έργου. Ως εκ τούτου, μία από τις περιπτώσεις CSGL12Control αντλεί ένας κύβος με μία επιλεγμένη "pixel shader" μεταξύ τέσσερις διαθέσιμες "pixel shaders".
Το άλλο παράδειγμα της CSGL12Control στέλνει μια σειρά εκδηλώσεων για την περίπτωση της εξυπηρέτησης σε ένα παράδειγμα του "CSGL12Example2Handler2.cs", στην οποία γίνεται ένας κύβος χρησιμοποιώντας υφή εικόνα (ή μια "σκακιέρα" πρότυπο αν ένα αρχείο εικόνας που ονομάζεται "image.jpg" δεν βρέθηκαν).
5.5 "CSGL12Avatar"
Το έργο ονομάζεται "CSGL12Avatar" παράγει ένα εκτελέσιμο αρχείο προγράμματος (EXE) ονομάζεται "CSGL12Avatar.exe". Το πρόγραμμα χρησιμοποιεί "CSGL12DLL.dll" και "CSGL12Control.dll" να καταλήξει σε κύβους χρησιμοποιώντας OpenGL για να "Form" χωρίς σύνορα, με βάση το χρώμα της διαφάνειας ενεργοποιημένη, για να έλκει 3D "avatar" ότι roams την επιφάνεια εργασίας Windows περιοχή.
Τα κινητά avatar μπορεί να κάνει κλικ και να παρασυρθούν σε μια νέα θέση, χρησιμοποιώντας το δρομέα. Διπλό κλικ στο avatar θα καταστήσει εξαφανίζονται. Αν και ο κώδικας απλώς αντλεί ένας κύβος, OpenGL μπορεί να χρησιμοποιηθεί για να αντλήσει άλλα πράγματα.
Πολλαπλές εμφανίσεις του "avatar" του προγράμματος μπορεί να ξεκινήσει. Έτσι, πολλές ανεξάρτητες "avatar" περιπτώσεις μπορεί ταυτόχρονα Windows περιφέρονται την επιφάνεια εργασίας. Αυτό είναι αστείο. Ο εμπειρογνώμονας C# προγραμματιστής μπορεί να απολαύσει την εξεύρεση τρόπων για τον συντονισμό της δραστηριότητας των "avatar" πολλές τέτοιες περιπτώσεις.
Δυστυχώς, ο ρυθμός με τον οποίο το αντικείμενο Window με διαφάνεια ενημερώνεται επί της οθόνης είναι πολύ βραδύτερη από το ρυθμό με τον οποίο μπορούν να αντλήσουν OpenGL. Το "avatar" ενημερώνει μόνο 10 φορές ανά δευτερόλεπτο. Δεν ξέρω αν αυτό μπορεί να βελτιωθεί.
5.6 "CSGL12BuiltExecutableExamplesForReference"
Ο κατάλογος περιλαμβάνει το όνομα "CSGL12BuiltExecutableExamplesForReference" αρχεία DLL και EXE όλα τα αρχεία που παράγονται από το παράδειγμα των έργων. Τα αρχεία αυτά που παρέχονται ως σημείο αναφοράς, ώστε τα αρχεία να μπορεί να ελεγχθεί άμεσα, ακόμη και αν ένα άτομο δεν έχει την ικανότητα να συγκεντρώνουν τα διάφορα σχέδια που παρέχονται από το C# κώδικα.
5.7 "CSGL12UsefulCode"
Ο κατάλογος περιλαμβάνει το όνομα "CSGL12UsefulCode" αρχεία C# που μπορεί να είναι χρήσιμη σε ανθρώπους που θέλουν να κάνουν συναλλαγές με την κοινοτοπία OpenGL. Ο κατάλογος περιλαμβάνει επίσης την DLL αρχεία "CSGL12DLL.dll" και "CSGL12Control.dll" για λόγους ευκολίας.
Ο κώδικας καθορίζει σε αυτόν τον κατάλογο class διαφόρων τύπων, όπως Color4f, Vector3f, Matrix4x4f, Triangle, Mesh, ImageData, Texture, ShaderProgram, κλπ. Ο κώδικας είναι αρκετά αποτελεσματική, αλλά ο κώδικας είναι μόνο στόχο να εμπνεύσει τους ανθρώπους να αναπτύξουν τις δικές τους εφαρμογές.
6. CSGL12 αρχεία
Η "CSGL12" συλλογή C# υπολογιστή αρχεία κώδικα περιλαμβάνει τα αρχεία που φαίνεται στο ακόλουθο διάγραμμα:

Η "CSGL12" συλλογή C# υπολογιστή αρχεία κώδικα περιλαμβάνει τα αρχεία που εμφανίζονται σε αυτό το διάγραμμα.
"CSGL12" Το λογισμικό περιλαμβάνει επίσης σχέδια για τη δημιουργία των δύο DLL αρχεία ("CSGL12DLL.dll" και "CSGL12Control.dll") παρουσιάζεται στο διάγραμμα. Τα δύο αυτά αρχεία DLL μπορούν να δημιουργηθούν, ώστε να είναι πιο βολικό να δημιουργήσουν προγράμματα που χρησιμοποιούν OpenGL, αλλά είναι επίσης δυνατή η δημιουργία προγραμμάτων που χρησιμοποιούν μόνο το C# αρχεία άμεσα.
7. "namespace CSGL12" και "class" είδη
Η "CSGL12" συλλογή C# υπολογιστή αρχεία κώδικα ορίζει "namespace CSGL12" και τα είδη "class" φαίνεται στο ακόλουθο διάγραμμα:

Η "CSGL12" συλλογή C# κώδικα υπολογιστή αρχεία "namespace CSGL12" καθορίζει και την "class" τύπους φαίνεται σε αυτό το διάγραμμα.
Ένα πρόγραμμα που κάνει OpenGL κατάρτιση μπορεί να δημιουργηθεί με τη χρήση μόνο "class GL" (χρησιμοποιώντας το C# αρχείο GL.cs άμεσα, ή με τη χρήση του DLL αρχείο CSGL12DLL.dll που περιέχει επίσης "class GL"). Ωστόσο, η χρήση "class CSGL12Control" (με τη χρήση του C# αρχείο CSGL12Control.cs άμεσα, ή με τη χρήση του DLL αρχείο CSGL12Control.dll που περιέχει επίσης "class CSGL12Control") καθιστά την προσθήκη OpenGL κατάρτιση σε Form (System.Windows.Forms.Form) εύκολη και βολική.
Η C# τάξεις Color4f, CSGL12Support, ImageData, ..., στο κάτω μέρος του διαγράμματος προσφέρονται μόνο για την ευκολία. Αυτές οι κατηγορίες που να διευκολύνει τη δημιουργία προγραμμάτων που να χρησιμοποιούν OpenGL. Ωστόσο, ίσως να έχουν ήδη τάξεις που εκτελεί τις εργασίες αυτές τις κατηγορίες, ή μπορείτε να επιλέξετε να δημιουργήσετε παρόμοιες κατηγορίες που εκτελεί τις εργασίες με διαφορετικό ή περισσότερο αποτελεσματικά. Αυτές οι κατηγορίες που προσφέρονται ως παραδείγματα ένα συγκεκριμένο κώδικα σχεδιασμού και υλοποίησης.
8. Η χρήση ενός ενιαίου "CSGL12Control" σε System.Windows.Forms.Form
8.1 Πρόγραμμα δομή
Το διάγραμμα που ακολουθεί δείχνει τον τρόπο με τον οποίο ένα πρόγραμμα με System.Windows.Forms.Form μπορούν να χρησιμοποιούν μια ενιαία "CSGL12Control" να κάνει με την κατάρτιση OpenGL. Το διάγραμμα δείχνει τα διάφορα CSGL12 αρχεία χρησιμοποιούνται για την κατασκευή του προγράμματος.

Ένα πρόγραμμα με τη χρήση ενός μόνο "CSGL12Control" σε System.Windows.Forms.Form
8.2 Χρησιμοποιώντας Microsoft Visual C# να δημιουργήσει το πρόγραμμα
(1) Start Microsoft Visual C#.
(2) Στο μενού, επιλέξτε "File" -> "New Project...".
(3) Στην "New Project" διαλόγου που εμφανίζεται, επιλέξτε "Windows Forms Application", και να επιλέξετε ένα όνομα για το πρόγραμμα και πατήστε "OK".
Αμέσως (4) αποθηκεύσετε το "Solution" επιλέγοντας "File" -> "Save All". Ένα πλαίσιο διαλόγου με τίτλο "Save Project" θα εμφανίζονται, δίνοντάς σας τη δυνατότητα να ορίσετε το όνομα του σχεδίου, τον κατάλογο του θέση, και η "λύση" για το όνομα του έργου. Θυμηθείτε θέση του καταλόγου, έτσι ώστε να είναι έτοιμοι για την επόμενη εντολή. "Save" Πατήστε το κουμπί για να αποθηκεύσετε το έργο.
(5) Αντιγράψτε όλα τα αρχεία από τον κατάλογο "CSGL12UsefulCode" στην "CSGL12" λογισμικού στον κατάλογο που περιέχει τον πηγαίο κώδικα των αρχείων του νέου σχεδίου (δηλαδή, κατάλογο που περιέχει τα αρχεία "Form1.cs", "Form1.Designer.cs", "Program.cs", κτλ), έτσι ώστε τα αρχεία "CSGL12DLL.dll", "CSGL12Control.dll", "Color4f.cs" , "CSGL12Support.cs", κλπ, είναι παράλληλα με το νέο σχέδιο αρχείων "Form1.cs", κλπ.
(6) Σε Microsoft Visual C#, προσθέστε το "CSGL12" C# αρχεία για το έργο. Στο μενού, επιλέξτε "Project" -> "Add Existing Item...", "Add Existing Item" και στο πλαίσιο διαλόγου, επιλέξτε όλα τα αρχεία από C# την CSGL12 λογισμικού ("Color4f.cs", "CSGL12Support.cs", "ImageData.cs", ...).
(7) Σε Microsoft Visual C#, προστίθενται οι "αναφορές" στην DLL αρχεία "CSGL12DLL.dll" και "CSGL12Control.dll". Στο μενού, επιλέξτε "Project" -> "Add Reference...", "Add Reference" και στο πλαίσιο διαλόγου, επιλέξτε την καρτέλα "Browse", και επιλέξτε τα αρχεία "CSGL12DLL.dll" και από το έργο "CSGL12Control.dll" πηγή αρχείο κατάλογο και πατήστε "OK".
(8) Σε Microsoft Visual C#, προσθέστε το "CSGL12Control" στην "Toolbox". Στο μενού, επιλέξτε "Tools" -> "Choose Toolbox Items...". Στην "Choose Toolbox Items" διαλόγου που εμφανίζεται, πατήστε το κουμπί "Browse...", και να προχωρήσει το έργο κατάλογο με τον πηγαίο κώδικα των αρχείων, και επιλέξτε "CSGL12Control.dll". Πατήστε το κουμπί "OK".
(9) Σε Microsoft Visual C#, δείτε το "Toolbox". Στο μενού, επιλέξτε "View" -> "Toolbox". Στην "Toolbox", πηγαίνετε στο τμήμα που ονομάζεται "General", και να εντοπίσουν το στοιχείο που ονομάζεται "CSGL12Control". Χρησιμοποιώντας το δρομέα, κάντε κλικ στο στοιχείο που ονομάζεται "CSGL12Control" και σύρετέ το στη "Form" στο "Design" άποψη.
(10) Σε Microsoft Visual C#, στην "Form" "Design" άποψη, μετακινήστε το "CSGL12Control" παράδειγμα για την "Form" και προσαρμόσει το πλάτος και το ύψος. Στην "Properties" πάνελ, που η αξία "Anchor" να συμπεριλάβει "Top, Bottom, Left, Right" αν θέλετε να αλλάξετε τον έλεγχο του μεγέθους, σύμφωνα με τις αλλαγές στο πρόγραμμα μέγεθος.
(11) Σε Microsoft Visual C#, αλλάξτε τις ιδιότητες του έργου, έτσι ώστε να μπορούν να χρησιμοποιούν "unsafe" κώδικα. Στο μενού, επιλέξτε "Project" -> "[project] Properties...". Επιλέξτε το πλαίσιο διαλόγου που εμφανίζεται, επιλέξτε την καρτέλα που ονομάζεται "Build" και ελέγξτε το πλαίσιο ελέγχου που ονομάζεται "[X] Allow unsafe code". Κλείστε το σχέδιο διαλόγου ιδιοτήτων.
(12) Σε Microsoft Visual C#, προσθέστε ένα νέο αρχείο C# με το έργο. Στο μενού, επιλέξτε "Project" -> "Add New Item...". Στο παράθυρο διαλόγου που ονομάζεται "Add New Item", επιλέξτε το πρότυπο που ονομάζεται "Class", και να επιλέξετε ένα όνομα για τη νέα κατηγορία του είδους, όπως "CSGL12MyHandler.cs" και, στη συνέχεια, πατήστε το κουμπί "Add". Δείτε το παράδειγμα σχεδίου που ονομάζεται "CSGL12Example1", στο αρχείο με το όνομα "CSGL12Example1Handler.cs", ως παράδειγμα του πώς ο κώδικας "CSGL12MyHandler.cs" θα πρέπει να γίνεται γραπτώς.
(13) Σε Microsoft Visual C#, στην "Solution Explorer", κάντε κλικ για "Form1". Στο μενού, επιλέξτε "View" -> "Code" (ή πατήστε F7, ή κάντε δεξί κλικ στον "Form1" και επιλέγουν "View Code". Ο κώδικας του φακέλου "Form1.cs" θα εμφανιστεί στην εκδότρια. Τροποποιήστε τον κώδικα στο αρχείο "Form1.cs" να είναι παρόμοιο με τον κώδικα στο αρχείο "CSGL12Example1Form.cs" στο έργο "CSGL12Example1" περιλαμβάνονται στο "CSGL12" λογισμικού. Ειδικότερα, να δημιουργήσει μια μεταβλητή για χάρη της εκδήλωσης σας εξυπηρέτησης κατηγορία τους (π.χ., "CSGL12MyHandler") και, στη συνέχεια, προσθέστε τις μεθόδους της κατηγορίας αυτής, όπως π.χ. για την περίπτωση που χειρίζονται τις διάφορες εκδηλώσεις με πρωτοβουλία του "CSGL12Control" στην "Form".
(14) Σε Microsoft Visual C#, την κατάρτιση και εκτέλεση του προγράμματος. Εάν επιθυμείτε να μοιραστείτε το πρόγραμμα, θα πρέπει να περιλαμβάνει τα δύο αρχεία DLL ("CSGL12DLL.dll" και "CSGL12Control.dll") με το εκτελέσιμο αρχείο (*.exe).
Εάν είστε εμπειρογνώμονας C# προγραμματιστής, τότε μπορείτε να αποφεύγεται η ανάγκη για τη διανομή των αρχείων DLL ("CSGL12DLL.dll" και "CSGL12Control.dll") με το εκτελέσιμο αρχείο (*.exe).
Αντιγράψτε τα αρχεία "GL.cs", "CSGL12Control.cs", και "PrecisionTime.cs" από τα έργα που κατονομάζονται "CSGL12DLL" και "CSGL12Control" στην "CSGL12" λογισμικού στην πηγή κατάλογο του τρέχοντος έργου σας. Προσθέστε τα αρχεία "GL.cs", "CSGL12Control.cs", και "PrecisionTime.cs" για το έργο σας, ώστε να καταρτίζονται σε απευθείας στο πρόγραμμα. Να μην έχουν αναφορές σε "CSGL12DLL.dll" και "CSGL12Control.dll" στο έργο.
Κοίτα το "CSGL12Example1" έργου στο "CSGL12" λογισμικό, και να εξετάσουμε τον κώδικα μέσα στα αρχεία ονομάζεται "CSGL12Example1Form.cs" και "CSGL12Example1Form.Designer.cs" να δούμε τι κώδικα πρέπει να δημιουργήσετε και να προετοιμάσει μια περίοδο λειτουργίας του "CSGL12Control" σε "Form". Προσθήκη παρόμοιο κωδικό σε "Form1.cs" και "Form1.Designer.cs" το χέρι για να δημιουργήσετε και να προετοιμάσει μια περίοδο λειτουργίας του "CSGL12Control" σας "Form".
Η διαδικασία αυτή είναι πολύ ενοχλητική, και απαιτεί εμπειρία και μεγάλη προσοχή, αλλά το αντίστοιχο εκτελέσιμο αρχείο (*.exe) δεν θα απαιτήσει "CSGL12DLL.dll" ή "CSGL12Control.dll". Είναι πολύ ωραίο για να είναι σε θέση να μοιραστεί το λογισμικό σας με τη μορφή ενός ενιαίου εκτελέσιμο αρχείο (*.exe) χωρίς να απαιτούν άλλα αρχεία.
8.3 Adding "αναφορές" σε CSGL12DLL.dll και CSGL12Control.dll
Το τμήμα αυτό περιλαμβάνει εικόνες από τη χρήση Microsoft Visual C# 2008 Express Edition να προσθέσετε "αναφορές" στο DLL αρχεία CSGL12DLL.dll και CSGL12Control.dll με το έργο.
Στο μενού, επιλέξτε "Project" -> "Add Reference...". Ή, κάντε δεξί κλικ "References" το τεμάχιο του "Solution Explorer" πάνελ και επιλέξτε "Add Reference...", όπως φαίνεται στην παρακάτω εικόνα.

Πλαίσιο μενού για την "References" στοιχείο στο "Solution Explorer", όπου φαίνεται η επιλογή "Add Reference..."
Μετά την επιλογή των "Add Reference..." επιλογή, ένα παράθυρο διαλόγου θα εμφανιστεί το όνομα "Add Reference". Σε αυτό το πλαίσιο διαλόγου, επιλέξτε την καρτέλα "Browse", και επιλέξτε το DLL αρχεία "CSGL12DLL.dll" και "CSGL12Control.dll", όπως φαίνεται στην παρακάτω εικόνα, και στη συνέχεια πατήστε το κουμπί με ετικέτα "OK".

Η "Browse" καρτέλα του "Add Reference" διαλόγου, με την DLL αρχεία "CSGL12DLL.dll" και "CSGL12Control.dll" δύο επιλεγμένους
Μετά το πάτημα του κουμπιού labeled "OK", η "Add Reference" διαλόγου θα εκλείψουν, και τα DLL αρχεία "CSGL12DLL.dll" και "CSGL12Control.dll" θα εμφανιστεί στην "References" υποκατάστημα στην "Solution Explorer", όπως φαίνεται στο ακόλουθο διάγραμμα.

Η DLL αρχεία "CSGL12DLL.dll" και "CSGL12Control.dll" στην "References" υποκατάστημα στην "Solution Explorer"
8.4 Η προσθήκη CSGL12Control στην Toolbox στο Microsoft Visual C# 2008 Express Edition
Το τμήμα αυτό περιλαμβάνει εικόνες από τη χρήση Microsoft Visual C# 2008 Express Edition να προσθέσετε CSGL12Control στην "Toolbox" έτσι ώστε ένα άτομο μπορεί εύκολα να προσθέσετε τις εμφανίσεις του CSGL12Control σε "Form" στην "Designer" (Shift+F7 από προεπιλογή).
Στο μενού, επιλέξτε "View" -> "Toolbox". Στην "Toolbox", πηγαίνετε στο τμήμα που ονομάζεται "General", όπως φαίνεται στην παρακάτω εικόνα.

Η "General" τμήμα της "Toolbox"
Κάντε δεξί κλικ οπουδήποτε εντός της "Toolbox". Κάντε την επιλογή "Choose Items..." στο πλαίσιο μενού που εμφανίζεται, όπως φαίνεται στην παρακάτω εικόνα.

Η επιλογή "Choose Items..." στο πλαίσιο μενού για την "Toolbox"
Εναλλακτικά, στο μενού, επιλέξτε επιλέξτε "Tools" -> "Choose Toolbox Items...".
Η "Choose Toolbox Items" διαλόγου θα πρέπει να εμφανίζονται, όπως φαίνεται στην παρακάτω εικόνα.

Η "Choose Toolbox Items" διαλόγου
Στην "Choose Toolbox Items" διαλόγου, πατήστε το κουμπί "Browse". Στην "Open" διαλόγου που εμφανίζεται, επιλέξτε το DLL αρχείο "CSGL12Control.dll", όπως φαίνεται στην παρακάτω εικόνα, και στη συνέχεια πατήστε το κουμπί "OK".

Η "Open" διαλόγου, με την DLL αρχείο επιλέγονται "CSGL12Control.dll"
Η "CSGL12Control" σημείο θα πρέπει να εμφανίζονται τώρα στο "Choose Toolbox Items" διαλόγου, όπως δείχνει η παρακάτω εικόνα. Πατήστε το κουμπί "OK".

Η "CSGL12Control" διάταξη εμφανίζεται τώρα στο παράθυρο διαλόγου "Choose Toolbox Items"
Η "CSGL12Control" σημείο θα πρέπει να εμφανίζονται τώρα στο "Toolbox", όπως φαίνεται στην παρακάτω εικόνα.

Η "CSGL12Control" διάταξη εμφανίζεται τώρα στο "Toolbox"
8.5 Η προσθήκη CSGL12Control σε "Form" με τη χρήση του "Toolbox"
Το τμήμα αυτό περιλαμβάνει εικόνες από τη χρήση Microsoft Visual C# 2008 Express Edition να προσθέσετε ένα παράδειγμα της CSGL12Control σε "Form" με τη χρήση του "Toolbox".
Στο μενού, επιλέξτε "View" -> "Designer" (Shift+F7 από προεπιλογή). Ή, διπλό κλικ σε ένα αρχείο "Form*.cs" στην "Solution Explorer". Ή δεξί κλικ σε ένα αρχείο "Form*.cs" στην "Solution Explorer" και επιλέξτε "View Designer". Χρησιμοποιώντας μία από τις τρεις αυτές μεθόδους, η "Designer" παράθυρο για "Form" θα πρέπει να εμφανιστεί.
Στο μενού, επιλέξτε "View" -> "Toolbox". Στην "Toolbox", πηγαίνετε στο τμήμα που ονομάζεται "General". Ένα αντικείμενο που ονομάζεται "CSGL12Control" πρέπει να εμφανιστεί εκεί, όπως φαίνεται στην παρακάτω εικόνα.

Η "CSGL12Control" θα έπρεπε να είναι ήδη στο "Toolbox"
Χρησιμοποιώντας το δρομέα, κάντε κλικ στο στοιχείο που ονομάζεται "CSGL12Control" και σύρετέ το στη "Form" στο "Designer". Ένα παράδειγμα της "CSGL12Control" θα πρέπει να εμφανιστεί στη "Form" όπως φαίνεται στην παρακάτω εικόνα.

Ένα παράδειγμα της "CSGL12Control" σε "Form" στην "Designer"
Κατά την άποψη "Form" "Designer", μετακινήστε το παράδειγμα της "CSGL12Control" για την "Form" και προσαρμόσει το πλάτος και το ύψος.
Κάντε κλικ στο παράδειγμα της "CSGL12Control" για την "Form" να επιλέξετε. Στη συνέχεια, στα "Properties" ομάδα, που η αξία "Anchor" να συμπεριλάβει "Top, Bottom, Left, Right", έτσι ώστε το μέγεθος του "CSGL12Control" θα αλλάξει ανάλογα με τις αλλαγές στο πρόγραμμα μέγεθος. Ίσως επίσης να θέλετε να αλλάξετε το όνομα της μεταβλητής (δηλαδή, η τιμή για την "(Name)") για το παράδειγμα της "CSGL12Control" από την αυτόματη προεπιλογή (π.χ., "csgL12Control") σε κάτι κατάλληλο για σας κωδικό (π.χ., "mCSGL12Control" ή "mCSGL12Control1", κτλ).
Η ακόλουθη εικόνα δείχνει την "Form" "Designer" σκοπό και το "Properties" πάνελ.

Ένα παράδειγμα της CSGL12Control σε Form στην Designer, και το πάνελ "Properties
9. Χρησιμοποιώντας δύο εμφανίσεις της "CSGL12Control" σε System.Windows.Forms.Form
Το διάγραμμα που ακολουθεί δείχνει ένα παράδειγμα για το πώς δύο εμφανίσεις της "CSGL12Control" μπορεί να προστεθεί σε μια System.Windows.Forms.Form να κάνει με την κατάρτιση OpenGL σε ένα πρόγραμμα.

Ένα πρόγραμμα με τη χρήση δύο εμφανίσεις του "CSGL12Control" σε System.Windows.Forms.Form
Ακολουθήστε τις οδηγίες στην προηγούμενη ενότητα για να προσθέσετε ένα μόνο παράδειγμα των "CSGL12Control" σε "Form". Στη συνέχεια, απλώς σύρετε ένα δεύτερο παράδειγμα της "CSGL12Control" από την "Toolbox" στην "Form" να προσθέσω ένα δεύτερο "CSGL12Control".
Κάθε κλίμακα της "CSGL12Control" θα έχει το δικό της όνομα μεταβλητής. Κάθε "CSGL12Control" παράδειγμα του μπορεί να έχει το δικό της πρόγραμμα χειρισμού συνδέονται κατηγορίας αυτής, ή μπορεί να χρησιμοποιεί ξεχωριστές περιπτώσεις από ένα μόνο είδος εξυπηρέτησης κατηγορίας.
Μελέτη έργου "CSGL12Example2" το παράδειγμα για να μάθετε πώς "CSGL12Control" δύο περιπτώσεις που μπορούν να έχουν τα γεγονότα που αποστέλλονται σε δύο διαφορετικές περιπτώσεις προσαρμοσμένο πρόγραμμα χειρισμού με διακριτές κατηγορίες OpenGL κατάρτιση λειτουργίες.
Το παράδειγμα "CSGL12Example2" πρόγραμμα έχει κάθε εμφάνιση του "CSGL12Control" σε "SplitContainer" "Control", απλά ένας τρόπος για να αποδείξει σε ποια περίπτωση μπορεί να "CSGL12Control" χρησιμοποιούνται. Ωστόσο, οι εμφανίσεις του "CSGL12Control" μπορούν, αντί να τεθεί άμεσα στην "Form".
10. Παράδειγμα C# κώδικα για "Form" με μια εμφάνιση του CSGL12Control
Το παρακάτω είναι το πλήρες C# κώδικα που περιέχεται στο φάκελο "CSGL12Example1Form.cs", η οποία αποτελεί μέρος του προγράμματος "CSGL12Example1" παράδειγμα.
Ο κωδικός αυτός παρουσιάζεται εδώ ως ένα απλό παράδειγμα για το πώς μια εμφάνιση του CSGL12Control μπορεί να δημιουργηθεί και να χρησιμοποιηθεί από έναν "Form".
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CSGL12;
namespace CSGL12Example1
{
public partial class CSGL12Example1Form : Form
{
public CSGL12Example1Handler mCSGL12Example1Handler;
private System.Windows.Forms.Timer mTimer;
public CSGL12Example1Form()
{
InitializeComponent();
mCSGL12Example1Handler = new CSGL12Example1Handler();
mCSGL12Control1.OpenGLStarted += new CSGL12Control.DelegateOpenGLStarted( mCSGL12Example1Handler.OpenGLStarted );
mCSGL12Control1.KeyDown += new KeyEventHandler(mCSGL12Example1Handler.KeyDown);
mCSGL12Control1.KeyUp += new KeyEventHandler(mCSGL12Example1Handler.KeyUp);
mCSGL12Control1.MouseDown += new MouseEventHandler(mCSGL12Example1Handler.MouseDown);
mCSGL12Control1.MouseUp += new MouseEventHandler(mCSGL12Example1Handler.MouseUp);
mCSGL12Control1.MouseMove += new MouseEventHandler(mCSGL12Example1Handler.MouseMove);
mCSGL12Control1.MouseWheel += new MouseEventHandler(mCSGL12Example1Handler.MouseWheel);
mCSGL12Control1.Paint += new PaintEventHandler(mCSGL12Example1Handler.Paint);
// Use a timer to trigger drawing at the desired frame rate.
//
// Windows timers are not very precise. Also, if we call wglSwapIntervalEXT(1)
// and we specify in the global OpenGL control panel that OpenGL drawing
// should wait for vertical sync (vsync) of the display, then the frame
// rate would be limited to 60 frames/second or 75 frames/second, for example,
// and our program would have to draw each frame in less than 1/60 seconds
// (16.6 milliseconds) or less than 1/75 seconds (13.3 milliseconds),
// otherwise the drawn frame would be forced to wait one or more full
// frame durations before appearing on the screen. Therefore, it would
// be best to have the timer interval somewhat shorter than a full frame
// interval, to ensure that even if there is a slight delay in responding
// to the timer event we will have at least one timer event per display
// frame interval.
//
// Theoretically, a timer interval of 16 milliseconds would be short enough
// to sustain a frame rate of 62.5 frames/second, and would seemingly have
// a corresponding rate sufficient to sustain 60 frames/second in the case
// of a vertical-sync limited drawing rate for OpenGL. However, in simple
// experiments on a system with a 2.5 GHz Core 2 Duo CPU with an nVidia
// GeForce 8600M GS with 512 MB, I found that a 16-millisecond Windows
// timer interval results in a 33 frames/second OpenGL frame rate (where
// vertical-sync locking is enabled, and the display refresh rate is
// 60 frames/second). So, despite theoretically being slightly more rapid
// than necessary to maintain a 60 frames/second drawing rate, a Windows
// timer with an interval of 16-milliseconds isn't quite rapid enough to
// ensure drawing soon enough to be ready for each display refresh; hence
// the rather significantly lower than desired frame rate of 33 frames/second.
//
// Here are the OpenGL drawing frame rates (limited to 60 Hz vertical sync)
// I observed on a particular computer for particular Windows timer intervals:
//
// 18-millisecond timer interval --> 31 frames/second OpenGL drawing
// 17-millisecond timer interval --> 31 frames/second OpenGL drawing
// 16-millisecond timer interval --> 33 frames/second OpenGL drawing
// 15-millisecond timer interval --> 60 frames/second OpenGL drawing
// 14-millisecond timer interval --> 60 frames/second OpenGL drawing
//
// So, it seems like choosing a Windows timer interval only a couple of
// milliseconds shorter than the theoretical 16.6 millisecond interval
// corresponding to a 60 frames/second rate is enough for this program to
// submit each new frame in time for the next display refresh.
//
// However, computers with slower CPUs or slower GPUs might benefit from
// an even shorter Windows timer interval, to ensure that drawing will
// happen soon enough for the next display refresh.
//
// Some displays are set to refresh at 75 frames/second, which corresponds
// to a frame duration of 13.3 milliseconds. We will aim for this drawing
// rate, and we will subtract a few milliseconds from the Windows timer
// interval to ensure that we receive and process the timer event soon
// enough to submit the frame in time for the next display refresh.
// Meanwhile, we will choose the Windows timer interval such that it isn't
// absurdly short, lest future faster computers actually manage to draw
// at that wasteful rate.
//
// Choosing a Windows timer interval of 10 milliseconds seems like it will
// reliably be able to trigger OpenGL frame drawing in time to keep up with
// a 75 frames/second display (13.3 millisecond frame duration), while
// only causing the OpenGL drawing to happen at a maximum rate of
// 100 frames/second in the unlikely scenario of a very fast computer
// actually being able to draw frames at that rate (given the overhead of
// C#, etc).
mTimer = new System.Windows.Forms.Timer();
mTimer.Interval = 10; // 10-millisecond interval
mTimer.Tick += new EventHandler(PrivateTimerTickEventHandler);
mTimer.Start();
// Set focus to a control so that it can immediately accept input
mCSGL12Control1.Focus();
// Also, whenever the form becomes activated, set focus to the main
// control on the form. The following sets up an event handler for
// that purpose.
this.Activated += new EventHandler(PrivateActivatedEventHandler);
// We want to preview dialog keys (most importantly, the cursor
// keys: up, down, right, left) so we can forward such events to
// the appropriate child control.
this.KeyPreview = true;
}
void PrivateTimerTickEventHandler(object sender, EventArgs e)
{
if (false == DesignMode)
{
mCSGL12Control1.Invalidate();
}
}
private void PrivateActivatedEventHandler(object sender, EventArgs e)
{
// When this form becomes activated, after some time of not
// being active, set input focus to a GL control on the form.
if (false == mCSGL12Control1.Focused)
{
mCSGL12Control1.Focus();
}
}
// Cursor keys (up,down,left,right) need to be specially captured
// and forwarded to the control.
// CAUTION: The KeyPreview property of this Form must be set to 'true'
// for the following method to be called.
protected override bool ProcessDialogKey(Keys keyData)
{
if
(
(keyData == Keys.Up)
|| (keyData == Keys.Down)
|| (keyData == Keys.Left)
|| (keyData == Keys.Right)
)
{
KeyEventArgs e = new KeyEventArgs(keyData);
if (true == mCSGL12Control1.Focused)
{
mCSGL12Example1Handler.KeyDown(mCSGL12Control1, e);
}
else
{
// The CSGL12Control does not have focus.
// Let's simply drop the dialog key event. The user
// may have focus on a different control.
}
return (true);
}
return base.ProcessDialogKey(keyData);
}
}
}
Σημειώστε ότι η μεταβλητή μέλος "mCSGL12Example1Handler" κηρύσσεται να αναφερθώ σε ένα παράδειγμα ενός class ονομάζεται "CSGL12Example1Handler". Η κατηγορία αυτή θα περιγραφεί σε επόμενη ενότητα του παρόντος εγγράφου. Σημειώστε ότι ο κατασκευαστής για "CSGL12Example1Form" προσθέτει τις μεθόδους της χάριν της "CSGL12Example1Handler" στην "multicast delegates" που συνδέονται με τα διάφορα γεγονότα που δημιουργούνται από μια εμφάνιση του "CSGL12Control". Αυτό σημαίνει ότι όταν το παράδειγμα της "CSGL12Control" δημιουργεί διάφορα γεγονότα, τα γεγονότα αυτά θα προκαλέσουν διάφορες μέθοδοι για την εμφάνιση του "CSGL12Example1Handler" (δηλαδή, "mCSGL12Example1Handler") να αποτελούν αντικείμενο επίκλησης.
Σημειώστε ότι η μεταβλητή μέλος "mTimer" κηρύσσεται να αναφερθώ σε ένα παράδειγμα ενός class ονομάζεται "System.Windows.Forms.Timer". Το αντικείμενο αυτό χρησιμοποιείται για να κινήσει μια λειτουργία που ονομάζεται "PrivateTimerTickEventHandler" κάθε 10 χιλιοστά του δευτερολέπτου. Η λειτουργία που ονομάζεται "PrivateTimerTickEventHandler" ζητεί μια μέθοδος η χάρη του "CSGL12Control" (δηλαδή, "mCSGL12Control1") ότι οι αιτίες που "Control" να καταρτίσει η ίδια. Αυτό είναι ένα παράδειγμα του πώς μπορεί "CSGL12Control" κινούμενο σε ποσοστό κατά προσέγγιση.
Μόνο ένα μέρος του ορισμού της "class CSGL12Example1Form" εμφανίζεται στο C# αρχείο με το όνομα "CSGL12Example1Form.cs". Ένα άλλο μέρος του ορισμού της "class CSGL12Example1Form" φαίνεται C# σε ένα αρχείο με το όνομα "CSGL12Example1Form.Designer.cs". Αν και τα αρχεία που ταιριάζουν με το όνομα του τρόπου διεξαγωγής "*.Designer.cs" είναι γενικά δημιουργούνται και τροποποιούνται μόνο από τις γραφικές "Form Designer" παράθυρο του editor C#, είναι επίσης δυνατό να δημιουργηθούν και να τα τροποποιούν C# αρχεία χρησιμοποιώντας ένα πρόγραμμα επεξεργασίας κειμένου.
Το παρακάτω είναι το πλήρες C# κώδικα που περιέχεται στο φάκελο "CSGL12Example1Form.Designer.cs", η οποία αποτελεί μέρος του προγράμματος "CSGL12Example1" παράδειγμα.
namespace CSGL12Example1
{
partial class CSGL12Example1Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.mCSGL12Control1 = new CSGL12.CSGL12Control();
this.SuspendLayout();
//
// mCSGL12Control1
//
this.mCSGL12Control1.Anchor = ((System.Windows.Forms.AnchorStyles)
((((System.Windows.Forms.AnchorStyles.Top
| System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.mCSGL12Control1.BackColor = System.Drawing.SystemColors.Control;
this.mCSGL12Control1.Location = new System.Drawing.Point(12, 12);
this.mCSGL12Control1.Name = "mCSGL12Control1";
this.mCSGL12Control1.Size = new System.Drawing.Size(640, 480);
this.mCSGL12Control1.TabIndex = 0;
this.mCSGL12Control1.Text = "CSGL12Control1";
//
// CSGL12Example1Form
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(664, 504);
this.Controls.Add(this.mCSGL12Control1);
this.Name = "CSGL12Example1Form";
this.Text = "CSGL12Example1";
this.ResumeLayout(false);
}
#endregion
private CSGL12.CSGL12Control mCSGL12Control1;
}
}
Σημειώστε ότι αυτό C# κώδικας περιέχει τη δήλωση της μεταβλητής "mCSGL12Control1", το οποίο αναφέρεται σε μια περίοδο λειτουργίας του "class CSGL12.CSGL12Control" (δηλαδή, "class CSGL12Control" στο "namespace CSGL12"). Αυτό το παράδειγμα έχει δημιουργηθεί και να ρυθμιστεί σε λειτουργία "InitializeComponent".
11. Χειρισμός γεγονότα που επικαλείται ένα παράδειγμα της CSGL12Control
Το προηγούμενο κεφάλαιο κατέδειξε C# κώδικα για "Form" ότι περιείχε ένα μόνο παράδειγμα των "CSGL12Control". Ο κωδικός C# προσθήκη μεθόδους ενός "class" όπως ονομάζεται "CSGL12Example1Handler" περίπτωση που χειρίζονται για διάφορα γεγονότα που δημιουργούνται από το παράδειγμα της "CSGL12Control".
Εδώ υπάρχει μια λίστα με ενδιαφέροντα γεγονότα της "CSGL12Control", και το "delegate" είδη που συνδέονται με αυτά τα γεγονότα:
OpenGLStarted CSGL12Control.DelegateOpenGLStarted
KeyDown System.Windows.Forms.KeyEventHandler
KeyUp System.Windows.Forms.KeyEventHandler
MouseDown System.Windows.Forms.MouseEventHandler
MouseUp System.Windows.Forms.MouseEventHandler
MouseMove System.Windows.Forms.MouseEventHandler
MouseWheel System.Windows.Forms.MouseEventHandler
Paint System.Windows.Forms.PaintEventHandler
Μόνο το "OpenGLStarted" περίπτωση είναι ένα γεγονός για το συγκεκριμένο τύπο "CSGL12Control".
Όλα τα άλλα γεγονότα είναι πρότυπο System.Windows.Forms εκδηλώσεις, των οποίων η εκδήλωση που χειρίζονται πρέπει να έχει κάποιες παραμέτρους (που καθορίζονται σε κάθε Forms τεκμηρίωση).
Η "OpenGLStarted" και "Paint" γεγονότα είναι τα πιο σημαντικά γεγονότα για την OpenGL.
Η εκδήλωση γίνεται επίκληση "OpenGLStarted" πριν από την πρώτη κιόλας "Paint" εκδήλωση γίνεται επίκληση.
Ως εκ τούτου, η "OpenGLStarted" πρόγραμμα χειρισμού πρέπει να προστεθεί στον έλεγχο πριν από τον έλεγχο έχει την ευκαιρία να επιχειρήσει να ζωγραφίσει η ίδια, αλλιώς το εφάπαξ περίπτωση δεν θα γίνονται δεκτές.
Η εκδήλωση αυτή αποτελεί απλώς μια διευκόλυνση, και μπορεί να αγνοηθεί.
Ωστόσο, η προσθήκη ενός φορέα εξυπηρέτησης για την εκδήλωση αυτή καθιστά δυνατή για την handler κώδικα για να κάνει περίπου ένα χρόνο initialization ότι εξαρτάται από OpenGL είναι έτοιμο προς χρήση.
(OpenGL δεν μπορεί να χρησιμοποιηθεί μέχρι το παράθυρο υπάρχει και το παράθυρο είναι έτοιμος να εκτελέσει το πρώτο του χρώμα.
Έτσι, η περίπτωση των ανταλλακτικών "OpenGLStarted" τον προγραμματιστή από τον κίνδυνο του προσπαθούν να χρησιμοποιήσουν OpenGL πολύ σύντομα μετά το πρόγραμμα ξεκινάει.
) Είναι αρκετά εύκολο να προστεθεί σε μια λογική εξυπηρέτησης "Paint" να κάνουμε μια φορά initialization, χρησιμοποιώντας το OpenGL πλαίσιο της "CSGL12Control".
Η εκδήλωση "OpenGLStarted" προσφέρεται ως ευκολία.
Το παρακάτω είναι το πλήρες C# κώδικα που περιέχεται στο φάκελο "CSGL12Example1Handler.cs", η οποία αποτελεί μέρος του προγράμματος "CSGL12Example1" παράδειγμα.
Ο κωδικός αυτός παρουσιάζεται εδώ ως ένα απλό παράδειγμα για το πώς τα γεγονότα που δημιουργούνται από μια εμφάνιση του "CSGL12Control" μπορεί να γίνει για να επιστήσω την χρήση OpenGL.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
// This program requires "references" to the following:
//
// CSGL12DLL.dll (defines CSGL12.GL)
// CSGL12Control.dll (defines CSGL12.CSGL12Control)
using CSGL12;
namespace CSGL12Example1
{
public class CSGL12Example1Handler
{
private Mesh mMesh;
private ShaderProgram mShaderProgram1;
private ShaderProgram mShaderProgram2;
private ShaderProgram mShaderProgram3;
private ShaderProgram mShaderProgram4;
private ShaderProgram mShaderProgramSelected;
private Bitmap mHUDBitmap;
private Texture mHUDTexture;
private Font mFont1;
private Font mFont2;
private Font mFont3;
private Font mFont4;
private Pen mPen1;
private Brush mBrush1;
private double mViewDistance = 800.0;
private double mViewAzimuthDegrees = 0.0;
private double mViewAltitudeDegrees = 0.0;
private double mViewAzimuthDegreesVelocity = 9.0;
private double mViewAltitudeDegreesVelocity = 5.0;
private Point mMouseClientPositionStart;
private double mViewAzimuthDegreesStart = 0.0;
private double mViewAltitudeDegreesStart = 0.0;
public CSGL12Example1Handler()
{
mMesh = new Mesh();
mShaderProgram1 = new ShaderProgramMandelbrotSet();
mShaderProgram2 = new ShaderProgramWood();
mShaderProgram3 = new ShaderProgramBrick();
mShaderProgram4 = new ShaderProgramCartoon();
mShaderProgramSelected = mShaderProgram1;
mHUDBitmap = new Bitmap(512, 512, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
mHUDTexture = new Texture();
mFont1 = new Font("Verdana", 36.0f);
mFont2 = new Font("Verdana", 24.0f);
mFont3 = new Font("Courier New", 16.0f);
mFont4 = new Font("Courier New", 10.0f);
mPen1 = new Pen(Color.Red, 3.0f);
mBrush1 = new SolidBrush(Color.FromArgb(64, 128, 128, 140));
}
public void OpenGLStarted( CSGL12Control csgl12Control )
{
GL gl = csgl12Control.GetGL();
if (null == gl) { return; }
// Load shaders and set variables
if (true == gl.bglCreateProgramObjectARB)
{
if (null != mShaderProgram1)
{
mShaderProgram1.ShaderProgramCreate(gl);
}
if (null != mShaderProgram2)
{
mShaderProgram2.ShaderProgramCreate(gl);
}
if (null != mShaderProgram3)
{
mShaderProgram3.ShaderProgramCreate(gl);
}
if (null != mShaderProgram4)
{
mShaderProgram4.ShaderProgramCreate(gl);
}
}
// Create cube mesh
mMesh = new Mesh();
mMesh.BuildCube(400.0f);
// Create a texture
mHUDTexture.CreateTextureFromBitmap(gl, mHUDBitmap, true);
// To prevent "tearing" (irregular streaks) due to swapping buffers at
// arbitrary times relative to the vsync times, we indicate that we wish
// to wait for vsync before swapping buffers.
// This request applies when the display driver control panel -- in the
// OpenGL settings area -- is set to let the application decide whether or
// not to wait for vsync. Otherwise, the driver control panel overrides
// any request made here.
if (true == gl.bwglSwapIntervalEXT)
{
gl.wglSwapIntervalEXT(1);
}
}
public void Paint(object sender, PaintEventArgs e)
{
if (null == sender) { return; }
if (false == (sender is CSGL12Control)) { return; }
CSGL12Control csgl12Control = (sender as CSGL12Control);
GL gl = csgl12Control.GetGL();
int clientWidth = csgl12Control.ClientRectangle.Width;
int clientHeight = csgl12Control.ClientRectangle.Height;
if (clientWidth <= 0)
{
clientWidth = 1;
}
if (clientHeight <= 0)
{
clientHeight = 1;
}
// Set the viewport
gl.glViewport(0, 0, clientWidth, clientHeight);
// Clear the viewport
gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
// Basic drawing conditions
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glDepthFunc(GL.GL_LEQUAL);
gl.glEnable(GL.GL_CULL_FACE);
gl.glCullFace(GL.GL_BACK);
gl.glFrontFace(GL.GL_CCW);
// PROJECTION matrix, typically for perspective correction or orthographic projection
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
double aspectRatio = 1.0;
if (0 != clientHeight)
{
aspectRatio = ((double)(clientWidth) / (double)(clientHeight));
}
double verticalFieldOfViewAngle = 60.0;
gl.gluPerspective
(
verticalFieldOfViewAngle, // Field of view angle (Y angle; degrees)
aspectRatio, // width/height
0.1, // distance to near clipping plane
64000.0 // distance to far clipping plane
);
// MODELVIEW matrix, typically used to transform individual models
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
// Preserve current matrix for the active matrix stack (in this case the MODELVIEW matrix)
gl.glPushMatrix();
if (mViewAltitudeDegreesVelocity != 0.0)
{
if (mViewAltitudeDegrees > 70.0)
{
mViewAltitudeDegrees = 70.0;
mViewAltitudeDegreesVelocity *= -1.0;
}
else if (mViewAltitudeDegrees < -70.0)
{
mViewAltitudeDegrees = -70.0;
mViewAltitudeDegreesVelocity *= -1.0;
}
mViewAzimuthDegrees += mViewAzimuthDegreesVelocity * csgl12Control.GetPreviousFrameDurationSeconds();
mViewAltitudeDegrees += mViewAltitudeDegreesVelocity * csgl12Control.GetPreviousFrameDurationSeconds();
}
Vector3f from =
new Vector3f
(
(float)(mViewDistance * Math.Cos(mViewAltitudeDegrees * (Math.PI / 180.0)) * Math.Sin(mViewAzimuthDegrees * (Math.PI / 180.0))),
(float)(mViewDistance * Math.Sin(mViewAltitudeDegrees * (Math.PI / 180.0))),
(float)(mViewDistance * Math.Cos(mViewAltitudeDegrees * (Math.PI / 180.0)) * Math.Cos(mViewAzimuthDegrees * (Math.PI / 180.0)))
);
Vector3f to = new Vector3f(0.0f, 0.0f, 0.0f);
Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
Matrix4x4f camera = Matrix4x4f.LookAt(from, to, up);
float[] matrix = new float[16];
matrix[0] = camera.m11;
matrix[1] = camera.m21;
matrix[2] = camera.m31;
matrix[3] = 0.0f;
matrix[4] = camera.m12;
matrix[5] = camera.m22;
matrix[6] = camera.m32;
matrix[7] = 0.0f;
matrix[8] = camera.m13;
matrix[9] = camera.m23;
matrix[10] = camera.m33;
matrix[11] = 0.0f;
matrix[12] = camera.m14;
matrix[13] = camera.m24;
matrix[14] = camera.m34;
matrix[15] = 1.0f;
gl.glMultMatrixf(matrix);
if (mShaderProgramSelected != null)
{
mShaderProgramSelected.DemonstrateModificationOfVariables(gl, csgl12Control.GetPreviousFrameStartTimeSeconds(), csgl12Control.GetPreviousFrameDurationSeconds());
mShaderProgramSelected.Select(gl);
}
// Draw model(s), using active texture or shader
mMesh.Draw(gl);
// If we used a shader, disable it now...
if (true == gl.bglUseProgramObjectARB)
{
ShaderProgram.ShaderProgram_Select(gl, 0);
}
// Restore the previously-preserved matrix for the active matrix stack (in this case the MODELVIEW matrix)
gl.glPopMatrix();
// Demonstrate drawing text to a GDI+ Bitmap and then copying to
// an OpenGL texture.
DemonstrateDrawingTextToAGDIBitmapAndCopyingToAnOpenGLTexture(csgl12Control, gl);
// Flush all the current rendering and flip the back buffer to the front.
gl.wglSwapBuffers(csgl12Control.GetHDC());
}
public void DemonstrateDrawingTextToAGDIBitmapAndCopyingToAnOpenGLTexture(CSGL12Control csgl12Control, GL gl)
{
bool updateOverlayImage = false;
// The following code only enables an update of the Bitmap
// and OpenGL texture every 64 frames, thus avoiding the
// slowdown of performing updates every single frame.
// HOWEVER, updating the Bitmap and OpenGL texture can be
// done EVERY frame with acceptable speed.
// Updates should be limited to once per frame, but the
// logic to trigger updates can be based on when the relevant
// text changes.
if ((csgl12Control.GetTotalFramesDrawn() % 64) == 0)
{
updateOverlayImage = true;
}
bool showOverlayImage = true;
if (true == updateOverlayImage)
{
using (Graphics g = Graphics.FromImage(mHUDBitmap))
{
g.Clear(Color.FromArgb(0, Color.White));
g.FillEllipse(mBrush1, new Rectangle(0, 0, 256, 256));
g.FillEllipse(mBrush1, new Rectangle(256, 256, 256, 256));
PointF center = new PointF(0.5f * (256.0f + 0.0f), 0.5f * (256.0f + 0.0f));
PointF displacement = new PointF();
double fraction = csgl12Control.GetTotalElapsedTimeSeconds() * 0.1;
displacement.X = 128.0f * (float)Math.Cos(2.0 * Math.PI * fraction);
displacement.Y = 128.0f * (float)Math.Sin(2.0 * Math.PI * fraction);
g.DrawLine(mPen1, center, new PointF(center.X + displacement.X, center.Y + displacement.Y));
PointF carat = new PointF(0.0f, 0.0f);
String text = "";
text = "C# OpenGL (CSGL)";
g.DrawString(text, mFont1, Brushes.Black, carat);
carat.Y += mFont1.GetHeight();
text = "Здравствуйте";
g.DrawString(text, mFont2, Brushes.Black, carat);
carat.Y += mFont2.GetHeight();
text = "γεια σου";
g.DrawString(text, mFont2, Brushes.Black, carat);
carat.Y += mFont2.GetHeight();
text = "مرحبا";
g.DrawString(text, mFont2, Brushes.Black, carat);
carat.Y += mFont2.GetHeight();
text = "שלום";
g.DrawString(text, mFont2, Brushes.Black, carat);
carat.Y += mFont2.GetHeight();
carat.Y += 64.0f;
text = "Shift + 0: Save BMP,PNG,JPG,GIF";
g.DrawString(text, mFont4, Brushes.Black, carat);
carat.Y += mFont4.GetHeight();
text = "1,2,3,4 : Switch shader program";
g.DrawString(text, mFont4, Brushes.Black, carat);
carat.Y += mFont4.GetHeight();
carat.Y += 12.0f;
text = "Text : GDI+ on 512*512 Bitmap.";
g.DrawString(text, mFont4, Brushes.Black, carat);
carat.Y += mFont4.GetHeight();
text = "Bitmap copied to OpenGL texture.";
g.DrawString(text, mFont4, Brushes.Black, carat);
carat.Y += mFont4.GetHeight();
text = "Texture update once per 64 frames,";
g.DrawString(text, mFont4, Brushes.Black, carat);
carat.Y += mFont4.GetHeight();
text = "but more often would be OK.";
g.DrawString(text, this.mFont4, Brushes.Black, carat);
carat.Y += this.mFont4.GetHeight();
carat.Y += 12.0f;
text = String.Format("Frame:{0}", csgl12Control.GetTotalFramesDrawn());
text += " ";
text += String.Format("Time:{0:f2}", csgl12Control.GetTotalElapsedTimeSeconds());
double previousFrameDurationSeconds =
csgl12Control.GetPreviousFrameDurationSeconds();
if (previousFrameDurationSeconds > 1.0e-10)
{
double framesPerSecondOverall =
1.0 / previousFrameDurationSeconds;
text += " ";
text += String.Format("FPS:{0:f2}", framesPerSecondOverall );
}
g.DrawString(text, mFont3, Brushes.Black, carat);
carat.Y += mFont3.GetHeight();
}
mHUDTexture.UpdateTextureWithBitmapData(gl, mHUDBitmap);
}
if (true == showOverlayImage)
{
CSGL12Support.SupportDrawTextureImageUnrotatedAndOrthographically
(
gl,
csgl12Control.ClientSize.Width,
csgl12Control.ClientSize.Height,
mHUDTexture,
0,
0, // i.e., 0 == draw TOP of image at TOP of viewport, Y-axis points DOWN
mHUDTexture.GetWidth(), // glControl.ClientSize.Width, // mHUDTexture.GetWidth(),
mHUDTexture.GetHeight() // glControl.ClientSize.Height // mHUDTexture.GetHeight()
);
}
}
public void KeyDown(object sender, KeyEventArgs e)
{
if (null == sender) { return; }
if (false == (sender is CSGL12Control)) { return; }
CSGL12Control csgl12Control = (sender as CSGL12Control);
GL gl = csgl12Control.GetGL();
if (e.KeyCode == Keys.A)
{
}
if (e.KeyCode == Keys.Z)
{
}
if (e.KeyCode == Keys.D1)
{
mShaderProgramSelected = mShaderProgram1;
}
if (e.KeyCode == Keys.D2)
{
mShaderProgramSelected = mShaderProgram2;
}
if (e.KeyCode == Keys.D3)
{
mShaderProgramSelected = mShaderProgram3;
}
if (e.KeyCode == Keys.D4)
{
mShaderProgramSelected = mShaderProgram4;
}
// NOTE: The only way for cursor key events (up,down,left,right)
// to make it to this function is for the main form to implement
// the following:
//
// protected override bool ProcessDialogKey ( Keys keyData )
//
// and explicitly invoke this KeyDown() method with the
// an appropriately formed KeyEventArgs instance.
if (e.KeyCode == Keys.Up)
{
mViewDistance -= 10.0;
}
if (e.KeyCode == Keys.Down)
{
mViewDistance += 10.0;
}
if (e.KeyCode == Keys.Left)
{
mViewAzimuthDegrees += 1.0;
}
if (e.KeyCode == Keys.Right)
{
mViewAzimuthDegrees -= 1.0;
}
// Save an image of the viewport (press Shift-0 (zero)). The following
// code writes out the viewport in the following image formats: BMP, PNG, GIF, JPG.
// If you only want a single format, comment out the other file write commands.
// BMP has no compression artifacts, but the file can be quite large.
// PNG looks good, and supports 8-bit transparancy (good for textures, etc).
// GIF looks bad unless you build the color table intelligently (there is a
// neural network color table builder for GIF, in C#/.NET, that you can
// find on the Internet; perhaps Paint.NET uses that code); but GIF files
// can be quite small, and supports animation.
// JPG looks good under most circumstances, and the file size can be quite small,
// but transparency is not supported.
// So, for pixel-perfect images, where file size is not important, BMP might be appropriate.
// For textures with transparency, PNG might be appropriate.
// For good-looking images, and small file size, and use in Web pages, JPG might be appropriate.
// For some purposes, with small file sizes, and use in Web pages, GIF might be appropriate.
if ((e.KeyCode == Keys.D0) && (e.Shift == true))
{
DateTime now = DateTime.Now;
String dateTimeString = String.Format("{0:d4}{1:d2}{2:d2}{3:d2}{4:d2}{5:d2}{6:d3}", now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, now.Millisecond);
String frameIndexString = String.Format("{0:d6}", csgl12Control.GetTotalFramesDrawn());
String fileNameWithoutExtension = "screen" + "_" + dateTimeString + "_" + frameIndexString;
CSGL12Support.SupportWriteViewportToImageFile(gl, fileNameWithoutExtension + ".bmp", System.Drawing.Imaging.ImageFormat.Bmp);
CSGL12Support.SupportWriteViewportToImageFile(gl, fileNameWithoutExtension + ".png", System.Drawing.Imaging.ImageFormat.Png);
CSGL12Support.SupportWriteViewportToImageFile(gl, fileNameWithoutExtension + ".gif", System.Drawing.Imaging.ImageFormat.Gif);
CSGL12Support.SupportWriteViewportToImageFile(gl, fileNameWithoutExtension + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
public void KeyUp(object sender, KeyEventArgs e)
{
}
public void MouseDown(object sender, MouseEventArgs e)
{
if (null == sender) { return; }
if (false == (sender is CSGL12Control)) { return; }
CSGL12Control csgl12Control = (sender as CSGL12Control);
mMouseClientPositionStart = csgl12Control.PointToClient(Cursor.Position);
mViewAzimuthDegreesStart = mViewAzimuthDegrees;
mViewAltitudeDegreesStart = mViewAltitudeDegrees;
if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
mViewAzimuthDegreesVelocity = 0.0;
mViewAltitudeDegreesVelocity = 0.0;
}
if ((e.Button & MouseButtons.Right) == MouseButtons.Right)
{
mViewAzimuthDegreesVelocity = 9.0;
mViewAltitudeDegreesVelocity = 5.0;
}
}
public void MouseUp(object sender, MouseEventArgs e)
{
if ((e.Button & MouseButtons.Right) == MouseButtons.Right)
{
}
}
public void MouseMove(object sender, MouseEventArgs e)
{
if (null == sender) { return; }
if (false == (sender is CSGL12Control)) { return; }
CSGL12Control csgl12Control = (sender as CSGL12Control);
Point mouseClientPositionCurrent = csgl12Control.PointToClient(Cursor.Position);
if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
double azimuth =
mViewAzimuthDegreesStart
- (360.0 / (double)(csgl12Control.Width + 1))
* (double)(mouseClientPositionCurrent.X - mMouseClientPositionStart.X);
double altitude =
mViewAltitudeDegreesStart
+ (180.0 / (double)(csgl12Control.Height + 1))
* (double)(mouseClientPositionCurrent.Y - mMouseClientPositionStart.Y);
double epsilon = 0.05;
if (azimuth < (-180 + epsilon)) { azimuth = (-180 + epsilon); }
if (azimuth > (180 - epsilon)) { azimuth = (180 - epsilon); }
if (altitude < (-90 + epsilon)) { altitude = (-90 + epsilon); }
if (altitude > (90 - epsilon)) { altitude = (90 - epsilon); }
mViewAzimuthDegrees = azimuth;
mViewAltitudeDegrees = altitude;
}
}
public void MouseWheel(object sender, MouseEventArgs e)
{
mViewDistance -= 0.1 * (double)e.Delta;
}
}
}
Σημειώστε ότι η λειτουργία "OpenGLStarted" είναι το όνομα που χρησιμοποιείται σε αυτό το παράδειγμα για τη δημιουργία "pixel shader programs" και μια OpenGL υφή. Για αυτό το πρόγραμμα, μόνο εμείς πρέπει να δημιουργήσουμε μια φορά αυτούς τους πόρους, και είναι πιο αποτελεσματική για τη δημιουργία από αυτούς μόνο μια φορά.
Σημειώστε ότι η λειτουργία ονομάζεται "OpenGLStarted" τον κωδικό έλεγχοι εάν ένα WGL "extension" λειτουργία ονομάζεται "wglSwapIntervalEXT()" υπάρχει, και, αν αυτή η λειτουργία υπάρχει, ο κωδικός που επικαλείται λειτουργία. Αυτή η λειτουργία καθορίζει μια κατάσταση που επηρεάζει τη λειτουργία του προγράμματος για το σύνολο της συνόδου, και γι 'αυτό χρειαζόμαστε πρόσκληση που λειτουργούν μόνο μια φορά, γι' αυτό και επιχειρούν να καλέσω που λειτουργούν κατά την "OpenGLStarted" λειτουργία (η οποία επικαλέστηκε μόνο μία φορά, όταν OpenGL έχει αρχίσει για μια συγκεκριμένη "CSGL12Control", υποθέτοντας ότι η προστιθέμενη "OpenGLStarted" κατάλληλη μέθοδος για την περίπτωση αναθέσει).
Η λειτουργία "Paint" το όνομα περιέχει το σύνολο των κώδικα για να έλκει ένα ενιαίο "πλαίσιο" animation χρησιμοποιώντας OpenGL. Η λειτουργία "Paint" θα ονομάζεται ίσως 60 φορές ανά δευτερόλεπτο, οφείλεται στο γεγονός ότι οι συνδεδεμένες "CSGL12Control" παράδειγμα έχει "ακυρωθεί" (αναγκάζονται να επιστήσω την ίδια πάλι) με τον εν λόγω συντελεστή. (Κοίτα το παράδειγμα κώδικα "Form" στην προηγούμενη ενότητα για να δείτε το χρονοδιακόπτη που καθορίζει το ύψος της "ακύρωσης" και της πραγματικής λειτουργίας που προκαλεί την κλήση παράδειγμα της "CSGL12Control" να "ακυρωθεί.)"
Όλες οι λειτουργίες είναι η επίκληση OpenGL χρησιμοποιώντας ένα παράδειγμα του "class GL" (παράδειγμα: gl.gl*()). Το παράδειγμα της "class GL" έχει αποκτηθεί από το παράδειγμα της "CSGL12Control", τα οποία είναι αποθηκευμένα σε σιωπηρώς την πρώτη παράμετρο στην "Paint" λειτουργία.
Όλα OpenGL σταθερές μπορεί να ορίζεται με την ένδειξη της "class" όνομα "GL", ακολουθούμενη από μια τελεία και το όνομα της σταθερής? Δηλαδή, "GL.GL_TRIANGLES".
Η OpenGL κωδικό σε αυτό το παράδειγμα δεν είναι εντελώς προφανές και εύκολα κατανοητή, αλλά ελπίζουμε ότι μπορείτε να αναγνωρίσουμε πως ο κωδικός μπορεί να τροποποιηθεί για τις δικές σας ανάγκες.
12. Έλεγχος για την ύπαρξη της "παράτασης" λειτουργίας των OpenGL
Απλά ελέγξτε αν το Boolean σημαία το ίδιο όνομα με τη λειτουργία OpenGL "ισχύει" πριν επιχειρήσετε να χρησιμοποιήσετε την αντίστοιχη λειτουργία.
Η Δυαδική μεταβλητή έχει ένα όνομα που αρχίζει με "b" ακολουθείται από το όνομα OpenGL λειτουργία.
if (true == gl.bglCreateProgramObjectARB)
{
// glCreateProgramObjectARB() exists and can be invoked.
// Also, because that function is related to pixel shaders, it is very
// likely that other functions that are required for the use of pixel
// shaders also exist and can be invoked.
// . . .
}
Ο έλεγχος είναι απαραίτητοι για "την επέκταση" λειτουργίες.
OpenGL 1.1 λειτουργίες, καθώς και όλες τις λειτουργίες GLU, και των βασικών λειτουργιών WGL, δεν απαιτείται η εξακρίβωση αυτή. Ωστόσο, υπάρχουν Boolean σημαίες, και που είναι κατάλληλα για όλες αυτές τις λειτουργίες που παρέχονται από "class GL", συμπεριλαμβανομένων των βασικών λειτουργιών OpenGL 1.1. Έτσι, υπάρχει μια συνεπής τρόπος για να ελέγξετε τη διαθεσιμότητα όλων των αξιωματούχων στην εν λόγω κατηγορία.
Γνωρίζοντας ή αν δεν είναι μια λειτουργία η "επέκταση" είναι η ευθύνη του προγραμματιστή.
Ωστόσο, η λειτουργία όνομα επιθέματα, όπως "EXT", "ARB", "MESA", "NV" (NVidia), "APPLE", κτλ, θα βοηθήσει να υποδεικνύουν παράταση λειτουργίες.
Αν μια λειτουργία "gl*()" έχει μια γειτονική λειτουργία "gl*ARB()" ή "gl*NV()," τότε η λειτουργία "gl*()" είναι πιθανότατα μια επέκταση (στο μέτρο που η Windows OPENGL32.DLL ανησυχεί).
Το μοναδικό πλεονέκτημα να γνωρίζει κατά πόσον ή δεν είναι μια λειτουργία η "επέκταση" (σε σχέση με το Windows OPENGL32.DLL) είναι σε θέση να αποφύγει τον έλεγχο, εάν είναι διαθέσιμες λειτουργίες.
Μπορείτε να κάνετε αναζήτηση για όλες τις λειτουργίες που χρησιμοποιούνται σε OpenGL τον κωδικό σας, και στη συνέχεια να οικοδομήσουν μια αλφαβητική λίστα των διαφόρων λειτουργιών που χρησιμοποιούνται.
Στη συνέχεια, κατά την έναρξη του προγράμματός σας, μετά την CSGL12Control ζητεί την OpenGLStarted αναθέσει, απλά ελέγχει όλες Boolean σημαίες για όλες τις λειτουργίες που σκοπεύετε να χρησιμοποιήσετε.
Αν επιλέξετε να τερματίσει το πρόγραμμα, εάν τυχόν "απαιτούμενες" λειτουργίες λείπουν, στη συνέχεια όλων των ελέγχων για τα καθήκοντα αυτά στον κώδικα μπορούν να εξαλειφθούν.
Επίσης, μπορείτε να αποτελούν μια ομάδα μη βασικές λειτουργίες του ελέγχου, και, ενδεχομένως, ενημερώνει τον χρήστη για κάθε χαρακτηριστικό αλλαγές, και ενδεχομένως αφήνουν ελέγχους διάσπαρτα γύρω από τον κώδικα.
Με περισσότερα OpenGL εμπειρία, μπορείτε να πάρετε μια αίσθηση του τι είναι σχετικές παρατάσεις (παραδείγματα: απεικόνιση, shaders, buffers, συμπίεσης, ...).
Έτσι, μπορείτε να ελέγχετε για την ύπαρξη μιας ενιαίας κρίσιμη λειτουργία και χρησιμοποιούν τις πληροφορίες αυτές για να αποφασίσουν εάν το σύνολο του υποσυνόλου είναι πιθανό να είναι παρόντες.
13. Ταχύτητα
Για διάφορους λόγους, C# είναι βραδύτερη από non-CLR C/C++.
C# είναι τελικά συγκεντρώνονται σε μητρική γλώσσα του συνέρχεσθαι, όπως ακριβώς και για C/C++, αλλά, λόγω των διαβεβαιώσεων που επέφερε το C# τη γλώσσα και την .NET CLR, η συνολική ταχύτητα του λογισμικού βασίζεται C# και .NET είναι κάπως πιο αργή από το λογισμικό με χρήση non-CLR C/C++.
Ως εκ τούτου, να επιτευχθεί η μεγαλύτερη δυνατή ταχύτητα μέσα, χρησιμοποιώντας non-CLR C/C++ αντί C#.
Επιπλέον, επειδή ζητούσε κάθε ιθαγενή από C# βιβλιοθήκη περιλαμβάνει P/Invoke, επικαλούμενη λειτουργίες όπως η OpenGL λειτουργίες θα χρειαστεί κάποιο χρόνο για να εκτελέσει την εργασία του στρώματος P/Invoke.
Ωστόσο, "CSGL12" φαίνεται να λειτουργεί αρκετά γρήγορα για να χρησιμοποιηθεί για πολλά γραφικά σε πραγματικό χρόνο σκοπούς, όπως για απλά παιχνίδια, 3D θεατές, τους συντάκτες, ή 3D παρουσιάσεις. Αυτό ισχύει ιδιαίτερα στην περίπτωση που το μεγαλύτερο μέρος του έργου είναι να γίνει από τον GPU αντί του CPU.
14. Σύγκριση μεταξύ "CSGL12" και την "Tao Framework"
Η "Tao Framework" είναι ένα μεγάλο C# / .NET βιβλιοθήκη η οποία παρέχει μια διασύνδεση για πολλές βιβλιοθήκες ανοιχτού κώδικα, όπως OpenGL, OpenAL (audio), SDL (α gaming / πλατφόρμα προσομοίωσης), Open Dynamics Engine (ODE) (φυσική), κ.λπ.
Η Tao Framework είναι cross-platform (Windows, Linux, Mac OS X).
"CSGL12" μόνο παρέχει ένα μέσο για να OpenGL και είναι μόνο για το λειτουργικό σύστημα Windows.
Η Tao Framework έχει μια κοινότητα. Ένα άτομο μπορεί να επωφεληθεί από την επικοινωνία με άλλους χρήστες του Tao Framework.
Ωστόσο, ενδέχεται να υπάρχουν πολλές "CSGL12" σκοπούς για τους οποίους θα μπορούσε να είναι ευκολότερο να χρησιμοποιήσετε για Windows προγράμματα.