Karol Zalewski gr. I6Y3S1
Wojskowa Akademia Techniczna
Grafika Komputerowa
Modelowanie brył
1.Treść zadania
Wykorzystując biblioteki OpenGL i GLUT napisać program rysujący stożek w trybie GL_TRIANGLE_STRIP. Program powinien umożliwiać użytkownikowi za pomocą obsługi klawiatury modyfikowanie ilości pionowych podziałów stożka, oraz „wycinanie kawałków ze środka stożka”.
2.Metoda rozwiązania zadania
Zadanie to nie zostało do końca rozwiązane przeze mnie. Zrobiłem dwie pierwsze części zadania, mianowicie narysowałem stożek i umożliwiłem użytkownikowi kontrolowanie ilości pionowych podziałów stożka. Wykonałem to w krokach opisanych w dalszej części sprawozdania. Na początku utworzyłem następujące zmienne globalne:
float pi =3.14;
float podzial = 6;
float kat;
Zmienna „pi” była mi potrzebna przy rysowaniu podstawy jak i ściany bocznej stożka ,a dokładnie przy użyciu funkcji trygonometrycznych sinus i cosinus. Zmiennej o nazwie „podział” użyłem do określenia pionowej liczby podziałów. W dalszej części programu umożliwiłem użytkownikowi modyfikowanie tej zmiennej poprzez obsługę klawiatury. Zmiennej „kat” użyłem jako kąt przy funkcjach trygonometrycznych.
Utworzyłem również stałej o nazwie „wysokość”, która określała wysokość stożka.
Stożek narysowałem w dwóch fazach. W pierwszej fazie narysowałem podstawę stożka używając powyższych zmiennych oraz stałej za pomocą pętli „for”:
for(kat=0;kat<=2*pi;kat+=2*pi/podzial){
glVertex3f(wysokosc*sin(kat),0,wysokosc*cos(kat));
glVertex3f(0,0,0);}
W drugiej fazie narysowałem ścianę boczną stożka. Jak w poprzedniej fazie użyłem również wyżej opisanych zmiennych oraz stałej oraz pętli „for”:
for(kat=0;kat<=2*pi;kat+=2*pi/podzial){
glVertex3f(wysokosc*sin(kat),0,wysokosc*cos(kat));
glVertex3f(0,wysokosc,0);}
3.Wyniki
Niestety nie udało mi się zrealizować wszystkich założeń zadania. Program napisany przeze mnie rysuje stożek oraz daje możliwość modyfikowania ilości podziałów pionowych stożka za pomocą obsługi klawiatury.
Przykład stożka dla 6 podziałów pionowych:
Przykład stożka dla 11 podziałów pionowych:
Przykład stożka dla 18 podziałów pionowych:
4.Kod źródłowy
//////////////////////////////////////////////////////////////////////////////////////////
// Program rysujący stożek. //
//////////////////////////////////////////////////////////////////////////////////////////
#include <GL/glut.h>
#include <cmath>
// Definicja stalych
#define DLUGOSC_BOKU 5.0
#define OBSERWATOR_ODLEGLOSC 20.0
#define OBSERWATOR_OBROT_X 20.0
#define OBSERWATOR_OBROT_Y 20.0
#define OBSERWATOR_FOV_Y 30.0
#define wysokosc 3.0
// Zmienne globalne
double bok = DLUGOSC_BOKU; // Dlugosc boku szescianu
int szerokoscOkna = 800;
int wysokoscOkna = 600;
float pi =3.14;
float podzial = 6;
float kat;
// Prototypy funkcji
void RysujSzescian(double a);
void UstawParametryWidoku(int szer, int wys);
void WyswietlObraz(void);
void ObslugaKlawiatury(unsigned char klawisz, int x, int y);
//////////////////////////////////////////////////////////////////////////////////////////
// Funkcja rysujaca szescian o boku "a" w trybie GL_QUAD_STRIP.
// Srodek szescianu znajduje się w punkcie (0,0,0).
void RysujSzescian(double a)
{
glBegin(GL_TRIANGLE_STRIP);
for(kat=0;kat<=2*pi;kat+=2*pi/podzial){
glVertex3f(wysokosc*sin(kat),0,wysokosc*cos(kat));
glVertex3f(0,0,0);}
glEnd();
glBegin(GL_TRIANGLE_STRIP);
for(kat=0;kat<=2*pi;kat+=2*pi/podzial){
glVertex3f(wysokosc*sin(kat),0,wysokosc*cos(kat));
glVertex3f(0,wysokosc,0);}
glEnd();
}
//////////////////////////////////////////////////////////////////////////////////////////
// Funkcja ustawiajaca parametry rzutu perspektywicznego i rozmiary viewportu. Powinna
// być wywolywana kazdorazowo po zmianie rozmiarow okna programu.
void UstawParametryWidoku(int szer, int wys)
{
// Zapamietanie wielkosci widoku
szerokoscOkna = szer;
wysokoscOkna = wys;
// Ustawienie parametrow viewportu
glViewport(0, 0, szerokoscOkna, wysokoscOkna);
// Przejscie w tryb modyfikacji macierzy rzutowania
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(OBSERWATOR_FOV_Y, (float)szerokoscOkna/(float)wysokoscOkna, 1.0, 1000.0);
}
//////////////////////////////////////////////////////////////////////////////////////////
// Funkcja wyswietlajaca pojedyncza klatke animacji
void WyswietlObraz(void)
{
// Wyczyszczenie bufora koloru i bufora glebokosci
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// Przejscie w tryb modyfikacji macierzy przeksztalcen geometrycznych
glMatrixMode(GL_MODELVIEW);
// Zastapienie aktywnej macierzy macierza jednostkowa
glLoadIdentity();
// Ustalenie polozenia obserwatora
glTranslatef(0, 0, -OBSERWATOR_ODLEGLOSC);
glRotatef(OBSERWATOR_OBROT_X, 1, 0, 0);
glRotatef(OBSERWATOR_OBROT_Y, 0, 1, 0);
// Narysowanie szescianu
RysujSzescian(bok);
// Przelaczenie buforow ramki
glutSwapBuffers();
}
//////////////////////////////////////////////////////////////////////////////////////////
// Funkcja obslugi klawiatury
void ObslugaKlawiatury(unsigned char klawisz, int x, int y)
{
if(klawisz == '+')
bok *= 2.0;
else if (klawisz == '-')
bok /= 2.0;
else if (klawisz == 'q'){
if(podzial<20) podzial += 1.0;}
else if (klawisz == 'a'){
if (podzial>6) podzial -= 1.0;}
else if (klawisz == 27)
exit(0);
}
//////////////////////////////////////////////////////////////////////////////////////////
// Glowna funkcja programu
int main(int argc, char **argv)
{
// Zainicjowanie biblioteki GLUT
glutInit(&argc, argv);
// Ustawienie trybu wyswietlania
glutInitDisplayMode (GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
// Ustawienie polozenia dolenego lewego rogu okna
glutInitWindowPosition(100, 100);
// Ustawienie rozmiarow okna
glutInitWindowSize(szerokoscOkna, wysokoscOkna);
// Utworzenie okna
glutCreateWindow("Szescian");
// Odblokowanie bufora glebokosci
glEnable(GL_DEPTH_TEST);
// Ustawienie wartosci czyszczacej zawartosc bufora glebokosci
glClearDepth(1000.0);
// Ustawienie koloru czyszczenia bufora ramki
glClearColor (0.0f, 0.0f, 0.3f, 0.0f);
// Wlaczenie wyswietlania wielokatow w postaci obrysow (przydatne w celach diagnostycznych).
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// Zarejestrowanie funkcji (callback) odpowiedzialnej za
glutDisplayFunc(WyswietlObraz);
// Zarejestrowanie funkcji (callback) wywolywanej za kazdym razem kiedy
// zmieniane sa rozmiary okna
glutReshapeFunc(UstawParametryWidoku);
// Zarejestrowanie funkcji wykonywanej gdy okno nie obsluguje
// zadnych zadan
glutIdleFunc(WyswietlObraz);
// Zarejestrowanie funkcji obslugi klawiatury
glutKeyboardFunc(ObslugaKlawiatury);
// Obsluga glownej petli programu (wywolywanie zarejestrowanych callbackow
// w odpowiedzi na odbierane zdarzenia lub obsluga stanu bezczynnosci)
glutMainLoop();
return 0;
}