pRoGraMerZ


Forum pRoGraMerZ Strona Główna -> OpenGL -> Podstawy - prymitywy | bryły | transformacje Idź do strony 1, 2  Następny
Napisz nowy temat  Odpowiedz do tematu Zobacz poprzedni temat :: Zobacz następny temat 
Podstawy - prymitywy | bryły | transformacje
PostWysłany: Pon 14:49, 31 Paź 2005
freeman
Administrator

 
Dołączył: 20 Paź 2005
Posty: 9
Przeczytał: 0 tematów

Ostrzeżeń: 0/5





W funkcji render() umieszczamy wszystkie obiekty, które po kolei są renderowane. Korzystając z biblioteki glut mamy do dyspozycji gotowe obiekty. Podmieńmy funkcję Render() z ostatniego programu na podaną poniżej:

void Render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glColor3f(0.0f, 1.0f, 0.0f);
glutWireTeapot(0.2);
glTranslatef( 0.5f, 0.0f, 0.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glutWireSphere( 0.1, 30.0, 30.0);
glColor3f(1.0f, 1.0f, 1.0f);
glutWireCube(0.3);
glTranslatef( -1.0f, 0.0f, 0.0f);
glColor3f(1.0f, 1.0f, 0.0f);
glutWireCone( 0.04, 0.3, 20, 20);
glColor3f(0.0f, 1.0f, 0.0f);
glutWireTorus( 0.03, 0.1, 20, 20);
glPopMatrix();

glutSwapBuffers();
}


Po skompilowaniu ukarze się zestaw obiektów obracających się w przestrzeni dzięki funkcji Idle (a ściśle glRotatef( 0.1f, 1.0f, 1.0f, 1.0f) - pierwszy parametr to wartość kąta o jaki ma się zmienić wektor podany w trzech kolejnych współrzędnych - to obrót układu ). Podobnie funkcja glTranslatef powoduje przesunięcie układu współrzędnych na wskazane miejsce i dopiero po tej operacji rysujemy obiekt w wybranym przez nas miejscu (zmodyfikowanym układzie współ.).
Jednak, aby przy kolejnym wywołaniu Render() renderer rysował znowu od początku układu współrzędnych musimy zresetować układ współrzędnych po narysowaniu każdej klatki. Do zapamiętywania i przywracania stanu układu służą dwie funkcje, odpowiednio: glPushMatrix();
glPopMatrix();
które umieszczamy na początku i końcu funkcji Render(). Dzięki temu nie musimy ręcznie transformować układu do stanu pierwotnego (np. glTranslatef(1.0f,0.0f,0.0f) rysujemy dzbanek i potem musimy przywrócić stan pierwotny układu pisząc glTranslatef(-1.0f,0.0f,0.0f) ).
Przed narysowaniem kolejnego obiektu możemy ustawić jego kolor funkcją glColor3f

Jednak w bibliotece glut jest mało gotowych obiektów, dlatego standardowo w OpenGL rysujemy modele za pomocą prymitywów graficznych - wspomnianych już GL_POINTS, GL_LINES, GL_TRIANGLES, GL_QUADS wpisanych wewnątrz funkcji glBegin() a glEnd(). Za pomocą tych prymitywów możemy tworzyć ściany obiektów, budynków np.
glBegin( GL_QUADS );
glColor3f( 0.0f, 1.0f, 0.0f );
glVertex3f( 0.0f, 0.0f, 0.0f );
glColor3f( 0.0f, 0.0f, 1.0f );
glVertex3f( 0.5f, 0.0f, 0.0f );
glColor3f( 1.0f, 1.0f, 0.0f );
glVertex3f( 0.5f, 0.5f, 0.0f );
glColor3f( 1.0f, 0.0f, 0.0f );
glVertex3f( 0.0f, 0.5f, 0.0f );
glEnd();


Ten proces jest niestety czasochłonny ze względu na liczbę instrukcji dlatego też najlepiej napisać swoją funkcję służącą do rysowania ścian na scenie.

I jeszcze z podstawowych informacji dane na temat typów danych w OpenGL:
OpenGL C++
GLfloat | Float
GLdouble | Double
GLint | Int
GLuint | unsigned int
GLbyte | signed char


Post został pochwalony 0 razy
Zobacz profil autora
PostWysłany: Pon 15:03, 31 Paź 2005
freeman
Administrator

 
Dołączył: 20 Paź 2005
Posty: 9
Przeczytał: 0 tematów

Ostrzeżeń: 0/5





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 [link widoczny dla zalogowanych]


Post został pochwalony 0 razy

Ostatnio zmieniony przez freeman dnia Pon 15:36, 31 Paź 2005, w całości zmieniany 1 raz
Zobacz profil autora
PostWysłany: Pon 15:27, 31 Paź 2005
freeman
Administrator

 
Dołączył: 20 Paź 2005
Posty: 9
Przeczytał: 0 tematów

Ostrzeżeń: 0/5





Jeszcze napiszę wzmiankę na temat kolorów w trybie RGBA.
Używamy go przy ustawianiu koloru sceny w funkcji Init() za pomocą funkcji glClearColor( 0.2f, 0.2f, 0.4f, 1.0f);
Pierwsze trzy parametry to Red, Green, Blue. Jako czwarty parametr podajemy współczynnik przenikalności Alpha, gdzie 1.0f oznacza, że nie ma przezroczystości. Za pomocą RGBA można tworzyć takie efekty jak wodę czy szkło.

W funkcji glTranslatef(1.0f, 0.0f, 0.0f) kolejne parametry to oś pozioma (x), oś pionowa (y), głębia (z).


Post został pochwalony 0 razy
Zobacz profil autora
PostWysłany: Wto 13:24, 27 Lut 2007
Abadmoster9
Poison Headcrab

 
Dołączył: 27 Lut 2007
Posty: 13
Przeczytał: 0 tematów

Ostrzeżeń: 0/5





Nicole Kidman Blowjob!
[link widoczny dla zalogowanych]


Post został pochwalony 0 razy
Zobacz profil autora
PostWysłany: Wto 13:26, 27 Lut 2007
Abadmoster9
Poison Headcrab

 
Dołączył: 27 Lut 2007
Posty: 13
Przeczytał: 0 tematów

Ostrzeżeń: 0/5





Carmen Electra Giving A Head And Taking A Load!
[link widoczny dla zalogowanych]


Post został pochwalony 0 razy
Zobacz profil autora
Podstawy - prymitywy | bryły | transformacje
Forum pRoGraMerZ Strona Główna -> OpenGL
Możesz pisać nowe tematy
Możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Wszystkie czasy w strefie EET (Europa)  
Strona 1 z 2  
Idź do strony 1, 2  Następny
  
  
 Napisz nowy temat  Odpowiedz do tematu  


fora.pl - załóż własne forum dyskusyjne za darmo
Powered by phpBB © 2001-2003 phpBB Group
Theme created by Vjacheslav Trushkin
Regulamin