Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Ćwiczenie oparte o:
- // SphereWorld.cpp
- // OpenGL SuperBible
- // Demonstrates an immersive 3D environment using actors
- // and a camera. This version adds lights and material properties
- // and shadows.
- // Program by Richard S. Wright Jr.
- #include <stdio.h>
- #include "../shared/gltools.h" // OpenGL toolkit
- #include "../shared/math3d.h" // 3D Math Library
- #include "../shared/glframe.h" // Frame class
- #include "../shared/stopwatch.h" // Timer class
- #include <math.h>
- // 3. Dodaj swoje imię i nazwisko do belki tytułowej
- // ...
- const char *appTitle = "Display lists & flat shadow. Autor: Jarosław Mielewski";
- bool displayListOn = false; // wyświetlanie przy pomocy list wyświetlania
- #define NUM_SPHERES 50
- GLFrame spheres[ NUM_SPHERES ];
- GLFrame frameCamera;
- // parametry świateł i materiałów
- GLfloat fLightPos[ 4 ] = { -100.0f, 100.0f, 50.0f, 1.0f }; // źródło światła punktowego
- GLfloat fNoLight[] = { 0.0f, 0.0f, 0.0f, 0.0f };
- GLfloat fLowLight[] = { 0.25f, 0.25f, 0.25f, 1.0f };
- GLfloat fBrightLight[] = { 1.0f, 1.0f, 1.0f, 1.0f };
- GLfloat vLightPos[] = { -80.0f,120.0f,100.0f,0.0f };
- M3DMatrix44f mShadowMatrix;
- GLuint sphereList, groundList, torusList; // identyfikatory list wyświetlania
- void DrawGround( void ); // rysowanie terenu
- //////////////////////////////////////////////////////////////////
- // This function does any needed initialization on the rendering
- // context.
- // tekstury
- const int GROUND_TEXTURE = 0;
- const int TORUS_TEXTURE = 1;
- const int SPHERE_TEXTURE = 2;
- const int TEXTURES_NUM = 3; // liczba wykorzystywanych tekstu
- GLuint textures[ TEXTURES_NUM ]; // identyfikatory tekstur
- void SetupRC()
- {
- const char *textureNames[ TEXTURES_NUM ] =
- {
- "..\\Media\\grass.tga", "..\\Media\\wood.tga", "..\\Media\\orb.tga"
- };
- int iSphere;
- int i;
- glStencilOp( GL_INCR, GL_INCR, GL_INCR ); // zwiększenie zawartości w przypadku nieudanego testu
- glClearStencil( 0 ); // wyczyszczenie bufora szablonu
- glStencilFunc( GL_EQUAL, 0x0, 0x01 ); // ustawienie funkcji porównującej bufora szablonu
- // 5b. Ustawienie parametrów rysowania sceny
- // - ustawienie koloru tła na szary (fLowLight) funkcją glClearColor()
- // - ustawienie nierysowania wewnętrznych ścianek (GL_BACK) funkcją glCullFace()
- // - ustawienie funkcją glFrontFace() przednich ścianek jako podawanych w kierunku
- // przeciwnym do ruchu wskazówek zegara (GL_CCW)
- // - włączenie nierysowania ścianek (GL_CULL_FACE)
- // - włączenie testu głębokości (GL_DEPTH_TEST)
- // - włączenie wieloprzebiegowych tekstur (GL_MULTISAMPLE_ARB)
- glClearColor(fLowLight[0],fLowLight[1],fLowLight[2],fLowLight[3]);
- glCullFace(GL_BACK);
- glFrontFace(GL_CCW);
- glDisable(GL_CULL_FACE);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_MULTISAMPLE_ARB);
- // 5c. Ustawienie parametrów oświetlenia
- // - Włączenie oświetlenia (GL_LIGHTING)
- // - Ustawienie parametrów dla światła GL_LIGHT0 funkcją glLightfv().
- // Składowe GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR ustawiamy odpowiednio
- // na podstawie wektorów: fLowLight, fBrightLight i fBrightLight
- // - Włączenia światła GL_LIGHT0
- glEnable(GL_LIGHTING);
- glLightfv(GL_LIGHT0,GL_AMBIENT,fLowLight);
- glLightfv(GL_LIGHT0,GL_DIFFUSE,fBrightLight);
- glLightfv(GL_LIGHT0,GL_SPECULAR,fBrightLight);
- glEnable(GL_LIGHT0);
- glLightModelfv( GL_LIGHT_MODEL_AMBIENT, fNoLight ); // brak światła ambient sceny
- glLightModeli( GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR );
- // 5d - Włączenie obsługi materiałów (GL_COLOR_MATERIAL)
- // - Ustawianie funkcją glColorMaterial() materiału koloru (GL_AMBIENT_AND_DIFFUSE)
- // ścianek przednich (GL_FRONT) na podstawie bieżącego koloru
- // - Ustawienie przednich (GL_FRONT) parametrów odbłyskowych materiału
- // (GL_SPECULAR, GL_SHININESS) na fBrightLight i 128 funkcjami odpowiednio:
- // glMaterialfv() oraz glMateriali
- glEnable(GL_COLOR_MATERIAL);
- glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
- glMaterialfv(GL_FRONT,GL_SPECULAR,fBrightLight);
- glMaterialfv(GL_FRONT,GL_SHININESS,fBrightLight);
- glMateriali(GL_FRONT,GL_SPECULAR,128);
- glMateriali(GL_FRONT,GL_SHININESS,128);
- // Obliczenie macierzy cienia mShadowMatrix
- M3DVector3f vPoints[ 3 ] =
- { // płaszczyzna y = -0.4f
- { 0.0f, -0.4f, 0.0f }, { 10.0f, -0.4f, 0.0f }, { 5.0f, -0.4f, -5.0f }
- };
- M3DVector4f pPlane;
- // 40. Wyznaczenie równania płaszczyzny pPlane na podstawie jej 3 punktów (vPoints[])
- // Użyj funkcji bibliotecznej m3dGetPlaneEquation( plane, point1, point2, point3 )
- // ...
- // 41. Obliczenie w mCubeTransform macierzy rzutowania cienia na płaszczyźnie
- // Użyj funkcji m3dMakePlanarShadowMatrix() podając jako parametry macierz
- // cienia, równanie płaszczyzny oraz pozycję światła fLightPos
- // ...
- // 18. Ustawienie losowych współrzędnych X oraz Z dla wszystkich
- // NUM_SPHERES sfer (spheres[]). Współrzędne X i Z mają mieć wartość losową
- // z zakresu -20 do 20 z krokiem 0.1, a współrzędna y ma mieć stałą wartość 0.0
- // Do ustawienia współrzędnych należy użyć metody SetOrigin( x, y, z )
- // ...
- for ( iSphere = 0; iSphere < NUM_SPHERES; iSphere++ )
- {
- spheres[ iSphere ].SetOrigin( ( (float)( ( rand() % 400 ) - 200) * 0.1f ), 0.0, (float)( ( rand() % 400 ) - 200 ) * 0.1f );
- }
- // 23. Włączenie przetwarzania tektur dwuwymiarowych (GL_TEXTURE_2D)
- // ...
- // 24. Ustawienie dla tekstur (GL_TEXTURE_ENV) trybu 'funkcji tekstury' (GL_TEXTURE_ENV_MODE)
- // na mnożenie kolorów (GL_MODULATE). Użyj funkcji glTexEnvi()
- // ...
- // 25. Przydzielenie identyfikatorów dla TEXTURES_NUM tekstur
- // Użyj funkcji glGenTextures() zapisując identyfikatory w tabeli textures
- // ...
- // 26. W PĘTLI dla KAŻDEJ tekstury
- // ...
- {
- GLbyte *pBytes;
- GLint iWidth, iHeight, iComponents;
- GLenum eFormat;
- // 27. Załaduj teksturę funkcją gltLoadTGA( textureNames[ i ], &nWidth, &nHeight, &iComponents, &eformat );
- // PODSTAWIAJĄC wynik do pBytes
- // ...
- // 28. Powiąż teksturę (GL_TEXTURE_2D) z odpowiednim identyfikatorem
- // funkcją glBindTexture()
- // ...
- // 29. Zbudowanie mipmap 2D (GL_TEXTURE_2D) funkcją gluBuild2DMipmaps( rodzaj tesktury, iComponents,
- // iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pBytes )
- // ...
- // 30. Zwolnij pamięć tekstur free( pBytes );
- // ...
- // 50. Ustaw parametry filtrowania (GL_TEXTURE_MIN_FILTER, GL_TEXTURE_MAG_FILTER)
- // i kafelkowania (GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T) dla tekstur dwuwymiarowych (GL_TEXTURE_2D)
- // kolejnymi wywołaniami fukcji glTexParameteri()
- // filtrowanie liniowe przy powiększeniu (GL_LINEAR) i zmniejszeniu (GL_LINEAR_MIPMAP_LINEAR)
- // zawijania (GL_CLAMP_TO_EDGE)
- // ..
- }
- // 33. Przydzielenie funkcją glGenLists() identyfikatorów dla list:
- // groundList, sphereList, torusList
- // ...
- // 34. Zdefiniowanie listy wyświetlania dla sfery
- // - rozpoczęcie funkcją glNewList() dla sphereList z parametrem kompilacji (GL_COMPILE)
- // - narysowanie sfery funkcją gltDrawSphere() - parametry jak w DrawInhabitants()
- // - zakończenie funkcją glEndList()
- // ...
- // 35. Zdefiniowanie listy wyświetlania dla torusa - parametry jak w DrawInhabitants()
- // ...
- // 36. Zdefiniowanie listy wyświetlania dla 'podłoża' - funkcja DrawGround()
- // ...
- }
- ////////////////////////////////////////////////////////////////////////
- void ShutdownRC( void )
- { // zwolnienie zaalokowanych zasobów
- // 32. Zwolnienie TEXTURES_NUM tekstur funkcją glDeleteTextures()
- // ...
- // 37. Zwolnienie 3 list wyświetlania funkcją glDeleteLists()
- // ...
- }
- ///////////////////////////////////////////////////////////
- // Draw the ground as a series of triangle strips
- void DrawGround( void )
- { // rysuje kwadratowy teren wykorzystując paski trójkątów
- GLfloat fExtent = 20.0f; // połowa boku kwadratu podłoża (odległość od środka do jego boków)
- GLfloat fStep = 1.0f; // krok wyznaczający wielkość trójkątów
- GLfloat y = -0.4f; // wysokość terenu
- GLint iStrip; // zmienna iterująca w poziomie
- GLint iRun; // zmienna iterująca w pionie
- GLfloat s = 0.0f; // pozioma współrzędna tekstury
- GLfloat t = 0.0f; // pionowa współrzędna tekstury
- GLfloat texStep = 1.0f / ( fExtent * 0.075f ); // krok tekstury
- // 32b. Ustawienie tektury SPHERE_TEXTURE jako aktualnej tekstury dwuwymiarowej
- // (GL_TEXTURE_2D) funkcją glBindTexture()
- // Ustawienie kafelkowania GL_TEXTURE_WRAP_S i GL_TEXTURE_WRAP_T na powtarzanie
- // wzoru (GL_REPEAT) funkcją glTexParameterf()
- // ...
- // 16. Narysowanie poziomego, kwadratowego podłoża o rozciągłości:
- // - w kierunku X (iStrip) od -fExtent do fExtent z krokiem fStep
- // - w kierunku Z (iRun) od -fExtent do fExtent z krokiem fStep
- // Krok dla tekstury wynosi texStep
- // Paski podajemy po DWA (2) wierzchołki na raz (sąsiadujące wzdłuż osi X)
- // Dla każdego wierzchołka podajemy:
- // - normalną zwróconą do góry (glNormal3f())
- // - współrzędne tekstury glTexCoord2f())
- // - współrzędne glVertex3f()
- for(iStrip = -fExtent; iStrip <= fExtent; iStrip+=fStep)
- {
- t = 0.0f;
- glBegin(GL_TRIANGLE_STRIP);
- for(iRun = -fExtent; iRun <= fExtent; iRun+=fStep)
- {
- glTexCoord2f(s,t);
- glNormal3f(0.0f, 1.0f, 0.0f);
- glVertex3f(iStrip,y,iRun);
- glTexCoord2f(s,t);
- glNormal3f(0.0f, 1.0f, 0.0f);
- glVertex3f(iStrip+fStep,y,iRun);
- t+= fStep;
- }
- glEnd();
- s+=fStep;
- }
- /* for (iStrip = - fExtent; iStrip<= fExtent; iStrip=iStrip+fStep)
- {
- t = 0.0f;
- glBegin(GL_TRIANGLE_STRIP);
- for (iRun=-fExtent;iRun<=fExtent;iRun+=fStep)
- {
- glNormal3f(0.0f,1.0f,0.0f);
- glTexCoord2f( s,t);
- glVertex3f(iStrip,y,iRun);
- glNormal3f(0.0f,1.0f,0.0f);
- glTexCoord2f(s+texStep,t);
- glVertex3f(iStrip+fStep,y,iRun);
- t+=texStep;
- }
- glEnd();
- s+=texStep;
- }*/
- }
- ///////////////////////////////////////////////////////////////////////
- // Draw random inhabitants and the rotating torus/sphere duo
- void DrawInhabitants( GLint nShadow )
- { // nShadow == 1 - rysowanie cieni, nShadow == 0 - rysowanie obieków
- static GLfloat yRot = 0.0f; // kąt obrotu
- GLint i;
- if ( nShadow == 0 )
- {
- yRot += 0.5f; // zwiększenie kąta obrotu kuli i torusa
- glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); // biały 'podkład' pod teksturę obiektów
- }
- // 43. ustawienie czarnego koloru rysowania jeżeli nShadow == 1
- // ...
- // 32b. Ustawienie tektury SPHERE_TEXTURE jako aktualnej tekstury dwuwymiarowej
- // (GL_TEXTURE_2D) funkcją glBindTexture()
- // ...
- glBindTexture( GL_TEXTURE_2D, textures[ SPHERE_TEXTURE ] );
- // 19. Narysowanie losowych NUM_SPHERES sfer
- // Przed narysowaniem sfery należy zachować aktualną wartość macierzy widoku modelu
- // oraz wykonać przesunięcie współrzędnych metodą ApplyActorTransform()
- // Do narysowania sfery o promieniu 0.1 należy użyć funkcji gltDrawSphere() z dokładnością 40
- // Po narysowaniu sfery należy odtworzyć aktualną wartość macierzy widoku modelu
- glPushMatrix();
- glTranslatef( 0.0f, 0.1f, -2.5f );
- applyact
- // 20. Narysowanie sfery obracającej się wokół torusa
- // - zachowanie macierzy widoku modelu
- // - obrót wokół osi Y o kąt równy 2*yRots
- // - przesunięcie o 1 wzdłuż osi X
- // - odtworzenie macierzy widoku modelu
- // ...
- // 32b. Ustawienie tektury TORUS_TEXTURE jako aktualnej tekstury dwuwymiarowej
- // (GL_TEXTURE_2D) funkcją glBindTexture()
- // ...
- // 21. Narysowanie obracającego się torusa
- // - ustawienie odbłyskowych własności (GL_SPECULAR) materiału dla
- // przedniej ścianki (GL_FRONT)na kolor fBrightLight[] funkcją
- // glMaterialfv
- // - obrót wokół osi Y o kąt yRot
- // - narysowanie torusa funkcją gltDrawTorus() z promieniami
- // 0.35 i 0.15 oraz z dokładnością 40
- // - odtworzenie macierzy widoku modelu
- // - usunięcie odbłyskowych własności materiału używając koloru fNoLight
- // ...
- }
- void RenderScene( void )
- { // rysowanie sceny
- static int iFrames = 0; // licznik ramek
- static CStopWatch frameTimer; // timer
- // 5. Wyczyszczenie okna bieżącym kolorem czyszczenia
- // używamy funkcji glClear czyszcząc bufor obrazu (GL_COLOR_BUFFER_BIT),
- // bufor głębokości (GL_DEPTH_BUFFER_BIT) oraz bufor szablonu
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- glPushMatrix();
- frameCamera.ApplyCameraTransform();
- // 14. Ustawienie pozycji (GL_POSITION) światła GL_LIGHT0 na
- // wektor vLightPos funkcją glLightfv()
- glLightfv(GL_LIGHT0,GL_POSITION,fLightPos);
- glColor3f( 1.0f, 1.0f, 1.0f );
- // 17. Narysowanie terenu
- //
- DrawGround();
- // 42. Narysowanie cieni
- // -wyłączenie testu głębokości (GL_DEPTH_TEST), oświetlenia (GL_LIGHTING),
- // teksturowania (GL_TEXTURE_2D)
- // - włączenie obsługi przezroczystości (GL_BLEND) i bufora szablonu (GL_STENCIL_TEST)
- // - ustawienie funkcji przezroczystości glBlendFunc() na GL_SRC_ALPHA i GL_ONE_MINUS_SRC_ALPHA
- // - zapamiętanie bieżacej macierzy przekształceń
- // - przemnożenie aktualnej macierzy przekształceń przez macierz cienia mShadowMatrix
- // funkcją glMultMatrixf()
- // - narysowanie sfer i torusa. UWAGA na parametr!
- // odtworzenie macierzy przekształceń
- // odtworzenie parametrów stanu
- // ...
- // 22. Narysowanie kul i torusa (bez cieni)
- // ...
- glPopMatrix(); // odtworzenie macierzy przekształceń
- glutSwapBuffers(); // wysłanie komend renderowania i przełączenie buforów
- iFrames++; // zwiększenie licznika ramek
- if ( iFrames == 100 )
- { // obliczenie częstotliwości wyświetlania
- float fps;
- char cBuffer[ 200 ];
- fps = 100.0f / frameTimer.GetElapsedSeconds();
- if ( displayListOn )
- sprintf( cBuffer, "%s [Display Lists] %.1f fps", appTitle, fps );
- else
- sprintf( cBuffer, "%s [Tryb bezpośredni] %.1f fps", appTitle, fps );
- glutSetWindowTitle( cBuffer );
- frameTimer.Reset();
- iFrames = 0;
- }
- }
- void KeyPressFunc( unsigned char key, int x, int y )
- { // obsługa przycisków
- switch ( key )
- {
- case ' ': // spacja
- // Naprzemienne włączenie użycia displayList po naciśnięciu spacji
- displayListOn = !displayListOn;
- break;
- case 27: // ESC
- // 4. Zamknięcie okna funkcją: void glutDestroyWindow( int window )
- // id okna należy pobrać funkcją: int glutGetWindow( void )
- glutDestroyWindow( glutGetWindow() );
- break;
- }
- glutPostRedisplay(); // odświeżenie okna
- }
- void SpecialKeys( int key, int x, int y )
- { // obsługa klawiszy specjalnych
- switch ( key )
- {
- case GLUT_KEY_UP:
- frameCamera.MoveForward( 0.1f );
- break;
- case GLUT_KEY_DOWN:
- frameCamera.MoveForward( -0.1f );
- break;
- case GLUT_KEY_LEFT:
- frameCamera.RotateLocalY( 0.01f );
- break;
- case GLUT_KEY_RIGHT:
- frameCamera.RotateLocalY( -0.01f );
- break;
- }
- glutPostRedisplay(); // odświeżenie okna
- }
- ///////////////////////////////////////////////////////////
- void TimerFunction( int value )
- { // wywoływana przez GLUT w trybie idle
- glutPostRedisplay();
- glutTimerFunc( 3, TimerFunction, 1 );
- }
- void ChangeSize( int w, int h )
- {
- // 6. Zabezpieczenie, aby rozmiary okna Viewport nie spadły poniżej 1
- if(w<1)
- w=1;
- if(h<1)
- h=1;
- // 7. Ustawienie okna Viewport na całą szerokość okna Window
- // Należy skorzystać z funkcji glViewport( .. )
- glViewport(0,0,w,h);
- GLfloat fAspect; // proporcje okna
- // 8. Wyznaczenie proporcji okna (w/h).
- // !!! UWAGA na ograniczenia dzielenia całkowitoliczbowego !!!
- fAspect = ((float) w) / ((float) h);
- // 9. Ustawienie macierzy rzutowania (GL_PROJECTION) jako aktualnej macierzy
- // funkcją glMatrixMode()
- glMatrixMode(GL_PROJECTION);
- // 10. Ustawienie macierzy rzutowania jako macierzy jednostkowej funkcją
- glLoadIdentity();
- // ...
- // 11. Ustawienie rzutowania perspektywicznego funkcją gluPerspective()
- // kąt widzenia = 35 stopni, odległość od bliższej płaszczyzny obcinania = 1
- // odległość od dalszej płaszczyzny obcinania = 50
- gluPerspective(35.0f,fAspect,1.0f,50.0f);
- // 12. Ustawienie macierzy widoku modelu (GL_MODELVIEW) jako aktualnej macierzy
- glMatrixMode(GL_MODELVIEW);
- // 13. Ustawienie macierzy widoku modelu jako macierzy jednostkowej
- glLoadIdentity();
- }
- int main( int argc, char* argv[] )
- {
- glutInit( &argc, argv );
- glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STENCIL );
- glutInitWindowSize( 800, 600 );
- glutCreateWindow( appTitle ); // utworzenie okna
- glutReshapeFunc( ChangeSize );
- glutDisplayFunc( RenderScene );
- glutKeyboardFunc( KeyPressFunc ); // funkcja obsługi klawiatury
- glutSpecialFunc( SpecialKeys );
- SetupRC();
- glutTimerFunc( 33, TimerFunction, 1 );
- glutMainLoop();
- ShutdownRC();
- return 0;
- }
Add Comment
Please, Sign In to add comment