Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Autor: Janusz Ganczarski
Biblioteki C++

Pierwszy program

[lekcja] Rozdział 2. Pierwszy program w OpenGL: rysowanie sceny 3D (kolor tła, czyszczenie bufora koloru, kolor obiektu, definiowanie obiektu, zamiana buforów koloru), tworzenie okna renederingu, obsługa menu podręcznego.

Pierwszy program

Pierwszy program korzystający z biblioteki OpenGL jest oczywiście bardzo prosty. Wyświetlimy w oknie o rozmiarach 400 × 400 pikseli kwadrat o bokach jednostkowych. Program składa się z trzech zasadniczych elementów. Pierwszy to funkcja rysująca scenę 3D, drugim jest inicjacja okna renderingu a trzecim obsługa menu podręcznego.

Poniższy rysunek przedstawia program, jaki zostanie napisany w oparciu o wiedzę zdobytą w niniejszym rozdziale.
Rysunek 1. Okno początkowe programu Kwadrat 1
Rysunek 1. Okno początkowe programu Kwadrat 1

Rysowanie sceny 3D

Rysowanie, czy tez jak przyjęło się to nazywać, renderowanie sceny 3D, składa się z kilku kroków. Z uwagi na prostotę programu etapy występujące w pierwszym programie nie przedstawiają kompletnego schematu tworzenia sceny 3D.

Kolor tła

Pierwszym etapem tworzenia sceny 3D, który realizuje funkcja Display, jest określenie koloru tła, czyli wartości jakimi zostanie wypełniony bufor koloru. Realizuje to funkcja:
C/C++
void glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
której parametry red, green, blue określają wartości składowych koloru, a parametr alpha wartość składowej kanału alfa (stopień przeźroczystości piksela). Wartości wszystkich parametrów funkcji glClearColor powinny zawierać się w przedziale [0, 1]. Parametry przekraczające powyższy zakres zostaną odpowiednio przycięte: mniejsze od 0 przyjmą wartość 0, większe od 1 wartość 1. Domyślne podczas czyszczenia bufora koloru używa się koloru (0, 0, 0, 0).

Czyszczenie bufora koloru

Po określeniu koloru tła przystępujemy do wyczyszczenia tła, czyli wypełnienia zawartości bufora koloru. Wykonuje to funkcja:
C/C++
void glClear( GLbitfield mask )
której na razie jedynym parametrem jest stała GL_COLOR_BUFFER_BIT określająca jaki element bufora ramki ma zostać wypełniony.

Kolor obiektu

Kolejnym etapem tworzenia naszej sceny 3D jest określenie koloru obiektu. Wykorzystamy do tego celu jedna z funkcji z rodziny glColor:
C/C++
void glColor3f( GLfloat red, GLfloat green, GLfloat blue )
której parametry red, green, blue określają wartości składowych koloru. Zakres tych wartości powinny zawierać się w przedziale [0, 1]. Wartości znajdujące się poza tym przedziałem zostaną odpowiednio przycięte.

Uważny Czytelnik zapyta zapewne dlaczego dla koloru obiektu nie określamy wartości składowej alfa. Jest to oczywiście możliwe - rodzina funkcji glColor zawiera także funkcje określające kolor na podstawie czterech składowych. Jeżeli jednak zdecydujemy się na określanie tylko składowych RGB, składowa alfa przyjmuje domyślną wartość 1,0 (całkowita nieprzezroczystość).

Definiowanie obiektu

Definiowanie obiektów w OpenGL rozpoczyna wywołanie funkcji:
C/C++
void glBegin( GLenum mode )
która określa rodzaj generowanego prymitywu lub prymitywów. W pierwszym programie traktujemy kwadrat jako szczególny przypadek wielokąta, stad stała GL_POLYGON. Kolejne wierzchołki kwadratu określamy przy pomocy funkcji:
C/C++
void glVertex3f( GLfloat x, GLfloat y, GLfloat z )
która należy do rodziny obszernej funkcji glVertex. Jeżeli uważnie popatrzymy na współrzędne wierzchołków rysowanego kwadratu, to zauważymy, ze zawiera się on w płaszczyźnie o równaniu Z = 0. W takim przypadku do definiowania współrzędnych wierzchołków obiektów można także zastosować funkcje glVertex2, która pozwala określić dwie pierwsze współrzędne wierzchołków, trzeciej nadając wartość 0.

