freeman |
Wysłany: Pon 15:03, 31 Paź 2005 Temat postu: |
|
Przykładowy program rysujący pokój zbudowany z 6 ścian:
#include <GL/gl.h>
#include <GL/glut.h>
#include <stdlib.h>
struct TPointf
{
GLfloat x, y, z; //struktura reprezentująca punkt w 3D
};
GLfloat kat; //zmienna globalna - wartość kąta obrotu
void RysujSciane(const TPointf &p1, const TPointf &p2,
const TPointf &p3, const TPointf &p4)
{
glBegin( GL_QUADS );
glVertex3f( p1.x, p1.y, p1.z );
glVertex3f( p2.x, p2.y, p2.z );
glVertex3f( p3.x, p3.y, p3.z );
glVertex3f( p4.x, p4.y, p4.z );
glEnd();
}
void Keyboard(unsigned char key, int x, int y)
{
if ( key == 27 )
exit( EXIT_SUCCESS );
}
void Init()
{
glClearColor( 0.2f, 0.2f, 0.4f, 1.0f);
glEnable( GL_DEPTH_TEST );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 60.0, 1.0, 0.1, 1000.0 ); //rzutowanie perspektywiczne
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glutFullScreen();
glutKeyboardFunc( Keyboard );
}
void Render()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
kat+=0.1;
glPushMatrix();
glRotatef( kat, 0.0, 1.0, 0.0 ); //obrót pokoju dookoła pionowej osi
TPointf p1 = { -300.0f, 50.0f, -300.0f }, //def 8 wierzchołków pokoju
p2 = { -300.0f, 50.0f, 300.0f },
p3 = { 300.0f, 50.0f, 300.0f },
p4 = { 300.0f, 50.0f, -300.0f },
p5 = { -300.0f, -50.0f, -300.0f },
p6 = { -300.0f, -50.0f, 300.0f },
p7 = { 300.0f, -50.0f, 300.0f },
p8 = { 300.0f, -50.0f, -300.0f };
//rysowanie ścian za pomocą funkcji
glColor3f( 1.0f, 1.0f, 1.0f );
RysujSciane( p1, p2, p6, p5 );
glColor3f( 1.0f, 0.0f, 0.0f );
RysujSciane( p4, p8, p7, p3 );
glColor3f( 0.0f, 1.0f, 0.0f );
RysujSciane( p1, p5, p8, p4 );
glColor3f( 0.0f, 1.0f, 1.0f );
RysujSciane( p3, p7, p6, p2 );
glColor3f( 1.0f, 1.0f, 0.0f );
RysujSciane( p1, p4, p3, p2 );
glColor3f( 0.0f, 0.0f, 1.0f );
RysujSciane( p5, p6, p7, p8 );
glPopMatrix(); //przywrócenie stanu układu zapisanego funkcją Push
glutSwapBuffers();
}
void Idle( void )
{
Render();
}
int main( int argc, char **argv )
{
glutInitDisplayMode( GLUT_DOUBLE );
glutCreateWindow( "Ekspert-OpenGL" );
Init();
glutDisplayFunc( Render );
glutIdleFunc( Idle );
glutMainLoop();
return 0;
}
Powyższy program rysuje 6 ścian funkcją RysujSciane oraz obraca pokój wokół pionowej osi glRotatef( kat, 0.0, 1.0, 0.0 ); o wartość kąta podaną w zmiennej kąt.
Z ważniejszych zmian w programie trzeba zaznaczyć, że zmieniliśmy w funkcji Init() sposób rzutowania z prostokątnego glOrtho na perspektywiczne gluPerspective( 60.0, 1.0, 0.1, 1000.0 ) - powoduje ono, że wraz ze zmianą odległości od obserwatora zmieniają się wymiary renderowanych obiektów.
Funkcja Render() na początku inkrementuje o 1 wartość zmiennej kat, która jest potem wstawiona do funkcji obracającej glRotatef( kat, 0.0, 1.0, 0.0 ). Dzięki temu zaobserwujemy wszystkie ściany pomieszczenia. Później definiujemy punkty od p1 do p8; granice naszego pomieszczenia. Punkty te są parametrami funkcji rysuj ścianę (przekazujemy je przez referencję co pozwala na większą oszczędność pamięci).
UWAGA!!!
I jeszcze badzo ważna sprawa. Podczas rysowania ściany funkcją RysujSciane() musimy przekazać do niej każde 4 punkty w kolejności odwrotnej do kolejności wskazówek zegara (dla przedniej strony ściany)!!! Otóż OpenGL musi jakoś rozpoznawać, która strona prymitywu jest przednia, a która tylna, aby uniknąć rysowania niewidocznych elementów obiektów (test głębi nie roziwiązuje tego problemu dla prymitywów, ale o innych metodach usuwania niewidocznych elementów sceny jeszcze nie będziemy mówić) dlatego za przednią stronę ściany uważamy tą, dla której kolejne wierzchołki są rysowane w odwrotnej kolejności wskazówek zegara i tylko ta strona jest wdoczna.
Po skompilowaniu programu klawiszem F9 powinniśmy zobaczyć obracający się pokój w przestrzeni trójwymiarowej. W razie problemów piszcie na mail'a half-life-2@o2.pl |
|