Programmera OpenGL i C++ Del 2
Förord
I föregående artikel gick vi igenom hur man kommer igång med programmering av OpenGL i Visual Studio.NET. Denna artikel utgår från föregående artikel och går igenom lite mer specifikt vad varje funktion gör. Det som koden i denna artikel kommer att göra är att få en tredimensionell kub att rotera på skärmen.Innehåll
»»
»
»
»
»
»
Relaterade artiklar
» Programmera OpenGL i C++ Del 1§
Koden i denna artikel kommer bestå av fyra funktioner.
Vi börjar med att gå igenom vad funktionerna i main funktionen gör. Såhär ser koden ut för main.
glutInit(&argc, argv);
Initierar glut biblioteket. Anledningen till att man skickar med argumenten från main är att glut kan använda vissa argument då man startar programmet.
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
Berättar för glut att vi vill använda oss av dubbel buffert och RGB skalan för färger.
glutInitWindowSize(500,500);
Sätter vilken storlek som fönstret skall ha vid uppstart.
glutInitWindowPosition(100, 100);
Sätter startpositionen på fönstret.
glutCreateWindow("Andra Opengl Programmet");
Skapar ett fönster och sätter titelraden till det man har satt i parametern.
glutDisplayFunc(display);
Tar emot en funktions pekare till en funktion och säger till glut att display är våran display funktion. glutMainLoop ser sedan till att köra denna funktion.
glutReshapeFunc(reshape);
Anger vilken funktion som ska köras då fönstret ändrar storlek. Denna funktion ska vara av typen void
(*func) (int, int). Där de båda int parametrarna är bredd och höjd.
glutIdleFunc(display);
Anger vilken funktion som ska köras då programmet inte har något att göra. I denna applikation anger vi att display ska vara våran funktion eftersom vi vill att den ska rita om skärmen hela tiden.
glutMainLoop()
Startar progammets huvud loop.
Init funktionen är i detta program väldigt simpel. Bara två funktioner som måste sättas då programmet kör igång.
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
Det denna funktion gör är att den sätter den färg som ska bli då skärmen rensas. Mellan varje utritning måste man nämligen rensa skärmen. gl sätter denna funktion till (0,0,0,0) som standard om man inte har med funktionen i sin kod.
glEnable(GL_DEPTH_TEST);
Denna funktion aktiverar glfunktioner och glDisable avaktiverar. Det finns över 60st värden som denna funktion kan ta som inparameter. I detta fall aktiverar vi djup test. Ni kan testa att kommentera bort denna rad för att se hur kuben ser ut utan att använda sig av depth test.
Glut kommer att se till att denna funktion körs varje gång som fönstret ändrar storlek.
Displayfunktionen är den funktion som sköter självaste utritningen på skärmen.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Rensar skärmen. Det som måste rensas i detta program är färg och djup buffert.
glRotatef(angle, 1.0f, 1.0f, 1.0f);
Kanske inte är allt får svårt att lista ut att denna funktion sköter roteringen av våran kub. Exakt hur denna funktion fungerar kommer vi gå igenom i nästa artikel.
glBegin(GL_QUADS);
Här specifierar vi vilken typ av data vi ska rita ut. Här kan vi ange om vi vill rita linjer, punkter eller något annat. De olika alternativen som finns är
glColor3f(0.0f, 0.0f, 1.0f);
Sätter vilken färg som ska användas i RGB format. Kan vara värden från 0.0 till 1.0. Denna rad ger alltså blå färg.
glVertex3f( 0.3f, 0.3f,-0.3f);
Skapar i detta fall en punkt i en 3d rymd. Eftersom vi använder oss av Quads så kommer inget att ritas ut förän den fått 4st Vertex punkter. Denna funktion kan även skrivas glVertex2f eller glVertex4f. Där siffran står för hur många dimentioner som ska användas. f:et i slutet står för att det ska vara GLfloat som invärde. Kan vara s, i, f eller d. Där s står för single, i för int, f för float och d för double. Det är däremot rekommenderat att använda sig av float eftersom grafikkortetn idag är anpassade för att beräkna float tal.
glEnd();
Avslutar våran glBegin()
glutSwapBuffers();
Eftersom vi använder oss av dubble buffert så måste vi även skifta mellan våra bufferts. Detta är precis vad denna funktion gör.
Slutresultatet efter att ni skrivigt koden ovanför kommer att se ut såhär. En kub som roterar.

