English  Español  Português  Français  Italiano  Deutsch  Nederlands  Svenska  Dansk  Suomi  Norsk  Русский  Polski  Română  Български  Hrvatski  Česky  中国  中國  日本語  한국어  Ελληνική  हिन्दी  العربية 
C# OpenGL interface
varten Windows käyttöjärjestelmä
Colin Fahey
CSGL12Example1_ScreenImage.png
CSGL12Control on Form, osoittaa "Fractal" Pixel Shader-ohjelman ja GDI+ piirustus kopioida joka muokkausaine
CSGL12Example2_ScreenImage.png
Kaksi CSGL12Control tapauksissa on Form, mikä osoittaa, Pixel Shader ohjelmat ja pintakuvioita
CSGL12Avatar_ScreenImage.png
3D avatar että roams työpöydälle voidaan siirtää kohdistimen

1. Ohjelmisto

CSGL12_20090725.zip
CSGL12: C# OpenGL välistyksen Windows, versio 12
4170499 bytes
MD5: 30781a6570441785ea636f2ae1cd16ef

2. Kaikki on C#-koodi on C# OpenGL Interface (CSGL12) on "julkisuudessa"

Kirjoitin koko C#-koodi on C# OpenGL Interface (CSGL12).
Julistan kaikki ne C#-koodi on C# OpenGL Interface (CSGL12) on oltava "julkisia."
Tämän vuoksi tietokone koodia voi käyttää mihin tahansa tarkoitukseen (kaupallinen vai yksityinen), ilman maksua, ilman rajoituksia, ilman velvoitteita, ja ilman tunnustaa alkuperäinen tekijä.
Koodia voidaan muuttaa, tai osia uudelleen, ilman rajoituksia, ja ilman velvoitteita, ja ilman tunnustaa alkuperäinen tekijä.
Esimerkkinä ohjelmat sisältävät pienen määrän tietokone-koodi (erityisesti "shader tietokone-koodi) on kirjoittanut muita ihmisiä."  Tällainen koodi ei ole Kanssakäymisen itse, ja ne voidaan trivially poistettu.  Tällainen koodi on ainoastaan osoittamaan yksinkertaisuus käyttää rajapintana luoda ja käyttää "shader" ohjelmia. 

3. Johdanto

"CSGL12" on kokoelma C#-koodi tiedostoja joka toteuttaa liityntäkohtaa OpenGL graphics library (mukaan lukien kaikki laajennuksia OpenGL vuoteen 2007) varten Windows käyttöjärjestelmä.
The C#-koodi tiedostojen kanssa "CSGL12" keräämisen avulla on helppo lisätä OpenGL nosto mitään C# / .NET ohjelmistojen kanssa "Form" (esimerkki on "System.Windows.Forms.Form").
The "CSGL12" kokoelma-koodi tiedostoja sisältää tiedoston nimeltä "CSGL12Control.cs", jossa määritellään luokan nimeltä "CSGL12Control", joka on johdettu "System.Windows.Forms.Control".  Jokainen esimerkki "CSGL12Control" edustaa riippumaton OpenGL nosto alueella.  Se on hyvin helppo lisätä useita esimerkkejä CSGL12Control joka Form (esimerkki on System.Windows.Forms.Form).

4. Ominaisuudet ja vaatimukset "CSGL12"

Koodi on ainoastaan Windows käyttöjärjestelmistä, jotka tukevat .NET 2.0 Framework (Windows 2000, Windows XP, Windows Vista, Windows 7)
Koodia voidaan laatia käyttäen "Microsoft Visual C# 2008 Express Edition" (vapaa kääntäjä) ja vastaavat C# kerääjiä.
Koodi edellyttää rakennetaan kanssa "[X] Allow unsafe code" rakentaa vaihtoehto valitaan siten, että optimoitu kuvan tietojen kopiointi toimintoja voidaan käyttää.  Jos olet asiantuntija C# ohjelmoija voit helposti tunnistaa osat C# koodi, joka edellyttää, että "unsafe" vaihtoehto ja poistaa ne haluttaessa tai vaaditaan.  Kuvan tietojen kopiointi on 10 kertaa nopeammin käyttämällä "unsafe" koodi kuin sen vaihtoehto, ja siksi tällainen koodi on käytössä.  Jos rakentaa DLL, joka sisältää kaikki ne "unsafe" koodi ja sitten hanke, joka käyttää tätä DLL ei edellytä rakennetaan kanssa "unsafe" vaihtoehto, joten voit päätellä, että ilman kyseistä "unsafe" vaihtoehto hanke ei tarkoita mitään ylimääräistä turvallisuus (koska useat DLL tiedostoja, joita käytetään suoraan tai epäsuorasti, että ohjelma sisältää "vaarallisia" code). 
Koodia voidaan koota ja käyttää jotain seuraavista:
Microsoft Visual C# 2008 Express Edition
Microsoft Visual Studio 2008
Microsoft .NET 3.5 SDK
SharpDevelop
Mono Project
Koodi tarjoaa eniten OpenGL laajennokset (läpi vuoden 2007), mukaan lukien "vertex shaders" ja "pixel shaders".
Koodi tarjoaa 1570 liittyvät tehtävät OpenGL:
 336  GL  functions
  51  GLU functions
  19  WGL functions
1164  extensions
Koodi tarjoaa vaihtoehtoisia muutoksia, 1570 toimintoja eri parametrien tyypit, mukavuuteen.
Koodi määritellään yli 3244 vakioita varten OpenGL.
Koodi on mahdollista saada useita OpenGL piirustus yhteyksissä, kaikki animating itsenäisesti, millä tahansa muulla "Form".
Klikkaamalla "CSGL12Control" antaa sille "panos keskittyä," jotta myöhemmin näppäimistö ja hiiri pyörän tuloliittimeen.  Kohdistin napsautuksia ja liikkeet ovat saaneet, kun kohdistin on suorakulmainen alue on esimerkki "CSGL12Control".
Koodi sisältää toimintoja osoittaa, miten joitakin yhteisiä OpenGL tehtäviä C# ja .NET.
Koodiluetteloista kaikki OpenGL vakioita ja tehtävät aakkosjärjestyksessä vuonna "class GL" vuonna "GL.cs", jolloin on helppo määrittää, jos sellainen on jatkuvaa tai toiminto puuttuu (mikä on epätodennäköistä, lukuun ottamatta extensions annetaan sen jälkeen kun vuoden 2007).
Esimerkkinä ohjelmat osoittavat, miten GDI+ piirustus, joka Bitmap, ja sitten, miten voit kopioida että Bitmap on OpenGL muokkausaine.
Tämä mahdollistaa tekstin ja muiden GDI+ nosto valmiuksia edistää, joka OpenGL näyttämöllä.
The GDI+ Bitmap voidaan päivittää ja ladannut, joka OpenGL texture niin usein kuin kerran OpenGL frame.
Esimerkkinä ohjelmat osoittavat, kuinka valita useiden eri "pixel shader programs" kun ohjelma on käynnissä.
Esimerkkinä ohjelmat osoittavat, kuinka kirjoittaa OpenGL puskureina että kuvatiedostot (JPG, BMP, GIF, PNG).
Paina Shift + 0 (Shift-nolla) kirjoittaa OpenGL puskuria kuvatiedostoja.
Esimerkki koodi näyttää, miten kääntäminen "GL.cs" vuonna on DLL tiedoston, ja sitten lisätään että DLL tiedoston toiseen hankkeeseen, voi estää Microsoft koodi editors (esim.  Microsoft Visual C# 2008 Express Edition jne.) kanssa "IntelliSense" (tilannekohtaisia koodi valmistuttua) tulee usein ja jatkuvasti tavoittamattomalta (toistuvasti keskeyttämällä monta sekuntia, jolloin toimittaja täysin käyttökelvoton).  Ottaa tiedoston "GL.cs" suoraan sisälly mitään hankkeen edited jonka Microsoft koodin muokkaus ei ole käytännöllistä, paitsi jos henkilö on valmis kestämään hitautta editorissa.  Tämä ongelma on vaikuttanut Microsoft Visual Studio 2003, 2005, 2008, ja se todennäköisesti vaikuttaa 2010 versio myös. 
Esimerkki koodi osoittaa käyttää useita esimerkkejä "CSGL12Control" on "Form".
Esimerkki koodi sisältää koodin tehdä 3D "avatarista" että roams työpöydän Windows.

5. Esimerkki ohjelmien mukana "CSGL12"

5.1 "CSGL12DLL"

Hanke nimeltä "CSGL12DLL" tuottaa DLL tiedoston nimeltä "CSGL12DLL.dll" joka sisältää "class GL" (ne on määritelty C# tiedosto "GL.cs").
Putting "class GL" vuonna on DLL tiedoston, ja sitten käyttää tätä DLL muissa hankkeissa, jotka käyttävät "class GL", auttaa välttämään äärimmäinen ongelma kaikki Microsoft koodi editorien kanssa IntelliSense ominaisuutta.  Käyttämällä C# tiedosto GL.cs suoraan hanke aiheuta Microsoft koodi editor kanssa IntelliSense ominaisuus tulla täysin tavoittamattomalta ja käyttökelvoton lähes jatkuvasti, koska tehottomuus ja IntelliSense ominaisuus (ja se, että IntelliSense ilmeisesti estää tärkein ohjelma säiettä, että toimittaja ). 
Jos käytät C# koodi toimittaja, joka ei ole tuotettu Microsoft (esim.  "SharpDevelop", "MonoDevelop" jne.), niin voit sisällyttää tiedoston "GL.cs" suoraan projektejasi, ja sinulla olisi epätodennäköistä saada mitään hyötyä käyttämällä "CSGL12DLL.dll". 

5.2 "CSGL12Control"

Hanke nimeltä "CSGL12Control" tuottaa DLL tiedoston nimeltä "CSGL12Control.dll" joka sisältää "class CSGL12Control" (ne on määritelty C# tiedosto "CSGL12Control.cs").
Putting "class CSGL12Control" vuonna on DLL tiedoston, mahdollistaa, että "Control" (eli luokan peräisin "System.Windows.Forms.Control") voitu liittää "Toolbox" on Microsoft Visual C# 2008 Express Edition (ja vastaavat C# editors).  Ottaa "CSGL12Control" on "Toolbox" helpottaa henkilön lisätä instanssi "CSGL12Control" on "Form" on "Designer" (esim.  henkilö voi yksinkertaisesti käyttää kohdistimen valita ja vetää instanssi "CSGL12Control" alkaen "Toolbox" on "Form"). 
The "CSGL12Control" objekti hallinnoi yksi OpenGL piirustus yhteydessä.  Useita esimerkkejä "CSGL12Control" voidaan samanaikaisesti on "Form".

5.3 "CSGL12Example1"

Hanke nimeltä "CSGL12Example1" tuottaa suoritettavan ohjelmatiedoston (EXE) nimeltä "CSGL12Example1.exe".  Ohjelma käyttää "CSGL12DLL.dll" ja "CSGL12Control.dll" on näyttää esimerkki CSGL12Control ja vetää kuution käyttäen OpenGL.
Ohjelma osoittaa käyttöön neljä erilaista "pixel shaders" "(Fractal, tiili-, puu-," ja "sarjakuva)." 
Ohjelma osoittaa myös käyttää "GDI+", joka .NET piirustus kirjasto, tehdä tekstiä ja muita muotoja on "Bitmap" objekti (a "GDI+" objekti) ja kopioi kuvan tiedot siitä "Bitmap" on "texture" vuonna OpenGL, jolloin kuvan tehdä jonka "GDI+" näkyvän OpenGL piirustus.  Tämä kyky on erittäin hyödyllistä, koska OpenGL puuttuu monia niistä 2D nosto-ominaisuudet löytyvät "GDI+" ja vastaavat 2D piirustus libaries.

5.4 "CSGL12Example2"

Hanke nimeltä "CSGL12Example2" tuottaa suoritettavan ohjelmatiedoston (EXE) nimeltä "CSGL12Example2.exe".  Ohjelma käyttää "CSGL12DLL.dll" ja "CSGL12Control.dll" näyttää kaksi on CSGL12Control, joista jokainen tekee kuutio käyttäen OpenGL.
Ohjelma on "SplitContainer" "Control" annetun "Form".  Kumpikin alueilla, "SplitContainer" sisältää instanssi CSGL12Control.  Näin ollen henkilö voi säätää sijoitukseen jaetun kahden esimerkkejä CSGL12Control.  Tämä osoittaa joustavuutta, CSGL12Control.
Yksi niistä esimerkkejä CSGL12Control lähettää tapahtumien joukko tapahtuman käsittelijöiden on esimerkki "CSGL12Example2Handler1.cs", joka käyttää samaa ohjelmakoodia kuin "CSGL12Example1Handler.cs" on "CSGL12Example1" esimerkki hankkeesta.  Sen vuoksi yksi tapauksista CSGL12Control tehdään kuution yhden valitun "pixel shader" joukosta neljä saatavilla "pixel shaders". 
Toinen esimerkki CSGL12Control lähettää tapahtumien joukko tapahtuman käsittelijöiden on esimerkki "CSGL12Example2Handler2.cs", joka tehdään kuutioina käyttäen muokkausaine kuva (tai "checkerboard" mallia jos kuvatiedosto nimeltä "image.jpg" ei löydy). 

5.5 "CSGL12Avatar"

Hanke nimeltä "CSGL12Avatar" tuottaa suoritettavan ohjelmatiedoston (EXE) nimeltä "CSGL12Avatar.exe".  Ohjelma käyttää "CSGL12DLL.dll" ja "CSGL12Control.dll" vetää kuution käyttäen OpenGL edelleen "Form" ilman rajalla, värien perustuu avoimuuteen käytössä, vetää 3D "avatarista" että roams että Windows työpöydän alueella.
Liikkuvat avatar voidaan napsautit ja vetää uuteen paikkaan käyttämällä kohdistinta.  Kaksoisnapsauttamalla avatar avulla kadota.  Vaikka koodi vain tehdään kuutio, OpenGL voidaan tehdä muita asioita. 
Useita tapauksia on "Avatar-ohjelma" voidaan käynnistää.  Näin ollen monet riippumattomat "avatarista" tapauksissa voi samanaikaisesti samota että Windows työpöydälle.  Tämä on huvittava.  Asiantuntijan C# ohjelmoija voi nauttia löytää tapoja koordinoida toimintaa monta tällaista "avatarista" tapauksissa. 
Valitettavasti korko, jolla Window objekti avoimuus on päivitetty ruudulla on paljon hitaampaa kuin missä määrin OpenGL voi tehdä.  The "avatarista" vain päivitykset 10 kertaa sekunnissa.  En tiedä, jos tämä voidaan parantaa. 

5.6 "CSGL12BuiltExecutableExamplesForReference"

Hakemiston nimeltä "CSGL12BuiltExecutableExamplesForReference" sisältää DLL tiedostot ja EXE tiedostoja tuottaa kaikki esimerkkinä hankkeisiin.  Nämä tiedostot toimitetaan viittaus niin, että tiedostot voidaan testata heti, vaikka henkilöllä ei ole kykyä koota eri hankkeiden alkaen edellyttäen C# koodi.

5.7 "CSGL12UsefulCode"

Hakemiston nimeltä "CSGL12UsefulCode" sisältää C# tiedostoja, jotka voivat olla hyödyllisiä niille ihmisille, jotka haluavat tehdä yleisiä nosto-operaatioiden OpenGL.  Hakemistoon myös DLL tiedostoja "CSGL12DLL.dll" ja "CSGL12Control.dll" mukavuuteen.
Koodi kyseisen hakemiston määritellään eri class, kuten Color4f, Vector3f, Matrix4x4f, Triangle, Mesh, ImageData, Texture, ShaderProgram jne.  Koodi on kohtuullisen tehokas, mutta koodi on tarkoitettu vain innostaa ihmisiä kehittämään omia implementations.

6. CSGL12 tiedostot

The "CSGL12" kokoelma C#-koodi tiedostoja sisältää tiedostot esitetty seuraavassa kaaviossa:
csgl12_files.png
The "CSGL12" kokoelma C#-koodi tiedostoja sisältää tiedostot näkyvät tässä kaaviossa.
The "CSGL12" ohjelmisto sisältää myös sellaisia projekteja, luoda kahden DLL tiedostot ("CSGL12DLL.dll" ja "CSGL12Control.dll") esitetään kaavio.  Nämä kaksi DLL tiedostoja voidaan luoda, jotta se olisi kätevintä luoda ohjelmia, jotka käyttävät OpenGL, mutta se on myös mahdollista luoda ohjelmia käyttämällä vain C# tiedostoja suoraan.

7. "namespace CSGL12" ja "class" tyypit

The "CSGL12" kokoelma C#-koodi tiedostoja määritellään "namespace CSGL12" ja "class" tyypit esitetty seuraavassa kaaviossa:
csgl12_namespace_and_classes.png
The "CSGL12" kokoelma C#-koodi tiedostoja määritellään "namespace CSGL12" ja "class" tyypit ovat osoittaneet tässä kaaviossa.
Ohjelma, joka ei OpenGL nosto voidaan luoda käyttämällä vain "class GL" (käyttäen C# tiedosto GL.cs suoraan tai käyttämällä DLL tiedosto CSGL12DLL.dll joka sisältää myös "class GL").  Kuitenkin käyttäen "class CSGL12Control" (käyttämällä C# tiedosto CSGL12Control.cs suoraan tai käyttämällä DLL tiedosto CSGL12Control.dll joka sisältää myös "class CSGL12Control") tekee lisäämällä OpenGL piirustus, joka Form (System.Windows.Forms.Form) helppoa ja kätevää.
The C# luokkiin Color4f, CSGL12Support, ImageData, ..., alareunassa oleva kaavio on tarjolla vain mukavuussyistä.  Nämä luokat helpottaa luoda ohjelmia, jotka tehdä käyttäen OpenGL.  Saatat kuitenkin jo luokkiin, jotka suorittavat toimia niissä luokissa, tai haluat ehkä luoda samanlainen luokkiin, jotka suorittavat toimia toisin tai tehokkaammin.  Nämä luokat on tarjolla esimerkkeinä erityisesti koodi suunnitteluun ja toteutukseen. 

8. Käyttäen samaa "CSGL12Control" on System.Windows.Forms.Form

8.1 Ohjelman rakenne

Seuraava kaavio osoittaa, miten ohjelman kanssa System.Windows.Forms.Form voi käyttää yhtä "CSGL12Control" tehdä piirustus kanssa OpenGL.  Kaavio osoittaa eri CSGL12 tiedostoja käytetään rakentaa ohjelmaa.
csgl12_windows_form_program.png
Ohjelma käyttäen samaa "CSGL12Control" on System.Windows.Forms.Form

8.2 Käyttämällä Microsoft Visual C# luoda ohjelma

(1) Käynnistä Microsoft Visual C#.
(2) Kun valikossa valitse "File" -> "New Project...".
(3) Kun "New Project" valintaikkunassa, joka tulee näkyviin, valitse "Windows Forms Application" ja valitse nimi ohjelma ja paina "OK".
(4) Heti tallentaa "Solution" valitsemalla "File" -> "Save All".  Valintaikkuna kanssa otsikko "Save Project" näkyy, jotta voit asettaa projektin nimi, hakemistossa, ja "ratkaisu" nimi hankkeeseen.  Muista hakemiston sijainti siten, että olet valmis ottamaan seuraavan ohjeen.  Paina "Save" painiketta, jos haluat tallentaa projektin.
(5) Kopioi kaikki tiedostot hakemistosta "CSGL12UsefulCode" on "CSGL12" ohjelmistoja hakemistoon lähdekoodin sisältävä tiedostot uuden hankkeen (eli hakemiston sisältävät tiedostot "Form1.cs", "Form1.Designer.cs", "Program.cs" jne.) siten, että tiedostot "CSGL12DLL.dll", "CSGL12Control.dll", "Color4f.cs" , "CSGL12Support.cs" jne., ovat yhdessä uuden projektin tiedostoja "Form1.cs" jne.
(6) Vuonna Microsoft Visual C#, lisää "CSGL12" C# tiedostoja projektiin.  Kun valikossa valitse "Project" -> "Add Existing Item...", ja sen "Add Existing Item" valintaikkuna, valitse koko C# tiedostot on CSGL12 ohjelmisto ("Color4f.cs", "CSGL12Support.cs", "ImageData.cs", ...).
(7) Vuonna Microsoft Visual C# lisäämällä "viittaukset asianomaisiin" DLL tiedostoja "CSGL12DLL.dll" ja "CSGL12Control.dll".  Kun valikossa valitse "Project" -> "Add Reference...", ja sen "Add Reference" valintaikkuna, valitse "Browse"-välilehti ja valitse tiedostot "CSGL12DLL.dll" ja "CSGL12Control.dll" alkaen hankkeen lähdetiedostoa directory ja paina "OK". 
(8) Vuonna Microsoft Visual C#, lisää "CSGL12Control" että "Toolbox".  Kun valikossa valitse "Tools" -> "Choose Toolbox Items...".  Kun "Choose Toolbox Items" valintaikkunassa, joka tulee näkyviin, paina "Browse..."-painiketta ja siirry hankkeen hakemistoon lähdekoodin tiedostot ja valitse "CSGL12Control.dll".  Paina "OK" painiketta.
(9) Vuonna Microsoft Visual C#, lukemaan "Toolbox".  Kun valikossa valitse "View" -> "Toolbox".  Kun "Toolbox", siirry osa nimeltä "General" ja etsi kohta nimeltä "CSGL12Control".  Käyttämällä kohdistimen, napsauta kohdetta nimeltä "CSGL12Control" ja vedä ne "Form" vuonna "Design" mieltä. 
(10) Vuonna Microsoft Visual C#, että "Form" "Design" mieltä, siirrä "CSGL12Control" oikeusasteessa annetun "Form" ja säätää sen leveys ja korkeus.  Kun "Properties" paneeli, aseta "Anchor" arvo sisällyttää "Top, Bottom, Left, Right", jos haluat, että valvonta muuttaa koon mukaan muutoksia ohjelman ikkunan kokoa.
(11) Vuonna Microsoft Visual C#, muuttaa projektin ominaisuudet niin, että se voi käyttää "unsafe" koodi.  Kun valikossa valitse "Project" -> "[project] Properties...".  Valitse valintaikkunasta, valitse välilehti nimeltä "Build" ja tarkista valintaruudun nimeltä "[X] Allow unsafe code".  Sulje Projektin ominaisuudet-valintaikkuna.
(12) Vuonna Microsoft Visual C#, lisätä uuden C# tiedosto hankkeeseen.  Kun valikossa valitse "Project" -> "Add New Item...".  Vuonna valintaikkuna nimeltä "Add New Item", valitse malli nimeltä "Class" ja valitse nimi uudelle luokan, kuten "CSGL12MyHandler.cs", ja paina sitten "Add" painiketta.  Katsokaa esimerkiksi hankkeen nimeltä "CSGL12Example1", joka tiedoston nimeltä "CSGL12Example1Handler.cs", joka on esimerkki siitä, miten koodi "CSGL12MyHandler.cs" olisi kirjoitettu. 
(13) Vuonna Microsoft Visual C#, että "Solution Explorer", klikkaa "Form1".  Kun valikossa valitse "View" -> "Code" (tai paina F7 tai oikealle-klikkaa "Form1" ja valitse "View Code".  Koodi tiedosto "Form1.cs" näkyvät editorissa.  Muokka koodi tiedosto "Form1.cs" olla samanlaisia koodi tiedosto "CSGL12Example1Form.cs" tämän hankkeen "CSGL12Example1" mukaan "CSGL12" ohjelmisto.  Erityisesti luoda muuttuja on esimerkiksi oman tapahtumakäsittely luokan (esim.  "CSGL12MyHandler"), ja lisää sitten menetelmistä että luokan esimerkiksi tapauksessa käsittelevät eri tapahtumien Esimerkiksi "CSGL12Control" annetun "Form". 
(14) Vuonna Microsoft Visual C#, kääntää ja suorittaa ohjelman.  Jos haluat jakaa ohjelman, sinun on oltava kahden DLL tiedostot ("CSGL12DLL.dll" ja "CSGL12Control.dll") kanssa suoritustiedoston (*.exe). 
Jos olet asiantuntija C# ohjelmoija, voit välttää tarvetta jakaa DLL tiedostot ("CSGL12DLL.dll" ja "CSGL12Control.dll") kanssa suoritustiedosto (*.exe).
Kopioi tiedostot "GL.cs", "CSGL12Control.cs" ja "PrecisionTime.cs" alkaen hankkeiden nimeltä "CSGL12DLL" ja "CSGL12Control" on "CSGL12" ohjelmistoja lähde hakemiston nykyinen projekti.  Lisää tiedostoja "GL.cs", "CSGL12Control.cs", ja "PrecisionTime.cs" projektiisi niin, että ne kootaan suoraan sisään ohjelmaan.  Ei ole viittauksia "CSGL12DLL.dll" ja "CSGL12Control.dll", että hankkeeseen. 
Katsokaa, että "CSGL12Example1" hankkeen yhteydessä "CSGL12" ohjelmistojen ja tarkastella koodi tiedostot nimeltä "CSGL12Example1Form.cs" ja "CSGL12Example1Form.Designer.cs" nähdä, mitä koodia tarvitaan luoda ja alustaa esimerkki on "CSGL12Control" joka "Form".  Lisää samanlaisia koodin "Form1.cs" ja "Form1.Designer.cs" manuaalisesti luoda ja alustaa esimerkki on "CSGL12Control" teidän "Form". 
Tämä menettely on hyvin vaikeaa, ja vaatii asiantuntemusta ja huolellinen, mutta tuloksena suoritustiedosto (*.exe) ei vaadi "CSGL12DLL.dll" tai "CSGL12Control.dll".  On erittäin mukavaa, että pystyy jakamaan ohjelmiston muodossa yhden suoritustiedoston (*.exe) ilman muita tiedostoja.

8.3 Lisäämällä "viittaukset" CSGL12DLL.dll ja CSGL12Control.dll

Tämä osio sisältää kuvia käyttäen Microsoft Visual C# 2008 Express Edition lisätä "viittaukset asianomaisiin" DLL tiedostoja CSGL12DLL.dll ja CSGL12Control.dll tässä hankkeessa.
Kun valikossa valitse "Project" -> "Add Reference...".  Tai napsauta hiiren kakkospainikkeella "References" kohde "Solution Explorer" paneeli ja valitse "Add Reference...", kuten käy ilmi seuraavasta kuvasta. 
adding_references_001.png
Kontekstivalikko varten "References" kohde "Solution Explorer", josta käy ilmi "Add Reference..."  vaihtoehto
Kun olet valinnut "Add Reference..."  vaihtoehto, valintaikkunan nimeltä "Add Reference" tulee näkyviin.  Tässä valintaikkunassa, valitse "Browse" välilehti ja valitse DLL tiedostoja "CSGL12DLL.dll" ja "CSGL12Control.dll", alla olevan kuvan, ja paina sitten painiketta "OK". 
adding_references_002.png
The "Browse" välilehti on "Add Reference" valintaikkuna, jossa DLL tiedostoja "CSGL12DLL.dll" ja "CSGL12Control.dll" sekä valittujen
Kun olet painanut painiketta "OK", että "Add Reference" Valintaikkuna kadota, ja DLL tiedostoja "CSGL12DLL.dll" ja "CSGL12Control.dll" näkyy, että "References" sivuliike on "Solution Explorer", kuten käy ilmi seuraavasta kaaviosta.
adding_references_003.png
The DLL tiedostoja "CSGL12DLL.dll" ja "CSGL12Control.dll" on "References" sivuliike on "Solution Explorer"

8.4 Lisäämällä CSGL12Control että Toolbox vuonna Microsoft Visual C# 2008 Express Edition

Tämä osio sisältää kuvia käyttäen Microsoft Visual C# 2008 Express Edition lisätä CSGL12Control että "Toolbox" niin, että henkilö voi helposti lisätä esimerkkejä CSGL12Control joka "Form" on "Designer" (Shift+F7 oletusarvona).
Kun valikossa valitse "View" -> "Toolbox".  Kun "Toolbox", siirry osa nimeltä "General", kuten käy ilmi seuraavasta kuvasta.
adding_control_to_toolbox_001.png
The "General" osassa on "Toolbox"
Napsauta hiiren kakkospainikkeella minne tahansa "Toolbox".  Valitse "Choose Items..."  on kontekstivalikko, joka näkyy, kuten käy ilmi seuraavasta kuvasta.
adding_control_to_toolbox_002.png
Optio "Choose Items..."  on kontekstivalikko varten "Toolbox"
Vaihtoehtoisesti, kun valikosta valitse "Tools" -> "Choose Toolbox Items...".
The "Choose Toolbox Items" valintaikkunassa pitäisi näkyä, kuten käy ilmi seuraavasta kuvasta.
adding_control_to_toolbox_003.png
The "Choose Toolbox Items" valintaikkuna
Kun "Choose Toolbox Items" valintaikkuna painamalla "Browse" painiketta.  Kun "Open" valintaikkunassa, joka tulee näkyviin, valitse DLL tiedosto "CSGL12Control.dll", alla olevan kuvan, ja paina sitten "OK" painiketta. 
adding_control_to_toolbox_004.png
The "Open" valintaikkuna, jossa DLL tiedosto "CSGL12Control.dll" valittu
The "CSGL12Control" erä olisi nyt esitettävä "Choose Toolbox Items" valintaikkunassa, kuten käy ilmi seuraavasta kuvasta.  Paina "OK" painiketta.
adding_control_to_toolbox_005.png
The "CSGL12Control" erä nyt näyttää, että "Choose Toolbox Items" valintaikkuna
The "CSGL12Control" erä olisi nyt esitettävä "Toolbox", kuten käy ilmi seuraavasta kuvasta. 
adding_control_to_toolbox_006.png
The "CSGL12Control" erä nyt näyttää, että "Toolbox"

8.5 Lisäämällä CSGL12Control joka "Form" käyttämällä "Toolbox"

Tämä osio sisältää kuvia käyttäen Microsoft Visual C# 2008 Express Edition lisätä instanssi CSGL12Control joka "Form" käyttämällä "Toolbox". 
Kun valikossa valitse "View" -> "Designer" (Shift+F7 oletusarvona).  Tai kaksoisosoitat "Form*.cs" tiedostosta ja "Solution Explorer".  Tai oikeus-osoita "Form*.cs" tiedostosta ja "Solution Explorer" ja valitse "View Designer".  Valitse jokin näistä kolmesta menetelmiä, "Designer" ikkuna, joka "Form" tulisi näkyä.
Kun valikossa valitse "View" -> "Toolbox".  Kun "Toolbox", siirry osa nimeltä "General".  Kohteen nimeltä "CSGL12Control" pitäisi olla siellä, kuten käy ilmi seuraavasta kuvasta. 
adding_control_to_toolbox_006.png
The "CSGL12Control" pitäisi jo olla, että "Toolbox"
Käyttämällä kohdistimen, napsauta kohdetta nimeltä "CSGL12Control" ja vedä ne "Form" vuonna "Designer".  Yksi esimerkki "CSGL12Control" olisi ilmoitettava "Form" kuten käy ilmi seuraavasta kuvasta. 
adding_control_to_toolbox_007.png
Yksi esimerkki "CSGL12Control" on "Form" on "Designer"
Kun "Form" "Designer" mieltä, siirrä Esimerkiksi "CSGL12Control" annetun "Form" ja säätää sen leveys ja korkeus. 
Klikkaa instanssi "CSGL12Control" annetun "Form" valitse se.  Sitten, kun "Properties" paneeli, aseta "Anchor" arvo sisällyttää "Top, Bottom, Left, Right" niin, että koosta "CSGL12Control" muuttuu vastauksena muutoksia ohjelman ikkunan kokoa.  Saatat myös haluta muuttaa muuttujan nimi (eli arvo "(Name)") varten Esimerkiksi "CSGL12Control" alkaen automaattisesti oletus (esim.  "csgL12Control") jotain sopiva koodi (esim.  "mCSGL12Control" tai "mCSGL12Control1" jne.). 
Seuraavassa kuvassa on "Form" "Designer" mieltä ja "Properties" paneeli.
CSGL12Control_ScreenImage.png
Yksi esimerkki CSGL12Control on Form on Designer ja "Properties paneeli

9. Käyttämällä kahta esimerkkejä "CSGL12Control" on System.Windows.Forms.Form

Seuraavassa kaaviossa on esimerkki siitä, kuinka kaksi on "CSGL12Control" voidaan lisätä, joka System.Windows.Forms.Form tehdä piirustus kanssa OpenGL olevaa ohjelmaa.
csgl12_windows_form_program_with_two_controls.png
Ohjelma käyttämällä kahta esimerkkejä "CSGL12Control" on System.Windows.Forms.Form
Seuraa ohjeita edellisessä jaksossa lisätä kerta-"CSGL12Control" joka "Form".  Sitten vain vedät toisen kerran "CSGL12Control" alkaen "Toolbox" on "Form" lisätä toinen "CSGL12Control". 
Jokainen esimerkki "CSGL12Control" on oma muuttujan nimi.  Jokainen esimerkki "CSGL12Control" voi olla oma liittyvät tapahtumakäsittely luokkaan, tai se voi käyttää erillistä tapauksissa yhden ainoan huolitsijan luokan tyyppi. 
Tutki esimerkiksi hankkeen "CSGL12Example2" oppia kaksi "CSGL12Control" voi olla omissa tapahtumissaan lähetetään kaksi erillistä instances mukautettujen tapahtumakäsittely luokkiin selvästi OpenGL piirustus toimintoja. 
Esimerkki ohjelman "CSGL12Example2" on kukin instanssi "CSGL12Control" on "SplitContainer" "Control" yksinkertaisesti osoittaa yksi tapa, jolla instanssi "CSGL12Control" voidaan käyttää.  Kuitenkin tapauksissa "CSGL12Control" voi sijaan sijoitetaan suoraan sen "Form". 

10. Esimerkki C# koodi on "Form" kanssa instanssi CSGL12Control

Seuraavassa on täydellinen C# koodin sisältämä tiedosto "CSGL12Example1Form.cs", joka on osa esimerkiksi ohjelman "CSGL12Example1". 
Tämä koodi on esitetty tässä yksinkertainen esimerkki siitä, miten instanssi CSGL12Control voidaan luoda ja käyttää joka "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);
        }




    }




}
Huomaa, että jäsen muuttuja "mCSGL12Example1Handler" on julistettu viitata esimerkki on class nimeltä "CSGL12Example1Handler".  Tämä luokka on kuvattu myöhemmin osa tätä asiakirjaa.  Huomaa, että rakentajan on "CSGL12Example1Form" lisää menetelmät Esimerkiksi "CSGL12Example1Handler" on "multicast delegates" liittyvien eri tapahtumien jonka instanssi "CSGL12Control".  Tämä tarkoittaa sitä, että kun Esimerkiksi "CSGL12Control" tuottaa erilaisia tapahtumia, nämä tapahtumat aiheuttavat eri Esimerkiksi "CSGL12Example1Handler" (eli "mCSGL12Example1Handler") olisi vedotaan.
Huomaa, että jäsen muuttuja "mTimer" on julistettu viitata esimerkki on class nimeltä "System.Windows.Forms.Timer".  Tämä objekti on käytetty vedota toiminto nimeltä "PrivateTimerTickEventHandler" jokainen 10 millisekuntia.  Toiminto nimeltä "PrivateTimerTickEventHandler" kutsuu menetelmää Esimerkiksi "CSGL12Control" (eli "mCSGL12Control1"), joka aiheuttaa, että "Control" tehdä itse.  Tämä on, miten instanssi "CSGL12Control" voi animoitu joka lähentää verokantaa.
Vain osa määritelmää "class CSGL12Example1Form" olevassa C# tiedoston nimeltä "CSGL12Example1Form.cs".  Toinen osa määritelmää "class CSGL12Example1Form" näkyvään paikkaan C# tiedoston nimeltä "CSGL12Example1Form.Designer.cs".  Vaikka tiedostoja, joiden nimet vastaavat mallia "*.Designer.cs" ovat yleensä luoneet ja muuttaa vain graafisia "Form Designer" ikkuna, joka C# toimittaja, on myös mahdollista luoda ja muokata tällaista C# tiedostot tekstieditorissa. 
Seuraavassa on täydellinen C# koodin sisältämä tiedosto "CSGL12Example1Form.Designer.cs", joka on osa esimerkiksi ohjelman "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(1212);
            this.mCSGL12Control1.Name = "mCSGL12Control1";
            this.mCSGL12Control1.Size = new System.Drawing.Size(640480);
            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(664504);
            this.Controls.Add(this.mCSGL12Control1);
            this.Name = "CSGL12Example1Form";
            this.Text = "CSGL12Example1";
            this.ResumeLayout(false);

        }

        #endregion

        private CSGL12.CSGL12Control mCSGL12Control1;
    }
}
Huomaa, että tämä C# koodi sisältää julistuksen, jonka muuttuja "mCSGL12Control1", joka liittyy instanssi "class CSGL12.CSGL12Control" (eli "class CSGL12Control" vuonna "namespace CSGL12").  Tässä tapauksessa on luotu ja määritetty toiminto "InitializeComponent". 