Definiowane współrzędnych wierzchołków obiektu obowiązkowo kończy wywołanie funkcji:
C/C++
void glEnd( void )
Specyfikacja biblioteki nie pozwala na uruchamianie wszystkich poleceń OpenGL pomiędzy para wywołań funkcji glBegin i glEnd. Co do zasady mogą się tam znaleźć polecenia generujące obiekty sceny. Wywołanie niedozwolonej funkcji powoduje zgłoszenie błędu, ale nie przerywa działania programu.

Wykonanie poleceń OpenGL i zamiana buforów koloru

To w jaki sposób biblioteka utworzy scenę 3D, po wywołaniu wszystkich funkcji tworzących jej elementy, zależy oczywiście od konkretnej implementacji. Jednak wywołując funkcje:
C/C++
void glFlush( void )
możemy wymusić wykonanie wszystkich dotychczasowych poleceń Ma to szczególne znaczenie, gdy dana implementacja stosuje bufory poleceń, a zależy nam na wykonaniu części zadań Końcowym elementem tworzenia sceny 3D jest zamiana buforów koloru, co w przypadku stosowania biblioteki GLUT realizuje funkcja:
C/C++
void glutSwapBuffers( void )

Tworzenie okna renderingu

Okno renderingu tworzone jest funkcji main programu. Inicjalizacje bufora ramki wykonuje funkcja:
C/C++
void glutInitDisplayMode( unsigned int mode )
W przykładowym programie wartość parametru mode decyduje, ze bufor ramki zawiera dwa bufory koloru (stała GLUT_DOUBLE), które pracują w trybie RGB (stała GLUT_RGB).

Rozmiar okna renderingu, w którym będzie rysowana scena 3D określa funkcja:
C/C++
void glutInitWindowSize( int width, int height )
której parametry width i height oznaczają odpowiednio szerokość i wysokość obszaru dostępnego do renderingu. Warto zauważyć, ze wielkość okna jakie zostanie utworzone po wywołaniu funkcji:
C/C++
int glutCreateWindow( char * name )
jest zależna od systemu operacyjnego i jest tak dobrane aby obszar dostępny do renderingu miał wcześniej określone rozmiary. W przykładowym programie obszar renderingu jest stały - zmiana rozmiaru okna (funkcja Reshape) nie modyfikuje jego rozmiarów. Zmiana rozmiaru okna nie powoduje zmiany wielkości ani przemieszczenia rysowanego kwadratu.

Ostatnim etapem tworzenia okna renderingu jest dołączenie funkcji generującej scenę 3D (Display) oraz funkcji wywoływanej przy zmianie rozmiarów okna (Reshape). Realizują to funkcje:
C/C++
void glutDisplayFunc( void( * func )( void ) );
void glutReshapeFunc( void( * func )( int width, int height ) );

Obsługa menu podręcznego

Menu podręczne tworzy funkcja:
C/C++
int glutCreateMenu( void( * func )( int value ) )
której parametrem jest wskaźnik do funkcji obsługi komunikatów menu (w programie funkcja Menu) a zwracana wartość to unikatowy numer menu.