Nu har ni fått lite större överblick över vad dom de olika funktionerna i glut, glu och gl gör. Nästa artikel kommer att handla om rotation, translation och skalning av objekt. Om ni har några synpunkter på denna artikel eller om det är någon bit ni inte förstår, tveka inte att höra av er till mig så får jag får göra något åt det. Lycka till med OpenGL kodandet och glöm inte att testa att sätta olika värden på funktionerna, det är ett mycket bra sätt att lära sig hur de fungerar.
Här har ni även källkoden till denna artikel:
Källkod
våra funktioner
Koden i denna artikel kommer bestå av fyra funktioner. | Funktion | Förklaring |
|---|---|
| void display() | Har hand om själva utritningen på skärmen |
| void init() | Har hand om initieringen som behöver göras första när programmet startar |
| void reshape(int w, int h) | Denna funktion har hand om sådant som måste ändras då fönstret ändrar storlek. |
| void main(int argc, char** argv) | Uppstarten av programmet |
main funktinoen
Vi börjar med att gå igenom vad funktionerna i main funktionen gör. Såhär ser koden ut för main.
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(100, 100);
glutCreateWindow("Andra Opengl Programmet");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(display);
glutMainLoop();
return 0;
}
glutInit(&argc, argv);
Initierar glut biblioteket. Anledningen till att man skickar med argumenten från main är att glut kan använda vissa argument då man startar programmet.
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
Berättar för glut att vi vill använda oss av dubbel buffert och RGB skalan för färger.
glutInitWindowSize(500,500);
Sätter vilken storlek som fönstret skall ha vid uppstart.
glutInitWindowPosition(100, 100);
Sätter startpositionen på fönstret.
glutCreateWindow("Andra Opengl Programmet");
Skapar ett fönster och sätter titelraden till det man har satt i parametern.
glutDisplayFunc(display);
Tar emot en funktions pekare till en funktion och säger till glut att display är våran display funktion. glutMainLoop ser sedan till att köra denna funktion.
glutReshapeFunc(reshape);
Anger vilken funktion som ska köras då fönstret ändrar storlek. Denna funktion ska vara av typen void
(*func) (int, int). Där de båda int parametrarna är bredd och höjd.
glutIdleFunc(display);
Anger vilken funktion som ska köras då programmet inte har något att göra. I denna applikation anger vi att display ska vara våran funktion eftersom vi vill att den ska rita om skärmen hela tiden.
glutMainLoop()
Startar progammets huvud loop.
init funktionen
void init()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnable(GL_DEPTH_TEST);
}
Init funktionen är i detta program väldigt simpel. Bara två funktioner som måste sättas då programmet kör igång.
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
Det denna funktion gör är att den sätter den färg som ska bli då skärmen rensas. Mellan varje utritning måste man nämligen rensa skärmen. gl sätter denna funktion till (0,0,0,0) som standard om man inte har med funktionen i sin kod.
glEnable(GL_DEPTH_TEST);
Denna funktion aktiverar glfunktioner och glDisable avaktiverar. Det finns över 60st värden som denna funktion kan ta som inparameter. I detta fall aktiverar vi djup test. Ni kan testa att kommentera bort denna rad för att se hur kuben ser ut utan att använda sig av depth test.
reshape funktionen
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0, -1.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
Glut kommer att se till att denna funktion körs varje gång som fönstret ändrar storlek.
display funktionen
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // ränsar alla pixlar på skärmen
glRotatef(angle, 1.0f, 1.0f, 1.0f); //roterar våran kub
glBegin(GL_QUADS); //startar våran Quad utritning,
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f( 0.3f, 0.3f,-0.3f); //Topp
glVertex3f(-0.3f, 0.3f,-0.3f);
glVertex3f(-0.3f, 0.3f, 0.3f);
glVertex3f( 0.3f, 0.3f, 0.3f);
glColor3f(0.0f, 1.0f, 1.0f);
glVertex3f( 0.3f,-0.3f, 0.3f); //Botten
glVertex3f(-0.3f,-0.3f, 0.3f);
glVertex3f(-0.3f,-0.3f,-0.3f);
glVertex3f( 0.3f,-0.3f,-0.3f);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f( 0.3f, 0.3f, 0.3f); //Framsida
glVertex3f(-0.3f, 0.3f, 0.3f);
glVertex3f(-0.3f,-0.3f, 0.3f);
glVertex3f( 0.3f,-0.3f, 0.3f);
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f( 0.3f,-0.3f,-0.3f); //baksida
glVertex3f(-0.3f,-0.3f,-0.3f);
glVertex3f(-0.3f, 0.3f,-0.3f);
glVertex3f( 0.3f, 0.3f,-0.3f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(-0.3f, 0.3f, 0.3f); //Vänster
glVertex3f(-0.3f, 0.3f,-0.3f);
glVertex3f(-0.3f,-0.3f,-0.3f);
glVertex3f(-0.3f,-0.3f, 0.3f);
glColor3f(1.0f, 0.0f, 1.0f);
glVertex3f(0.3f, 0.3f,-0.3f); //Höger
glVertex3f(0.3f, 0.3f, 0.3f);
glVertex3f(0.3f,-0.3f, 0.3f);
glVertex3f(0.3f,-0.3f,-0.3f);
glEnd();
glutSwapBuffers(); //Shiftar buffert
}Displayfunktionen är den funktion som sköter självaste utritningen på skärmen.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Rensar skärmen. Det som måste rensas i detta program är färg och djup buffert.
glRotatef(angle, 1.0f, 1.0f, 1.0f);
Kanske inte är allt får svårt att lista ut att denna funktion sköter roteringen av våran kub. Exakt hur denna funktion fungerar kommer vi gå igenom i nästa artikel.
glBegin(GL_QUADS);
Här specifierar vi vilken typ av data vi ska rita ut. Här kan vi ange om vi vill rita linjer, punkter eller något annat. De olika alternativen som finns är
| Värde | Förklaring |
|---|---|
| GL_POINTS | Individuella punkter |
| GL_LINES | Linje |
| GL_LINE_STRIP | Serie av ihopkopplade linjer |
| GL_LINE_LOOP | Serie av ihopkopplade linjer fast där det blir en linje mellan sista och första punkten |
| GL_TRIANGLES | Trianglar |
| GL_TRIANGLE_STRIP | Ihoplänkade trianglar i strip ordning |
| GL_TRIANGLE_FAN | Ihoplänkade trianglar i fan ordning |
| GL_QUADS | Fyrsidiga polygoner |
| GL_QUAD_STRIP | Ihoplänkade fyrsidiga polygoner |
| GL_POLYGON | Simpel vanlig polygon |
glColor3f(0.0f, 0.0f, 1.0f);
Sätter vilken färg som ska användas i RGB format. Kan vara värden från 0.0 till 1.0. Denna rad ger alltså blå färg.
glVertex3f( 0.3f, 0.3f,-0.3f);
Skapar i detta fall en punkt i en 3d rymd. Eftersom vi använder oss av Quads så kommer inget att ritas ut förän den fått 4st Vertex punkter. Denna funktion kan även skrivas glVertex2f eller glVertex4f. Där siffran står för hur många dimentioner som ska användas. f:et i slutet står för att det ska vara GLfloat som invärde. Kan vara s, i, f eller d. Där s står för single, i för int, f för float och d för double. Det är däremot rekommenderat att använda sig av float eftersom grafikkortetn idag är anpassade för att beräkna float tal.
glEnd();
Avslutar våran glBegin()
glutSwapBuffers();
Eftersom vi använder oss av dubble buffert så måste vi även skifta mellan våra bufferts. Detta är precis vad denna funktion gör.
Slutresultat
Slutresultatet efter att ni skrivigt koden ovanför kommer att se ut såhär. En kub som roterar.
Avslutning
Nu har ni fått lite större överblick över vad dom de olika funktionerna i glut, glu och gl gör. Nästa artikel kommer att handla om rotation, translation och skalning av objekt. Om ni har några synpunkter på denna artikel eller om det är någon bit ni inte förstår, tveka inte att höra av er till mig så får jag får göra något åt det. Lycka till med OpenGL kodandet och glöm inte att testa att sätta olika värden på funktionerna, det är ett mycket bra sätt att lära sig hur de fungerar.Här har ni även källkoden till denna artikel:
Källkod
Krister Johansson
Varför får jag domma felen? Jag har tagit källkoden osv men det funkar inte.... c:\documents and settings\administratör\mina dokument\visual studio projects\firstoplelgl\asdf.cpp(3): warning C4305: 'initializing' : truncation from 'double' to 'GLfloat' och c:\documents and settings\administratör\mina dokument\visual studio projects\firstoplelgl\asdf.cpp(14): warning C4305: 'argument' : truncation from 'double' to 'GLfloat'
Jesper Brännström
Tack Krister för att du meddelade mig detta. Självklart måste man skriva 0.0f istället för 0.0 eftersom kompilatorn tolkar 0.0 som en double och inte en float som det ska vara i detta tillfälle. Jag har nu ändrat detta och lagt upp ny källkod. Nu ska det fungera :-)
Eric Johansson
När kommer nästa artikel??? Skulle gärna vilja läsa mer!
Jesper Brännström
Det var ca 8-9 månader sen jag skrev ihop dessa två artiklar. Jag hoppades på lite respons men det verkar som dessa artiklar inte är så intressanta. Kul i alla fall att du gillade att läsa dem Eric. Jag får se ifall jag kanske tar tag i att skriva vidare på den här serien. Lovar inget just nu i alla fall. Om jag skriver fler artiklar. Vad är de i så fall ni vill se?
Rasmus Anderzon
Om man får rösta så röstar jag på att en till artikel. Mycket bra artiklar