<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN"> <html> <head> <meta name="generator" content="HTML Tidy, see www.w3.org"> <title>GLUT: Menu's gebruiken</title> </head> <body> <h1>GLUT: Menu's Gebruiken</h1> <h4>ArticleCategory: [Choose a category for your article]</h4> SoftwareDevelopment <h4>AuthorImage:[Here we need a little image from you]</h4> <img src="../../common/images/Miguel-S.jpg" alt= "Miguel Sepulveda" width="129" height="168"> <h4>TranslationInfo:[Author and translation history]</h4> <p>original in en <a href= "mailto:Miguel.Sepulveda@disney.com">Miguel A Sepulveda</a></p> <p>en to nl <a href= "nospam:ghs(at)linuxfocus.org">Guus Snijders</a></p> <h4>AboutTheAuthor:[A small biography about the author]</h4> <h4>Abstract:[Here you write a little summary]</h4> <p>Dit artikel is de derde in een serie over de GL Utility Toolkit (GLUT), ontwikkeld door Mark Kilgard. GLUT is een erg bruikbare toolkit voor OpenGL ontwikkelaars, omdat je hiermee de API op een simpel te leren en te gebruiken manier kan gebruiken voor een OpenGL applicatie, architectuur onafhankelijk!</p> <h4>ArticleIllustration:[This is the title picture for your article]</h4> <img src="../../common/images/transpix.gif" alt= "[Illustratie]" hspace="10" width="1" height="1"> <h4>ArticleBody:[The article body]</h4> <h2>Introductie</h2> <p>Zoals reeds eerder genoemd in eerdere artikelen, bevat OpenGL om ontwerp-redenen alleen de architectuur ofhankelijke aanwijzingen van een geavanceerde 3D API. Het openen van vensters, afhandelen van toetsenbord invoer, enz.. zijn sterk platform afhankelijk en vallen daardoor buiten het bereik van OpenGL. Het antwoord op dit probleem is GLUT: GLUT biedt een algemene interface, op meerdere platformen, voor het hanteren van dingen als vensters, dubbel bufferen, tekst renderen, toetsenbord invoer en menu's.</p> <p></p> <h2>Menu's</h2> <p>Vandaag zullen we het gebruik van menu's in onze OpenGL applicaties verkennen. Een menu is een manier van gebruiker-applicatie communicatie. In ons vorige artikel (<a href= "../March1998/article29.html">Vensters Beheren</a>) demonstreerden we een andere techniek voor gebruikers invoer, hot keys. GLUT vangt de toetsenbord invoer gebeurtenissen, evenals muis knop gebeurtenissen af en staat ons toe callback functies te definiëren om op die gebeurtenissen te reageren. Het nadeel van "hot keys" is dat ze onzichtbaar zijn, van de gebruiker verlangen de handleiding te lezen of te onthouden wat welke toets doet. Menu's zijn daarentegen veel flexibeler omdat ze grafisch zijn en de gebruiker de momenteel beschikbare opties tonen. </p> <p>Als voorbeeld is hier de broncode van een programmavoorbeeld (<a href= "../../common/May1998/example1.tar.gz" >example1.tar.gz</a>). Dit programma is een modificatie van het voorbeeld in ons vorige artikel <a href="../March1998/article29.html">Vensters Beheren</a> Download het programma en compileer deze met de geleverde Makefile. </p> <a href="../../common/May1998/glut3.jpg"><img src= "../../common/May1998/glut5.jpg" width="305" height="313" border="1" align="left" hspace="10"></a> <P>Voor compileren is een OpenGL library nodig (bijvoorbeeld Mesa) en de GLUT library. Beide libraries zijn breed beschikbaar en in verschillende vormen onderdeel van de meeste Linux distributies. Na compilatie hebben we een uitvoerbaar bestand, <tt>example1</tt> . Als je deze uitvoert zie je een nieuw venster met een gekleurde driehoek van rood-groen-blauwe vlakken (zie linker figuur). </p> <p>Het frame bevat een hoofdvenster met een zwarte achtergrond en een driehoek in het midden en een sub-venster met een grijze achtergrond waar wat tekst op geschreven is. On voorbeeld is eigenlijk een echte tijd animatie, dus het tijd veld in het sub-venster zou voorwaarts moeten bewegen. </p> <p>Verplaats de muis cursor naar het gebied van het hoofdvenster en klik en houdt de linker muisknop ingedrukt. Deze gebeurtenis wordt afgevangen door ons voorbeeld en zou het volgende menu moeten openen: </p> <img src="../../common/May1998/glut1.jpg" width="124" height= "68" border="0" align="left" hspace="10"> <p>Het menu bevat drie acties (switch on rotation, switch on translation, change color) en een laatste optie om de applicatie af te sluiten. Houd de linkermuisknop ingedrukt, beweeg naar iedere actie en test deze om te zien wat er gebeurd. </p> <p>Door "Rotation On" te selecteren, zal de driehoek rond zijn centrum gaan draaien, het "Translation On" menu item laat de driehoek horizontaal door het venster bewegen en om het scherm "wrappen" als het einde is bereikt. De "Change Color" actie triggert een sub-menu met deze nieuwe opties:</p> <img src="../../common/May1998/glut2.jpg" width="50" height= "68" border="0" align="left" hspace="10"> <ul> <li><b>Red</b> Rendert de driehoek in rood</li> <li><b>Blue</b> Rendert de driehoek in blauw</li> <li><b>Green</b>Rendert de driehoek in groen</li> <li><b>RGB</b> Rendert de driehoek in rood, groen en blauw</li> </ul> <p>Dit is een erg simpel voorbeeld van het gebruik van menu's binnen een OpenGL applicatie. Het uiterlijk van de menu's en sub-menu's is platform-afhankelijk. De weergave die hier is weergegeven is representatief voor Linux GLUT. Gecompileerd onder Windows 95/NT zullen de menu's er enigzins anders uitzien. Wat telt is dat de functionaliteit overdraagbaar is zolang je de GLUT library gebruikt. </p> <p>Merk op dat het hoofdmenu twee verschillende soorten menu ingangen heeft. Het eerste type (Rotation On, Translation On) veranderd nadat de gevraagde actie wordt uitgevoerd. Dit betekend dat, nadat je de driehoek in rotatie modus start, de volgende keer dat je het menu bekijkt, de optie "Rotation Off" zal heten. Het andere type menu ingang blijft altijd constant, zoals "Change Color", "Red", "Blue" en "Green". </p> <p>Er zijn nog een paar interessante dingen waarvan ik zou willen dat de lezer op de hoogte is, alvorens verder te gaan met het beschrijven van hoe deze menu's zijn te programmeren. Herinner je je dat ik deze demo had met twee hot keys? (<a href="../March1998/article29.html">Vensters Beheren</a>). Deze toetsen zijn "q" om af te sluiten (q) en "i" om de informatieve banner in- en uit te schakelen. Probeer deze, ze werken nog steeds. </p> <p>Terwijl de informatieve banner op een (sub-venster) aan is, beweeg de cursor ergens in het grijze gebied en klik met de linkermuisknop. Verassing! Je zou dit andere menu moeten zien: </p> <center> <img src="../../common/May1998/glut4.jpg" width="160" height= "20" border="0"> </center> <p>Dit demonstreert dat menu's niet alleen aan gebeurtenissen zijn verbonden (linkermuisknop) maar dat ze ook vertaald worden naar de huidige OpenGL context. In ons vorige artikel hebben we reeds gemeld dat een GLUT sub-venster zijn eigen OpenGL context heeft, hier zien we een andere consequentie van dat feit. Twee menu's zijn verbonden met dezelfde gebeurtenis, maar in een verschillende context. De ontwikkelaar heeft dan een krachtige tool om een erg geavanceerde gebruikers interface te maken voor zijn/haar applicaties.</p> <p>Nog interessanter is het feit dat je de informatie banner kunt uitschakelen met de i-toets, de cursor bewegen naar het bovenste deel van het frame en vervolgens een melding krijgen dat je niet terug kunt naar de "This is a dummy menu" entry. Waarom? Omdat bij het verbergen van een sub-venster de volledige context (inclusief bijbehorende menu's) ook wordt verborgen. </p> <p>Nu zullen we de inhoud van het programma beschrijven. Ik ga er vanuit dat lezers reeds bekend zijn met het GLUT & OpenGL materiaal in eerdere artikelen. De <tt>main()</tt> bevat verschillende secties, <em>de volgorde is belangrijk</em>: </p> <ul> <li><b>GLUT initialisaties</b>. Open een weergave venster, geef opdrachtregel argumenten mee, zet weergave mode en opties. </li> <li><b>Main Window Creation</b>. Creëer het hoofd venster, stel relevante callback functies in die geassocieerd zijn met het venster, zet <tt>idle</tt> callback functie</li> <li><b>Create a Sub-menu</b>. Dit sub-menu beheert de "Change Color" actie en wordt straks in het hoofdmenu opgenomen. </li> <li><b>Create Main Menu</b>. Bouw een hoofd menu, voeg de menu items toe en neem ook het vorige sub-menu op als een van de items, en koppel dit menu ten slotte aan de linker-muisknop gebeurtenis. Merk op dat we ons nog steeds in de context van het hoofd venster bevinden. </li> <li><b>Create a GL Call list</b>. Dit is een geavanceerd OpenGL onderwerp waar we hier niet ver op ingaan. Het volstaat te zeggen dat een call list een manier is om een OpenGL objecten te bouwen en op te nemen tijdens een run time voor latere oproepen. Het aanroepen van een GL call list element, in tegenstelling tot het opnieuw opbouwen van het element, is veel efficiënter. In deze demo zijn er vier call list items: een rode driehoek, een blauwe driehoek, een groene driehoek en een RGB driehoek. </li> <li><b>Sub-Window Creation.</b> Creëer een sub-venster, bewaar een handle, stel pertinente callback functies in. Nadat het sub-venster is gebouwd, wordt er een nieuwe context gecreëerd. </li> <li><b>Create Main Menu for sub-Window.</b> Net zoals we eerder hebben gedaan, creëren we een nieuw menu, voegen menu items toe en verbinden deze aan de linker muisknop. Nu zal het menu worden opgenomen in de context van het sub-venster. </li> </ul> <p>Behalve het creëren van het menu, zou de lezer al bekend moeten zijn met de secties. Een snelle inspectie van de menu creatie code laat zien hoe eenvoudige het is. Menu's worden gemaakt met de directive <tt>int glutCreateMenu( void (f*)(int) )</tt>, de funcite <tt>f</tt> is een callback functie die het nummer neemt dat wordt geretourneerd door het getriggerde menu item en voert de bijbehorende actie uit. De waarde die wordt geretourneerd door <tt>glutCreateMenu</tt> is een integer identifier voor het nieuw gecreërde venster. </p> <p>De callback functies die worden gebruikt om de menu gebeurtenissen af te handelen zijn vrij eenvoudig. Bekijk <tt>void mainMenu(int)</tt> of <tt>void subMenu(int)</tt>. Ze gebruiken gewoon een <tt>switch</tt> statement die de gevraagde menu items verwerkt. </p> <p>Nadat een menu is gemaakt, voegt onze code hier items aan toe met de functie <tt>void glutAddMenuEntry(char *s, int nr)</tt>, waarbij s de tekst is die in het menu item veld wordt geschreven en nr het id dat aan de callback functie wordt meegegeven als dit menuitem wordt geselecteerd. Uiteraard moet je er wel op letten dat je geen identieke id's voor menu items in hetzelfde menu gebruikt. </p> <p>Sub-menu's worden op een vergelijkbare manier toegevoegd met de functie <tt>void glutAddSubMenu(char *s, int nr)</tt>.</p> <p>Tenslotte, bij het afronden van het menu, wordt deze verbonden aan een invoer gebeurtenis (linker muisknop) met de <tt>glutAttachMenu</tt> functie. Deze functie kan ook GLUT_RIGHT_BUTTON, GLUT_MIDDLE_BUTTON nemen. </p> <p>Menu items kunnen tijdens bedrijf aangepast worden dankzij het commando <tt>void glutChangeToMenuEntry(int entry, char *s, int value)</tt>, welke het menu item "entry" van het huidige venster veranderd in een met het label <tt>s</tt> en retourneerd <tt>value</tt> aan de callback functie. In ons voorbeeld gebruikten we </p> <pre> glutChangeToMenuEntry(2, "Translation On", 2); </pre> om entry nummer 2 te hernoemen van het hoofd menu en zo verder met de andere mogelijkheden. <br> <br> <p>GLUT biedt meer mogelijkheden: een menu item veranderen in een gestapeld menu en omgekeerd, menu's vernietigen, menu items verwijderen, en meer. We zullen deze hier niet verkennen omdat ik van mening ben dat het huidige voorbeeld simpel en functioneel genoeg is om de meeste gebruikers tevreden te stellen. Als je extra functionaliteit nodig hebt, kun je het beste kijken naar het meest recente GLUT manual boek. </p> <hr size="2" noshade> <br> <b>Voor meer informatie</b>:<br> <ul> <li>Lees andere artikelen in deze serie: <a href= "../January1998/article16.html">Vensters en Animaties</a>, <a href="../March1998/article29.html">Windows Management</a>.</li> <li>Lees de GLUT manual, onderdeel van de broncode. </li> </ul> </body> </html>