11. Käsittely tapahtumia, joihin on esimerkki CSGL12Control

Edellisessä luvussa kävi ilmi, C# koodi on "Form" että sisältyi kerta-"CSGL12Control".  The C# koodi lisätä menetelmiä on "class" nimeltä "CSGL12Example1Handler" kuin tapahtuma käsittelevät eri tapahtumien mukaan Esimerkiksi "CSGL12Control". 
Seuraavassa on luettelo mielenkiintoisia tapahtumia "CSGL12Control" ja "delegate" tyypit liittyvät tapahtumat:
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
Ainoastaan "OpenGLStarted" tapahtuma on tapahtuma tyyppi liittyvät "CSGL12Control".
Kaikki muut tapahtumat ovat standardin System.Windows.Forms tapahtumia, joiden tapahtuma käsittelijöiden on tiettyjen parametrien (määritelty missään Forms dokumentointi).
The "OpenGLStarted" ja "Paint" tapahtumat ovat tärkeimpiä tapahtumia OpenGL piirustus.
The "OpenGLStarted" tapahtuma on vedota aivan ensimmäinen "Paint" tapauksessa vedotaan.
Näin ollen "OpenGLStarted" Jos huolitsija on lisättävä valvontaa, ennen kuin valvonta on mahdollisuus yrittää maalata itse, muuten kerta-tapahtumaa ei saatu.
Tämä tapahtuma on vain sopii, ja se voidaan jättää huomiotta.
Kuitenkin lisäämällä huolitsijan tätä tapahtumaa varten mahdollistaa sen, että huolitsijan code tehdä noin-aika alustamisen, että riippuu OpenGL on valmis käytettäväksi.
(OpenGL ei voida käyttää, kunnes ikkuna on olemassa, ja ikkuna on valmis tekemään sen ensimmäisen maalin.
Joten, "OpenGLStarted" tapauksessa varaosat ohjelmoijan osoitteesta riski yrität käyttää OpenGL liian pian sen jälkeen, kun ohjelma alkaa.
) On melko helppoa lisätä logiikka on "Paint" huolitsijan tehdä kerta-käynnistystoimien käyttäen OpenGL osana "CSGL12Control".
The "OpenGLStarted" tapahtuma on tarjota mukavuutta.
Seuraavassa on täydellinen C# koodin sisältämä tiedosto "CSGL12Example1Handler.cs", joka on osa esimerkiksi ohjelman "CSGL12Example1". 
Tämä koodi on esitetty tässä yksinkertainen esimerkki siitä, miten tapahtumien jonka instanssi "CSGL12Control" voidaan käsitellä tehdä käyttäen 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(512512, 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(64128128140));
        }
















        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(00, 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(0Color.White));


                    g.FillEllipse(mBrush1, new Rectangle(00256256));
                    g.FillEllipse(mBrush1, new Rectangle(256256256256));

                    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;
        }




    }




}
Huomaa, että toiminto nimeltä "OpenGLStarted" käytetään tässä esimerkissä luodaan "pixel shader programs" ja OpenGL muokkausaine.  Tämän ohjelman, meidän tarvitsee vain luoda näitä resursseja kerran, ja se on tehokkaampaa luoda ne vain kerran. 
Huomaa, että toiminto nimeltä "OpenGLStarted" koodin tarkastuksia, jos WGL "extension" toiminto nimeltä "wglSwapIntervalEXT()" olemassa, ja jos tämä toiminto on olemassa, koodi vetoaa tätä toiminnallisuutta.  Tämä toiminto asetetaan valtion, joka vaikuttaa toiminnan ohjelman koko session, joten meidän täytyy vain soittaa, että toiminto kerran, ja siksi yrittää soittaa, että vaikutuksia "OpenGLStarted" toiminto (joka itse on vain vedota kerran, kun OpenGL on aloittanut tietyn "CSGL12Control", jos olemme lisänneet "OpenGLStarted" menetelmä on sopiva tapauksessa siirtää).
Toiminto nimeltä "Paint" sisältää kaikki koodi tehdä "yhden" kuvan animaation avulla OpenGL.  The "Paint" toiminto kutsutaan ehkä 60 kertaa sekunnissa, johtuu siitä, että assosioituneet "CSGL12Control" esimerkiksi on "mitätöity" (pakko tehdä itse uudestaan) näillä pisteillä.  (Katso lukua "Form" koodi esimerkiksi edellisessä jaksossa nähdä ajastin, joka määrittää osuus "mitättömyysperuste" ja todellisen funktiokutsua joka aiheuttaa Esimerkiksi "CSGL12Control" tulla "mitätöity.)" 
Kaikki OpenGL toiminnot ovat vedonneet käyttämällä esimerkiksi, että "class GL" (esimerkki: gl.gl*()).  Esimerkiksi "class GL" on hankittu Esimerkiksi "CSGL12Control", joka on implisiittisesti tallennetaan ensimmäisen parametrin itse "Paint" toiminto.
Kaikki OpenGL vakioita voidaan määrittää lisäämällä "class" nimi "GL" seurasi pisteen ja nimi on vakiona, eli "GL.GL_TRIANGLES".
The OpenGL koodi tässä esimerkissä ei ole täysin selvä ja helposti ymmärrettävä, mutta toivottavasti voit tunnistaa miten koodia voidaan muuttaa omaan käyttöösi.

12. Tarkistaminen saatavuuden "laajentamisesta" tehtävä OpenGL

Yksinkertaisesti tarkistaa, jos Boolen lippu on sama nimi kuin OpenGL toiminto on "totta," ennen kuin yrität käyttää vastaavaa toimintoa.
The Boolen muuttuja on nimi, joka alkaa "b" jota seuraa OpenGL toiminnon nimeä.
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.

    // . . .
}
Tarkastuslennot tarvitaan vain "laajentaminen" toimintoja.
OpenGL 1.1 tehtäviä, ja kaikki GLU toimintoja, ja keskeisten WGL toimintoja, eivät edellytä tällaista tarkkailun.  Kuitenkin Boolen liput on olemassa, ja ne asianmukaisesti, kaikkien näiden tehtävistä säädetään "class GL", mukaan lukien ydin OpenGL 1.1 toimintoja.  Näin ollen on johdonmukainen tapa tarkistaa kaikki käytettävissä olevat toiminnot kyseisessä luokassa. 
Tietäen, onko toiminto on "pidennys" on vastuu ohjelmoijan.
Kuitenkin funktion nimi suffixes, kuten "EXT", "ARB", "MESA", "NV" (NVidia), "APPLE" jne. auttaa osoittavat laajentaminen toimintoja.
Jos funktio "gl*()" on läheisten funktio "gl*ARB()" tai "gl*NV()," sitten funktio "gl*()" on luultavasti laajennus (sikäli kuin Windows OPENGL32.DLL on huolissaan).
Ainoa etu tietää, onko funktio "on" jatkoa (suhteessa sen Windows OPENGL32.DLL) on pystyttävä välttämään tarkastuksen, jos toiminnot ovat käytettävissä.
Voit hakea kaikki OpenGL toimintoja käytetään koodi, ja sitten rakentaa aakkosellinen luettelo eri toimintoja käytetään.
Sitten alussa ohjelman jälkeen CSGL12Control kutsuu OpenGLStarted siirtää yksinkertaisesti tarkistaa kaikki Boolen lippuja kaikkien toimintojen aiot käyttää.
Jos päätät lopettaa ohjelma, jos "tarvittavat" toiminnot ovat kateissa, niin kaikki tarkastukset tällaisten toimintojen koodi voidaan poistaa.
Lisäksi voit muodostaa ryhmän muita kuin keskeisiä tehtäviä on tarkistettava, ja mahdollisesti ilmoittaa käyttäjälle kaikista ominaisuus muutoksia, ja mahdollisesti jättää tarkastusten siroteltuna ympäriinsä koodia.
With more OpenGL kokemus, voit saada tunteen siitä, mitä laajennuksia ovat etuyhteydessä (esimerkkejä: kuvantaminen, shaders, puskurien, kompressio, ...).
Siksi voit tarkistaa läsnä yhden kriittisen toiminnan ja käyttää kyseisiä tietoja päättää, jos koko osajoukko on todennäköisesti läsnä.