Dodanie kolejnych pozycji do menu podręcznego umożliwia funkcja:
C/C++
void glutAddMenuEntry( char * name, int value )
której parametry to nazwa pozycji menu i numer (unikatowy) przekazywany w przypadku wybrania tej pozycji do funkcji obsługującej komunikaty menu. W tym i dalszych programach unikatowość numerów menu zapewnia zastosowanie typu wyliczeniowego. W pierwszym programie menu ma minimalna zawartość - umożliwia jedynie wyjście z programu. Z uwagi na różnice w kodowaniu polskich znaków w rożnych systemach operacyjnych wywołanie tej funkcji ujęte zostało w bloku instrukcji warunkowych preprocesora:
C/C++
#ifdef WIN32
#else
#endif
Ostatnia operacja przy tworzeniu menu podręcznego jest wywołanie funkcji określającej, który przycisk myszki aktywuje menu:
C/C++
void glutAttachMenu( int button )
Możliwe są następujące wartości parametru button:
  • GLUT_LEFT_BUTTON - lewy przycisk myszki,
  • GLUT_MIDDLE_BUTTON - środkowy przycisk myszki,
  • GLUT_RIGHT_BUTTON - prawy przycisk myszki.

Plik kwadrat1.cpp

Rysunek 1. Okno początkowe programu Kwadrat 1
Rysunek 1. Okno początkowe programu Kwadrat 1

Początkowe okno programu kwadrat1.cpp, którego tekst źródłowy znajduje się poniżej, przedstawia rysunek 1.
C/C++
/*
(c) Janusz Ganczarski (Power)
http://www.januszg.hg.pl
JanuszG(małpeczka)enter.net.pl
*/

#include <GL/glut.h>
#include <stdlib.h>

// funkcja generująca scenę 3D

void Display()
{
    // kolor tła - zawartość bufora koloru
    glClearColor( 1.0, 1.0, 1.0, 1.0 );
   
    // czyszczenie bufora koloru
    glClear( GL_COLOR_BUFFER_BIT );
   
    // kolor kwadratu
    glColor3f( 1.0, 0.0, 0.0 );
   
    // początek definicji wielokąta
    glBegin( GL_POLYGON );
   
    // kolejne wierzchołki wielokąta
    glVertex3f( 0.0, 0.0, 0.0 );
    glVertex3f( 0.0, 1.0, 0.0 );
    glVertex3f( 1.0, 1.0, 0.0 );
    glVertex3f( 1.0, 0.0, 0.0 );
   
    // koniec definicji prymitywu
    glEnd();
   
    // skierowanie poleceń do wykonania
    glFlush();
   
    // zamiana buforów koloru
    glutSwapBuffers();
}

// zmiana wielkości okna

void Reshape( int width, int height )
{
    // generowanie sceny 3D
    Display();
}

// stałe do obsługi menu podręcznego

enum
{
    EXIT // wyjście
};

// obsługa menu podręcznego

void Menu( int value )
{
    switch( value )
    {
        // wyjście
    case EXIT:
        exit( 0 );
    }
}

int main( int argc, char * argv[] )
{
    // inicjalizacja biblioteki GLUT
    glutInit( & argc, argv );
   
    // inicjalizacja bufora ramki
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB );
   
    // rozmiary głównego okna programu
    glutInitWindowSize( 400, 400 );
   
    // utworzenie głównego okna programu
    glutCreateWindow( "Kwadrat 1" );
   
    // dołączenie funkcji generującej scenę 3D
    glutDisplayFunc( Display );
   
    // dołączenie funkcji wywoływanej przy zmianie rozmiaru okna
    glutReshapeFunc( Reshape );
   
    // utworzenie menu podręcznego
    glutCreateMenu( Menu );
   
    // dodatnie pozycji do menu podręcznego
    #ifdef WIN32
   
    glutAddMenuEntry( "Wyjście", EXIT );
    #else
   
    glutAddMenuEntry( "Wyjscie", EXIT );
    #endif
   
    // określenie przycisku myszki obsługującej menu podręczne
    glutAttachMenu( GLUT_RIGHT_BUTTON );
   
    // wprowadzenie programu do obsługi pętli komunikatów
    glutMainLoop();
    return 0;
}
Poprzedni dokument Następny dokument
Podstawy Definiowanie sceny 3D