13. Speed

Eri syistä, C# on hitaampaa kuin non-CLR C/C++.
C# lopulta käännetty alas native kokoonpano kielellä, aivan kuin C/C++, mutta johtuu siitä, että vakuutukset tekemät C# kielen ja .NET CLR, yleinen nopeus ohjelmisto rakentuu C# ja .NET on hieman hitaampaa kuin ohjelmisto on rakennettu käyttäen non-CLR C/C++.
Siksi saamaan suurin nopeus mahdollisia keinoja käyttäen non-CLR C/C++ sijasta C#.
Lisäksi, koska vaativat kaikki natiivi-kirjaston mistä C# liittyy P/Invoke vedoten toimintoja, kuten OpenGL tehtävät edellyttävät jonkin verran aikaa tehdä työtä, P/Invoke kerroksella.
Tästä huolimatta "CSGL12" näyttää toimivan riittävän nopeasti, jota käytetään monissa reaaliaikainen graafinen tarkoituksiin, kuten yksinkertaisia pelejä, 3D katsojat, toimittajat, tai 3D-esityksiä.  Tämä on erityisen totta, jos suurin osa työstä on tehty, jonka GPU sijaan, että CPU.

14. Vertailu "CSGL12" ja "Tao Framework"

The "Tao Framework" on suuri C# / .NET kirjasto, joka tarjoaa rajapinnan monien avoimen lähdekoodin kirjastoja, kuten OpenGL, OpenAL (ääni), SDL (a pelaamista / simulointi foorumi), Open Dynamics Engine (ODE) (fysiikka), jne.
The Tao Framework on cross-platform (Windows, Linux, Mac OS X).
"CSGL12" vain tarjoaa käyttöliittymän OpenGL ja ainoastaan sen Windows käyttöjärjestelmä.
The Tao Framework on yhteisö.  Henkilö voisi saada viestiä muiden käyttäjien kanssa Tao Framework.
Voi kuitenkin olla monia tarkoituksia, joita varten "CSGL12" saattaa olla helpompaa käyttää Windows ohjelmia. 
colinfahey.com
yhteystiedot
English  Español  Português  Français  Italiano  Deutsch  Nederlands  Svenska  Dansk  Suomi  Norsk  Русский  Polski  Română  Български  Hrvatski  Česky  中国  中國  日本語  한국어  Ελληνική  हिन्दी  العربية