sprawozdanie2, Zarządzanie i inżynieria produkcji, Semestr 7, Maszyny i urządzenia technologiczne


Wojskowa Akademia Techniczna

Laboratorium Grafiki Komputerowej

SPRAWOZDANIE

Osoba Prowadząca: dr inż. Marek Salamon

Wykonał: Stanisław Berk

Grupa szkoleniowa: C02A

Data wykonania sprawozdania: 2005-06-04

Ocena sprawozdania: .............................................

  1. Numer i treść zadania

Modelowanie oświetlenia

Zadanie 19

Wykorzystując biblioteki OpenGL i GLUT napisać program przedstawiający perspektywiczny obraz obiektu o następujących parametrach:

1. Typ obiektu: sfera o zmiennej parzystej liczbie podziałów pionowych i poziomych,

2. Właściwości materiału nr l: fioletowy błyszczący (widziany w białym świetle),

3. Właściwości materiału nr 2: żółty matowy (widziany w białym świetle),

4. Sposób przyporządkowania materiałów do obiektu zgodnie ze wzorem: szachownica z uwzględnieniem podziałów pionowych i poziomych.

Obiekt należy oświetlić dwoma źródłami światła o następujących parametrach:

Źródło nr 1:

- typ: reflektor (ang. spot),

- kolor: biały,

- natężenie: l,

- kąt odcięcia: 30°,

- położenie: zmienne po orbicie kołowej o środku w punkcie S(0,0,0) z możliwością interaktywnej zmiany następujących parametrów:

o promienia orbity,

o kąta nachylenia orbity do osi OX,

o kąta nachylenia orbity do osi OZ,

- kierunek świecenia: na obiekt.

Źródło nr 2:

- typ: kierunkowe,

- kolor: zielony,

- natężenie: 0.7,

- położenie: stałe w punkcie P(10.10, 10) układu współrzędnych obserwatora.

- kierunek świecenia: na obiekt.

Program powinien umożliwiać:

a) interaktywne, niezależne włączanie i wyłączanie źródeł światła;

b) interaktywną zmianę liczby podziałów pionowych i poziomych bryły;

c) interaktywną zmianę położenia obserwatora poprzez podanie następujących parametrów:

- odległości obserwatora od środka układu współrzędnych sceny;

- wysokości względem płaszczyzny XZ;

- kąta obrotu wokół osi OY w zakresie [0°, 360°] z krokiem l°.

Oświetlony obiekt powinien zawsze znajdować się w centralnej części okna

  1. Realizacja zadania laboratoryjnego

void UstawDomyslneWartosciParametrow(void)

{

// Tablica parametrow materialu

GLfloat param_materialu[6][4] = {

{0.2, 0.2, 0.2, 1.0}, // [0] wspolczynnik odbicia swiatla otoczenia

{0.5, 0.0, 1.0, 1.0}, // [1] wspolczynnik odbicia swiatla rozproszonego

{0.4, 0.4, 0.4, 1.0}, // [2] wspolczynnik odbicia swiatla lustrzanego

{0.1, 0.0, 0.1, 0.0}, // [3] polysk

{0.0, 0.0, 0.0, 1.0}}; // [4] kolor swiatla emitowanego

// Tablica parametrow materialu2

GLfloat param_materialu2[6][4] = {

{1.0, 1.0, 0.0, 1.0}, // [0] wspolczynnik odbicia swiatla otoczenia

{1.0, 1.0, 0.0, 1.0}, // [1] wspolczynnik odbicia swiatla rozproszonego

{0.0, 0.0, 0.0, 1.0}, // [2] wspolczynnik odbicia swiatla lustrzanego

{0.0, 0.0, 0.0, 0.0}, // [3] polysk

{0.0, 0.0, 0.0, 1.0}}; // [4] kolor swiatla emitowanego

// Tablica parametrow swiatla

GLfloat param_swiatla[10][4] = {

{0.0, 0.0, 0.0, 1.0}, // [0] otoczenie

{1.0, 1.0, 1.0, 1.0}, // [1] rozproszenie

{0.0, 1.0, 0.0, 1.0}, // [2] lustrzane

{10.0, 10.0, 10.0, 0.0}, // [3] polozenie

{0.0, 0.0, -1.0, 0.0}, // [4] kierunek swiecenia

{0.0, 0.0, 0.0, 0.0}, // [5] tlumienie katowe swiatla

{180.0, 0.0, 0.0, 0.0},// [6] kat odciecia swiatla

{0.7, 0.0, 0.0, 0.0}, // [7] stale tlumienie

{0.0, 0.0, 0.0, 0.0}, // [8] tlumienie liniowe

{0.0, 0.0, 0.0, 0.0}}; // [9] tlumienie kwadratowe

// Tablica parametrow swiatla2

GLfloat param_swiatla2[10][4] = {

{0.0, 0.0, 0.0, 1.0}, // [0] otoczenie

{1.0, 1.0, 1.0, 1.0}, // [1] rozproszenie

{1.0, 1.0, 1.0, 1.0}, // [2] lustrzane

{0.0, 0.0, 0.0, 0.0}, // [3] polozenie

{-1.0, 0.0, 0.0, 0.0}, // [4] kierunek swiecenia

{100.0, 0.0, 0.0, 0.0}, // [5] tlumienie katowe swiatla

{30.0, 0.0, 0.0, 0.0},// [6] kat odciecia swiatla

{1.0, 0.0, 0.0, 0.0}, // [7] stale tlumienie

{0.0, 0.0, 0.0, 0.0}, // [8] tlumienie liniowe

{0.0, 0.0, 0.0, 0.0}}; // [9] tlumienie kwadratowe

// Skopiowanie zawartosci tablic param_* do tablic globalnych

memcpy(material, param_materialu, LPOZ_MENU_MATERIALU*4*sizeof(GLfloat));

memcpy(swiatlo, param_swiatla, LPOZ_MENU_SWIATLA*4*sizeof(GLfloat));

memcpy(material2, param_materialu2, LPOZ_MENU_MATERIALU*4*sizeof(GLfloat));

memcpy(swiatlo2, param_swiatla2, LPOZ_MENU_SWIATLA*4*sizeof(GLfloat));

// Parametry walca

lPionowych = 18; // Liczba podzialow pionowych

lPoziomych = 10; // Liczba podzialow poziomych

promien = 1.0; // Promien sfery

//wysokosc = 0.0; // Wysokosc walca

// Pozostale parametry

sIndeks = 0; // Wybrana pozycja w tablicy parametrow swiatla

mIndeks = 0; // Wybrana pozycja w tablicy parametrow materialu

menu = ID_MENU_SWIATLA;

glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);

}

Na początku tej procedury zadeklarowane są dwie tablice (po jednej dla dwóch różnych materiałów) zawierające parametry materiału: współczynnik odbicia światła otoczenia, współczynnik odbicia światła rozproszonego, współczynnik odbicia światła lustrzanego, połysk oraz kolor światła emitowanego.

Następne dwie tablice określają parametry dla obu świateł, oznaczają one kolejno: ustawienie koloru otaczającego światła(cztery składowe RGBA), określenie składowej światła rozproszonego (RGBA), określenie składowej światła odbłysków (RGBA), pozycję reflektora (pierwsze trzy elementy tego wiersza tablicy określają położenie źródła światła. Jeżeli czwarty element ma wartość 1.0 to światło rzeczywiście znajduje się we wskazanym miejscu. W przeciwnym razie źródło światła jest kierunkowe i promienie są równoległe), określenie kierunku świecenia (trzy parametry), ustawienie gęstości światła (przyjmuje wartość od 0 - 128, gdzie 0 to światło najgęstsze), ustawienie rozwartości stożka światła, określenie stałego zanikania światła, liniowe zanikanie światła, nieliniowe (kwadratowe) zanikanie światła.

Kolejnym krokiem jest skopiowanie zawartości tych tablic, przy pomocy funkcji memcpy, do wcześniej zadeklarowanych tablic globalnych:

// Tablica parametrow swiatla

GLfloat swiatlo[10][4];

GLfloat swiatlo2[10][4];

// Tablica parametrow materialu z jakiego wykonana jest sfera

GLfloat material[6][4];

GLfloat material2[6][4];

Później zdefiniowane zostają wyjściowe parametry sfery czyli: liczba podziałów pionowych, liczba podziałów poziomych, oraz promień. Oraz indeksy tablicy dla wybranych pozycji w tablicy parametrów lub światła.

void WlaczOswietlenie(int z, int q)

{

int os1=z;

int os2=q;

// Odblokowanie oswietlenia

glEnable(GL_LIGHTING);

// Odblokowanie zerowego zrodla swiatla

if(os1==1)

glEnable(GL_LIGHT0);

else

glDisable(GL_LIGHT0);

if(os2==1)

glEnable(GL_LIGHT1);

else

glDisable(GL_LIGHT1);

obrot=(obrot+5)%360;

pozycja[0]=cos(DEG2RAD(obrot));

pozycja[1]=wysokosc;

pozycja[2]=sin(DEG2RAD(obrot));

pozycja[3]=0.0;

kierunek[0]=-cos(DEG2RAD(obrot));

kierunek[1]=-wysokosc;

kierunek[2]=-sin(DEG2RAD(obrot));

kierunek[3]=0.0;

// Inicjowanie zrodla swiatla

glLightfv(GL_LIGHT0, GL_AMBIENT, swiatlo[0]);

glLightfv(GL_LIGHT0, GL_DIFFUSE, swiatlo[1]);

glLightfv(GL_LIGHT0, GL_SPECULAR, swiatlo[2]);

glLightfv(GL_LIGHT0, GL_POSITION, swiatlo[3]);

glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, swiatlo[4]);

glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, swiatlo[5][0]);

glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, swiatlo[6][0]);

glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, swiatlo[7][0]);

glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, swiatlo[8][0]);

glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, swiatlo[9][0]);

// Inicjowanie zrodla swiatla2

glLightfv(GL_LIGHT1, GL_AMBIENT, swiatlo2[0]);

glLightfv(GL_LIGHT1, GL_DIFFUSE, swiatlo2[1]);

glLightfv(GL_LIGHT1, GL_SPECULAR, swiatlo2[2]);

glLightfv(GL_LIGHT1, GL_POSITION, pozycja);

glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, kierunek);

glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, swiatlo2[5][0]);

glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, swiatlo2[6][0]);

glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, swiatlo2[7][0]);

glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, swiatlo2[8][0]);

glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, swiatlo2[9][0]);

}

Funkcja posiada dwa parametry wejściowe z i q przy pomocy których określają czy odpowiednio pierwsze i drugie źródło światła jest włączone czy też nie. Odbywa się to za pomocą dwóch funkcji: glEnable (włączone), glDisable (wyłączone). Przed włączaniem i wyłączaniem źródeł odblokowuje oświetlenie funkcją: glEnable(GL_LIGHTING).

Ponieważ drugie źródło światła ma zmieniać położenie po orbicie kołowej, dlatego jego położenie oraz kierunek świecenia zdefiniowane są przy pomocy funkcji trygonometrycznych.

Funkcja glLightf() służy do ustalania parametrów dla danego światła. Jako pierwszy argument przyjmuje numer światła. Maksymalna ilość świateł, jakie można włączyć jednocześnie wynosi 8. Przy pomocy tej funkcji inicjalizowane są kolejne źródła światła. Drugi argument określa jeden z parametrów światła (ich przeznaczenie zostało zdefiniowane w wyżej opisywanej funkcji przy opisie tablic parametrów dla światła). Trzeci argument to konkretne wartości pobrane z tablic parametrów dla światła).

void DefiniujMaterial(int w)

{

if (w==0)

{

glMaterialfv(GL_FRONT, GL_AMBIENT, material[0]);

glMaterialfv(GL_FRONT, GL_DIFFUSE, material[1]);

glMaterialfv(GL_FRONT, GL_SPECULAR, material[2]);

glMaterialfv(GL_FRONT, GL_SHININESS, material[3]);

glMaterialfv(GL_FRONT, GL_EMISSION, material[4]);

}

if (w==1)

{

glMaterialfv(GL_FRONT, GL_AMBIENT, material2[0]);

glMaterialfv(GL_FRONT, GL_DIFFUSE, material2[1]);

glMaterialfv(GL_FRONT, GL_SPECULAR, material2[2]);

glMaterialfv(GL_FRONT, GL_SHININESS, material2[3]);

glMaterialfv(GL_FRONT, GL_EMISSION, material2[4]);

}

}

Funkcja przyjmuje jeden parametr wejściowy, przy pomocy którego, określam który z dwóch rodzajów materiału ma zostać użyty. Użycie materiału obowiązuje tylko do ścian skierowanych przodem do obserwatora. Funkcja glMaterialfv() umożliwia inicjalizacje właściwości materiału na podstawie zapisanych w tablicy materiał parametrów. Pierwszy argument określa która ściana bryły nas interesuje. Drugi argument określa jeden z parametrów materiału (ich przeznaczenie zostało zdefiniowane podczas opisywania pierwszej funkcji - opis tablic parametrów dla materiału).

void RysujWalec(double r, int nv, int nh)

{

double dH, dAlfa, dBeta;

int i,j;

dAlfa = 180/(double)nv;

dBeta = 360/(double)nh;

k=0;

for (i=0;i*dAlfa<=180;i++)

{

for(j=0;j*dBeta<=360;j++)

{

if(k==0)

k=1;

else

k=0;

DefiniujMaterial(k);

glBegin(GL_QUAD_STRIP);

glNormal3f(cos(DEG2RAD(i*dAlfa))*cos(DEG2RAD(j*dBeta)),sin(DEG2RAD(i*dAlfa))*cos(DEG2RAD(j*dBeta)),sin(DEG2RAD(j*dBeta)));

glVertex3f(r*cos(DEG2RAD(i*dAlfa))*cos(DEG2RAD(j*dBeta)),r*sin(DEG2RAD(i*dAlfa))*cos(DEG2RAD(j*dBeta)),r*sin(DEG2RAD(j*dBeta)));

glNormal3f(cos(DEG2RAD(i*dAlfa))*cos(DEG2RAD((j+1)*dBeta)),sin(DEG2RAD(i*dAlfa))*cos(DEG2RAD((j+1)*dBeta)),sin(DEG2RAD((j+1)*dBeta)));

glVertex3f(r*cos(DEG2RAD(i*dAlfa))*cos(DEG2RAD((j+1)*dBeta)),r*sin(DEG2RAD(i*dAlfa))*cos(DEG2RAD((j+1)*dBeta)),r*sin(DEG2RAD((j+1)*dBeta)));

glNormal3f(cos(DEG2RAD((i+1)*dAlfa))*cos(DEG2RAD(j*dBeta)),sin(DEG2RAD((i+1)*dAlfa))*cos(DEG2RAD(j*dBeta)),sin(DEG2RAD(j*dBeta)));

glVertex3f(r*cos(DEG2RAD((i+1)*dAlfa))*cos(DEG2RAD(j*dBeta)),r*sin(DEG2RAD((i+1)*dAlfa))*cos(DEG2RAD(j*dBeta)),r*sin(DEG2RAD(j*dBeta)));

glNormal3f(cos(DEG2RAD((i+1)*dAlfa))*cos(DEG2RAD((j+1)*dBeta)),sin(DEG2RAD((i+1)*dAlfa))*cos(DEG2RAD((j+1)*dBeta)),sin(DEG2RAD((j+1)*dBeta)));

glVertex3f(r*cos(DEG2RAD((i+1)*dAlfa))*cos(DEG2RAD((j+1)*dBeta)),r*sin(DEG2RAD((i+1)*dAlfa))*cos(DEG2RAD((j+1)*dBeta)),r*sin(DEG2RAD((j+1)*dBeta)));

glEnd();

}

}

}

Funkcja przyjmuje trzy parametry: r - promień sfery, nv - liczba podziałów pionowych, nh - liczba podziałów poziomych. Następnie, przy pomocy technik poznanych na pierwszych ćwiczeniach laboratoryjnych, rysuje sferę w trybie graficznym GL_QUAD_STRIP. W wewnętrznej pętli umieszczona została dodatkowo zmienna k, która przyjmuje wartości 0 lub 1 i zmienia się w każdym obiegu tej pętli. Zmienna ta służy jako argument funkcji DefiniujMaterial(k) (opisana została powyżej), która również znajduje się w wewnętrznej pętli.

Aby umożliwić interaktywną zmianę położenia obserwatora dokonałem modyfikacji wewnątrz procedury void WyswietlObraz(void). W funkcji glTranslatef(0, 0, odl_obs), która określa położenie obserwatora, współrzędna „z” została określona za pomocą zmiennej odl_obs. Zaś funkcja glRotatef(obrot_y, 0, 1, 0), gdzie kąt obrotu został zadeklarowany jako zmienna, umożliwia obrót obserwatora wokół obiektu.

Po dodaniu w funkcji void ObslugaKlawiatury(unsigned char klawisz, int x, int y) obsługi dodatkowych klawiszy, które zmieniają wartości różnych wyżej wymienionych zmiennych otrzymałem następujące efekty:

kula z materiałami ułożonymi włączone źródło nr 1 -

w szachownice reflektor

0x01 graphic
0x01 graphic

włączone źródło nr2 - włączone źródło nr 1 i nr 2

kierunkowe

0x01 graphic
0x01 graphic

  1. Kod całego programu

#include <math.h>

#include <string.h>

#include <stdio.h>

#include <GL/glut.h>

// Definicja stalych

#define LPOZ_MAX 100

#define LPOZ_MIN 3

#define LPION_MAX 100

#define LPION_MIN 3

#define R_MAX 10.0

#define WYS_MAX 5.0

#define KROK_FLOAT 0.1

#define X_OFFSET_SWIATLO 10

#define Y_OFFSET_SWIATLO 120

#define X_OFFSET_MAT 10

#define Y_OFFSET_MAT 220

#define X_OFFSET_OBIEKT 10

#define Y_OFFSET_OBIEKT 300

#define ID_MENU_SWIATLA 0

#define ID_MENU_MATERIALU 1

#define LPOZ_MENU_SWIATLA 10

#define LPOZ_MENU_MATERIALU 5

#define M_PI 3.14159

#define OBSERWATOR_ODLEGLOSC 20.0

#define OBSERWATOR_OBROT_X 0.0

#define OBSERWATOR_OBROT_Y 0.0

#define OBSERWATOR_FOV_Y 40.0

// Makro przeliczajace stopnie na radiany

#define DEG2RAD(x) ((float)(x)*M_PI/180.0)

// Zmienne globalne

double kat = 0.0; // Kat obrotu obserwatora wokol osi OY [stopnie]

int lPionowych; // Liczba podzialow pionowych

int lPoziomych; // Liczba podzialow poziomych

double promien; // Promien walca

double wysokosc; // Wysokosc walca

int sIndeks; // Wybrana pozycja w tablicy parametrow swiatla

int mIndeks; // Wybrana pozycja w tablicy parametrow materialu

int menu; // Identyfikator wybranego menu (menu swiatla lub menu materialu)

int szerokoscOkna = 800;

int wysokoscOkna = 600;

int z;

int q;

int a;

int k;

double obrot_x= -90.0;

double obrot_y= 0.0;

double odl_obs = -20.0;

// Tablica parametrow swiatla

GLfloat swiatlo[10][4];

GLfloat swiatlo2[10][4];

// Tablica parametrow materialu z jakiego wykonany jest walec

GLfloat material[6][4];

GLfloat material2[6][4];

GLfloat pozycja[4]={3.0,0.0,0.0,0.0};

GLfloat kierunek[4]={-3.0,0.0,0.0,0.0};

int obrot;

// Prototypy funkcji

void UstawDomyslneWartosciParametrow(void);

void RysujTekstRastrowy(void *font, char *tekst);

void UstawKolorPozycji(int m, int indeks);

void WlaczOswietlenie(void);

void DefiniujMaterial(void);

void UstawParametryOswietlenia(int indeks, char operacja);

void UstawParametryMaterialu(int indeks, char operacja);

void RysujWalec(double r, int nv, int nh);

void UstawParametryWidoku(int szer, int wys);

void RysujNakladke(void);

void WyswietlObraz(void);

void ObslugaKlawiatury(unsigned char klawisz, int x, int y);

void ObslugaKlawiszySpecjalnych(int klawisz, int x, int y);

//////////////////////////////////////////////////////////////////////////////////////////

// Funkcja ustawiajaca domyslne parametry walca, materialu i zrodla swiatla

void UstawDomyslneWartosciParametrow(void)

{

// Tablica parametrow materialu

GLfloat param_materialu[6][4] = {

{0.2, 0.2, 0.2, 1.0}, // [0] wspolczynnik odbicia swiatla otoczenia

{0.5, 0.0, 1.0, 1.0}, // [1] wspolczynnik odbicia swiatla rozproszonego

{0.4, 0.4, 0.4, 1.0}, // [2] wspolczynnik odbicia swiatla lustrzanego

{0.1, 0.0, 0.1, 0.0}, // [3] polysk

{0.0, 0.0, 0.0, 1.0}}; // [4] kolor swiatla emitowanego

// Tablica parametrow materialu2

GLfloat param_materialu2[6][4] = {

{1.0, 1.0, 0.0, 1.0}, // [0] wspolczynnik odbicia swiatla otoczenia

{1.0, 1.0, 0.0, 1.0}, // [1] wspolczynnik odbicia swiatla rozproszonego

{0.0, 0.0, 0.0, 1.0}, // [2] wspolczynnik odbicia swiatla lustrzanego

{0.0, 0.0, 0.0, 0.0}, // [3] polysk

{0.0, 0.0, 0.0, 1.0}}; // [4] kolor swiatla emitowanego

// Tablica parametrow swiatla

GLfloat param_swiatla[10][4] = {

{0.0, 0.0, 0.0, 1.0}, // [0] otoczenie

{1.0, 1.0, 1.0, 1.0}, // [1] rozproszenie

{0.0, 1.0, 0.0, 1.0}, // [2] lustrzane

{10.0, 10.0, 10.0, 0.0}, // [3] polozenie

{0.0, 0.0, -1.0, 0.0}, // [4] kierunek swiecenia

{0.0, 0.0, 0.0, 0.0}, // [5] tlumienie katowe swiatla

{180.0, 0.0, 0.0, 0.0},// [6] kat odciecia swiatla

{0.7, 0.0, 0.0, 0.0}, // [7] stale tlumienie

{0.0, 0.0, 0.0, 0.0}, // [8] tlumienie liniowe

{0.0, 0.0, 0.0, 0.0}}; // [9] tlumienie kwadratowe

// Tablica parametrow swiatla2

GLfloat param_swiatla2[10][4] = {

{0.0, 0.0, 0.0, 1.0}, // [0] otoczenie

{1.0, 1.0, 1.0, 1.0}, // [1] rozproszenie

{1.0, 1.0, 1.0, 1.0}, // [2] lustrzane

{0.0, 0.0, 0.0, 0.0}, // [3] polozenie

{-1.0, 0.0, 0.0, 0.0}, // [4] kierunek swiecenia

{100.0, 0.0, 0.0, 0.0}, // [5] tlumienie katowe swiatla

{30.0, 0.0, 0.0, 0.0},// [6] kat odciecia swiatla

{1.0, 0.0, 0.0, 0.0}, // [7] stale tlumienie

{0.0, 0.0, 0.0, 0.0}, // [8] tlumienie liniowe

{0.0, 0.0, 0.0, 0.0}}; // [9] tlumienie kwadratowe

// Skopiowanie zawartosci tablic param_* do tablic globalnych

memcpy(material, param_materialu, LPOZ_MENU_MATERIALU*4*sizeof(GLfloat));

memcpy(swiatlo, param_swiatla, LPOZ_MENU_SWIATLA*4*sizeof(GLfloat));

memcpy(material2, param_materialu2, LPOZ_MENU_MATERIALU*4*sizeof(GLfloat));

memcpy(swiatlo2, param_swiatla2, LPOZ_MENU_SWIATLA*4*sizeof(GLfloat));

// Parametry walca

lPionowych = 18; // Liczba podzialow pionowych

lPoziomych = 10; // Liczba podzialow poziomych

promien = 1.0; // Promien walca

wysokosc = 0.0; // Wysokosc walca

// Pozostale parametry

sIndeks = 0; // Wybrana pozycja w tablicy parametrow swiatla

mIndeks = 0; // Wybrana pozycja w tablicy parametrow materialu

menu = ID_MENU_SWIATLA;

glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);

}

//////////////////////////////////////////////////////////////////////////////////////////

// Funkcja rysujaca tekst rastrowy <tekst> za pomca fontow bitmapowych <font>.Rysowanie

// tekstu wykonywane jest poczawszy od biezacej pozycji ekranu.

void RysujTekstRastrowy(void *font, char *tekst)

{

int i;

for (i = 0; i < (int)strlen(tekst); i++)

glutBitmapCharacter(font, tekst[i]);

}

//////////////////////////////////////////////////////////////////////////////////////////

// Funkcja ustawia kolor dla pozycji <indeks> w menu <m>. Aktualnie wybrana pozycja

// jest rysowana w kolorze zoltym.

void UstawKolorPozycji(int m, int indeks)

{

if (m == menu)

if((m == ID_MENU_SWIATLA) && (indeks == sIndeks)

|| (m == ID_MENU_MATERIALU) && (indeks == mIndeks))

// Pozycja podswietlona wyswietlana jest w kolkorze zoltym

glColor3f(1.0, 1.0, 0.0);

else

// Pozostale na bialo

glColor3f(1.0, 1.0, 1.0);

}

//////////////////////////////////////////////////////////////////////////////////////////

// Wlaczenie oswietlenia sceny

void WlaczOswietlenie(int z, int q, int a)

{

int os1=z;

int os2=q;

int poz=a;

// Odblokowanie oswietlenia

glEnable(GL_LIGHTING);

// Odblokowanie zerowego zrodla swiatla

if(os1==1)

glEnable(GL_LIGHT0);

else

glDisable(GL_LIGHT0);

if(os2==1)

glEnable(GL_LIGHT1);

else

glDisable(GL_LIGHT1);

obrot=(obrot+5)%360;

//if(poz==1)

//{

pozycja[0]=cos(DEG2RAD(obrot));

pozycja[1]=wysokosc;

pozycja[2]=sin(DEG2RAD(obrot));

pozycja[3]=0.0;

kierunek[0]=-cos(DEG2RAD(obrot));

kierunek[1]=-wysokosc;

kierunek[2]=-sin(DEG2RAD(obrot));

kierunek[3]=0.0;

//}

/* else

{

pozycja[0]=cos(DEG2RAD(obrot));

pozycja[1]=sin(DEG2RAD(obrot));

pozycja[2]=sin(DEG2RAD(obrot));

pozycja[3]=0.0;

kierunek[0]=-cos(DEG2RAD(obrot));

kierunek[1]=-sin(DEG2RAD(obrot));

kierunek[2]=-sin(DEG2RAD(obrot));

kierunek[3]=0.0;

}*/

// Inicjowanie zrodla swiatla

glLightfv(GL_LIGHT0, GL_AMBIENT, swiatlo[0]);

glLightfv(GL_LIGHT0, GL_DIFFUSE, swiatlo[1]);

glLightfv(GL_LIGHT0, GL_SPECULAR, swiatlo[2]);

glLightfv(GL_LIGHT0, GL_POSITION, swiatlo[3]);

glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, swiatlo[4]);

glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, swiatlo[5][0]);

glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, swiatlo[6][0]);

glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, swiatlo[7][0]);

glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, swiatlo[8][0]);

glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, swiatlo[9][0]);

// Inicjowanie zrodla swiatla2

glLightfv(GL_LIGHT1, GL_AMBIENT, swiatlo2[0]);

glLightfv(GL_LIGHT1, GL_DIFFUSE, swiatlo2[1]);

glLightfv(GL_LIGHT1, GL_SPECULAR, swiatlo2[2]);

glLightfv(GL_LIGHT1, GL_POSITION, pozycja);

glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, kierunek);

glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, swiatlo2[5][0]);

glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, swiatlo2[6][0]);

glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, swiatlo2[7][0]);

glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, swiatlo2[8][0]);

glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, swiatlo2[9][0]);

}

//////////////////////////////////////////////////////////////////////////////////////////

// Zdefiniowanie walasciwosci materialu walca na podstawie zapisanych w tablcy 'material'

// parametrow (material obowiazuje tylko do scian skierowanych przodem do obserwatora)

void DefiniujMaterial(int w)

{

if (w==0)

{

glMaterialfv(GL_FRONT, GL_AMBIENT, material[0]);

glMaterialfv(GL_FRONT, GL_DIFFUSE, material[1]);

glMaterialfv(GL_FRONT, GL_SPECULAR, material[2]);

glMaterialfv(GL_FRONT, GL_SHININESS, material[3]);

glMaterialfv(GL_FRONT, GL_EMISSION, material[4]);

}

if (w==1)

{

glMaterialfv(GL_FRONT, GL_AMBIENT, material2[0]);

glMaterialfv(GL_FRONT, GL_DIFFUSE, material2[1]);

glMaterialfv(GL_FRONT, GL_SPECULAR, material2[2]);

glMaterialfv(GL_FRONT, GL_SHININESS, material2[3]);

glMaterialfv(GL_FRONT, GL_EMISSION, material2[4]);

}

}

//////////////////////////////////////////////////////////////////////////////////////////

// Ustawienie parametrow oswietlenia sceny

void UstawParametryOswietlenia(int indeks, char operacja)

{

switch(indeks)

{

// Parametry swiatla otoczenia, rozproszenia i odbicia lustrzanego

case 0:

case 1:

case 2:

switch(operacja)

{

// Zwiekszenie skladowej R o wartosc KROK_FLOAT

case '1':

swiatlo[indeks][0] = (swiatlo[indeks][0] >= 1.0) ? 1.0 : swiatlo[indeks][0]+ KROK_FLOAT;

break;

// Zmniejszenie skladowej R o wartosc KROK_FLOAT

case '!':

swiatlo[indeks][0] = (swiatlo[indeks][0] <= 0.1) ? 0.0 : swiatlo[indeks][0]- KROK_FLOAT;

break;

// Zwiekszenie skladowej G o wartosc KROK_FLOAT

case '2':

swiatlo[indeks][1] = (swiatlo[indeks][1] >= 1.0) ? 1.0 : swiatlo[indeks][1]+ KROK_FLOAT;

break;

// Zmniejszenie skladowej G o wartosc KROK_FLOAT

case '@':

swiatlo[indeks][1] = (swiatlo[indeks][1] <= 0.01) ? 0.0 : swiatlo[indeks][1]- KROK_FLOAT;

break;

// Zwiekszenie skladowej B o wartosc KROK_FLOAT

case '3':

swiatlo[indeks][2] = (swiatlo[indeks][2] >= 1.0) ? 1.0 : swiatlo[indeks][2]+ KROK_FLOAT;

break;

// Zmniejszenie skladowej B o wartosc KROK_FLOAT

case '#':

swiatlo[indeks][2] = (swiatlo[indeks][2] <= 0.1) ? 0.0 : swiatlo[indeks][2]- KROK_FLOAT;

break;

// Zwiekszenie skladowej A o wartosc KROK_FLOAT

case '4':

swiatlo[indeks][3] = (swiatlo[indeks][3] >= 1.0) ? 1.0 : swiatlo[indeks][3]+ KROK_FLOAT;

break;

// Zmniejszenie skladowej B o wartosc KROK_FLOAT

case '$':

swiatlo[indeks][3] = (swiatlo[indeks][3] <= 0.1) ? 0.0 : swiatlo[indeks][3]- KROK_FLOAT;

break;

}

break;

// Parametry opisujace polozenie i orientacje swiatla

case 3:

case 4:

case 5:

case 6:

switch(operacja)

{

// Zwiekszenie wspolrzednej X o wartosc KROK_FLOAT

case '1':

swiatlo[indeks][0] += KROK_FLOAT;

break;

// Zmniejszenie wspolrzednej X o wartosc KROK_FLOAT

case '!':

swiatlo[indeks][0] -= KROK_FLOAT;

break;

// Zwiekszenie wspolrzednej Y o wartosc KROK_FLOAT

case '2':

swiatlo[indeks][1] += KROK_FLOAT;

break;

// Zmniejszenie wspolrzednej Y o KROK_FLOAT

case '@':

swiatlo[indeks][1] -= KROK_FLOAT;

break;

// Zwiekszenie wspolrzednej Z o wartosc KROK_FLOAT

case '3':

swiatlo[indeks][2] += KROK_FLOAT;

break;

// Zmniejszenie wspolrzednej Z o wartosc KROK_FLOAT

case '#':

swiatlo[indeks][2] -= KROK_FLOAT;

break;

// Zwiekszenie wspolrzednej W o wartosc KROK_FLOAT

case '4':

swiatlo[indeks][3] += KROK_FLOAT;

break;

// Zmniejszenie wspolrzednej W o wartosc KROK_FLOAT

case '$':

swiatlo[indeks][3] -= KROK_FLOAT;

break;

}

break;

case 7:

case 8:

case 9:

switch(operacja)

{

// Zwiekszenie skladowych tlumienia wartosc KROK_FLOAT/10

case '1':

swiatlo[indeks][0] += KROK_FLOAT/10.0;

break;

// Zmniejszenie stalych tlumienia o wartosc KROK_FLOAT/10

case '!':

swiatlo[indeks][0] -= KROK_FLOAT/10.0;

break;

}

}

}

//////////////////////////////////////////////////////////////////////////////////////////

// Ustawienie parametrow materoalu

void UstawParametryMaterialu(int indeks, char operacja)

{

switch(indeks)

{

// Parametry odbicia swiatla swiatla otoczenia, swiatla rozproszonego, swiatla

// kierunkowego i emitowanego

case 0:

case 1:

case 2:

case 4:

switch(operacja)

{

// Zwiekszenie skladowej R o wartosc KROK_FLOAT

case '1':

material[indeks][0] = (material[indeks][0] >= 1.0) ? 1.0 : material[indeks][0]+ KROK_FLOAT;

break;

// Zmniejszenie skladowej R o wartosc KROK_FLOAT

case '!':

material[indeks][0] = (material[indeks][0] <= 0.1) ? 0.0 : material[indeks][0]- KROK_FLOAT;

break;

// Zwiekszenie skladowej G o wartosc KROK_FLOAT

case '2':

material[indeks][1] = (material[indeks][1] >= 1.0) ? 1.0 : material[indeks][1]+ KROK_FLOAT;

break;

// Zmniejszenie skladowej G o wartosc KROK_FLOAT

case '@':

material[indeks][1] = (material[indeks][1] <= 0.1) ? 0.0 : material[indeks][1]- KROK_FLOAT;

break;

// Zwiekszenie skladowej B o wartosc KROK_FLOAT

case '3':

material[indeks][2] = (material[indeks][2] >= 1.0) ? 1.0 : material[indeks][2]+ KROK_FLOAT;

break;

// Zmniejszenie skladowej B o wartosc KROK_FLOAT

case '#':

material[indeks][2] = (material[indeks][2] <= 0.1) ? 0.0 : material[indeks][2]- KROK_FLOAT;

break;

// Zwiekszenie skladowej A o wartosc KROK_FLOAT

case '4':

material[indeks][3] = (material[indeks][3] >= 1.0) ? 1.0 : material[indeks][3]+ KROK_FLOAT;

break;

// Zmniejszenie skladowej A o wartosc KROK_FLOAT

case '$':

material[indeks][3] = (material[indeks][3] <= 0.1) ? 0.0 : material[indeks][3]- KROK_FLOAT;

break;

}

break;

// Parametr opisujacy polysk powierzchni

case 3:

switch(operacja)

{

// Zwiekszenie skladowej R o wartosc KROK_FLOAT*10

case '1':

material[indeks][0] = (material[indeks][0] >= 100.0) ? 100.0 : material[indeks][0]+ KROK_FLOAT * 10.0;

break;

// Zmniejszenie skladowej R o wartosc KROK_FLOAT*10

case '!':

material[indeks][0] = (material[indeks][0] <= 0.0) ? 0.0 : material[indeks][0]- KROK_FLOAT * 10.0;

break;

}

break;

}

}

//////////////////////////////////////////////////////////////////////////////////////////

// Funkcja rysujaca walec o zadanej wysokosci, promieniu oraz liczbie podzialow

// pionowych i poziomych. Tryb modelowania powierzchni bocznej - GL_TRIANGLE_STRIP,

// podstaw - GL_TRIANGLE_FAN.

void RysujWalec(double r, int nv, int nh)

{

double dH, dAlfa, dBeta;

int i,j;

dAlfa = 180/(double)nv;

dBeta = 360/(double)nh;

k=0;

for (i=0;i*dAlfa<=180;i++)

{

for(j=0;j*dBeta<=360;j++)

{

if(k==0)

k=1;

else

k=0;

DefiniujMaterial(k);

glBegin(GL_QUAD_STRIP);

glNormal3f(cos(DEG2RAD(i*dAlfa))*cos(DEG2RAD(j*dBeta)),sin(DEG2RAD(i*dAlfa))*cos(DEG2RAD(j*dBeta)),sin(DEG2RAD(j*dBeta)));

glVertex3f(r*cos(DEG2RAD(i*dAlfa))*cos(DEG2RAD(j*dBeta)),r*sin(DEG2RAD(i*dAlfa))*cos(DEG2RAD(j*dBeta)),r*sin(DEG2RAD(j*dBeta)));

glNormal3f(cos(DEG2RAD(i*dAlfa))*cos(DEG2RAD((j+1)*dBeta)),sin(DEG2RAD(i*dAlfa))*cos(DEG2RAD((j+1)*dBeta)),sin(DEG2RAD((j+1)*dBeta)));

glVertex3f(r*cos(DEG2RAD(i*dAlfa))*cos(DEG2RAD((j+1)*dBeta)),r*sin(DEG2RAD(i*dAlfa))*cos(DEG2RAD((j+1)*dBeta)),r*sin(DEG2RAD((j+1)*dBeta)));

glNormal3f(cos(DEG2RAD((i+1)*dAlfa))*cos(DEG2RAD(j*dBeta)),sin(DEG2RAD((i+1)*dAlfa))*cos(DEG2RAD(j*dBeta)),sin(DEG2RAD(j*dBeta)));

glVertex3f(r*cos(DEG2RAD((i+1)*dAlfa))*cos(DEG2RAD(j*dBeta)),r*sin(DEG2RAD((i+1)*dAlfa))*cos(DEG2RAD(j*dBeta)),r*sin(DEG2RAD(j*dBeta)));

glNormal3f(cos(DEG2RAD((i+1)*dAlfa))*cos(DEG2RAD((j+1)*dBeta)),sin(DEG2RAD((i+1)*dAlfa))*cos(DEG2RAD((j+1)*dBeta)),sin(DEG2RAD((j+1)*dBeta)));

glVertex3f(r*cos(DEG2RAD((i+1)*dAlfa))*cos(DEG2RAD((j+1)*dBeta)),r*sin(DEG2RAD((i+1)*dAlfa))*cos(DEG2RAD((j+1)*dBeta)),r*sin(DEG2RAD((j+1)*dBeta)));

glEnd();

}

}

/*

double dH, dAlfa;

int i, j;

// Wyznaczenie kata wyznaczajacego pojedynczy wycinek pionowy

dAlfa = 360.0L/(double)nh;

// Wyznaczenie wysokosci pojedynczego wycinka poziomego

dH = h/(double)nv;

// Wyznaczanie wierzcholkow i wektorow normalnych powierzchni bocznych

for (i = 0; floor((i+1)*dH*1.0E10) <= floor(h*1.0E10); i++)

{

glBegin(GL_TRIANGLE_STRIP);

glNormal3f(0.0, 0.0, 1.0);

glVertex3f(0.0, (i + 1)*dH, r);

glVertex3f(0.0, i*dH, r);

for (j = 1; j*dAlfa <= 360.0L + dAlfa; j++)

{

glNormal3f(sin(DEG2RAD(j*dAlfa)), 0.0, cos(DEG2RAD(j*dAlfa)));

glVertex3f(r*sin(DEG2RAD(j*dAlfa)), (i + 1)*dH, r*cos(DEG2RAD(j*dAlfa)));

glVertex3f(r*sin(DEG2RAD(j*dAlfa)), i*dH, r*cos(DEG2RAD(j*dAlfa)));

}

glEnd();

}

// Wyznaczenie wierzcholkow i wektorow normalnych dolnej podstawy

glBegin(GL_TRIANGLE_FAN);

glNormal3f(0.0, -1.0, 0.0);

glVertex3f(0.0, 0.0, 0.0);

for (i = 0; i * dAlfa <= 360.0L + dAlfa; i++)

glVertex3f(r*sin(DEG2RAD(i*dAlfa)), 0.0, r*cos(DEG2RAD(i*dAlfa)));

glEnd();

// Wyznaczenie wierzcholkow i wektorow normalnych gornej podstawy

glBegin(GL_TRIANGLE_FAN);

glNormal3f(0.0, 1.0, 0.0);

glVertex3f(0.0, h, 0.0);

for (i = 0; i * dAlfa <= 360.0L + dAlfa; i++)

glVertex3f(r*sin(DEG2RAD(i*dAlfa)), h, r*cos(DEG2RAD(i*dAlfa)));

glEnd(); */

}

//////////////////////////////////////////////////////////////////////////////////////////

// Funkcja ustawiajaca parametry rzutu perspektywicznego i rozmiary viewportu

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);

// Przejscie w tryb modyfikacji macierzy przeksztalcen geometrycznych

glMatrixMode(GL_MODELVIEW);

// Zmiana macierzy znajdujacej sie na wierzcholku stosu na macierz jednostkowa

glLoadIdentity();

}

//////////////////////////////////////////////////////////////////////////////////////////

// Funkcja rysujaca na wygenerowanym obrazie walca nkladke z tekstem opisujacym

// aktualne parametry zrodla swiatla i materialu.

void RysujNakladke(void)

{

char buf[255];

// Zmiana typu rzutu z perspektywicznego na ortogonalny

glMatrixMode(GL_PROJECTION);

glPushMatrix();

glLoadIdentity();

glOrtho(0.0, szerokoscOkna, 0.0, wysokoscOkna,-100.0, 100.0);

// Modelowanie sceny 2D (zawartosci nakladki)

glMatrixMode(GL_MODELVIEW);

glPushMatrix();

glLoadIdentity();

// Zablokowanie oswietlenia (mialoby ono wplyw na kolor tekstu)

glDisable(GL_LIGHTING);

// Okreslenie koloru tekstu

glColor3f(1.0, 1.0, 1.0);

// RYSOWANIE MENU PARAMETROW ZRODLA SWIATLA

sprintf(buf, "Swiatlo");

glRasterPos2i(X_OFFSET_SWIATLO, Y_OFFSET_SWIATLO);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

UstawKolorPozycji(ID_MENU_SWIATLA,0);

sprintf(buf, " - otaczajace (%.1f, %.1f, %.1f, %.1f)", swiatlo[0][0], swiatlo[0][1], swiatlo[0][2],

swiatlo[0][3]);

glRasterPos2i(X_OFFSET_SWIATLO, Y_OFFSET_SWIATLO - 10);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

UstawKolorPozycji(ID_MENU_SWIATLA,1);

sprintf(buf, " - rozproszone (%.1f, %.1f, %.1f, %.1f)", swiatlo[1][0], swiatlo[1][1], swiatlo[1][2],

swiatlo[1][3]);

glRasterPos2i(X_OFFSET_SWIATLO, Y_OFFSET_SWIATLO - 20);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

UstawKolorPozycji(ID_MENU_SWIATLA,2);

sprintf(buf, " - lustrzane (%.1f, %.1f, %.1f, %.1f)", swiatlo[2][0], swiatlo[2][1], swiatlo[2][2],

swiatlo[2][3]);

glRasterPos2i(X_OFFSET_SWIATLO, Y_OFFSET_SWIATLO - 30);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

UstawKolorPozycji(ID_MENU_SWIATLA,3);

sprintf(buf, " - polozenie (%.1f, %.1f, %.1f, %.1f)", swiatlo[3][0], swiatlo[3][1], swiatlo[3][2],

swiatlo[3][3]);

glRasterPos2i(X_OFFSET_SWIATLO, Y_OFFSET_SWIATLO - 40);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

UstawKolorPozycji(ID_MENU_SWIATLA,4);

sprintf(buf, " - kierunek (%.1f, %.1f, %.1f)", swiatlo[4][0], swiatlo[4][1], swiatlo[4][2]);

glRasterPos2i(X_OFFSET_SWIATLO, Y_OFFSET_SWIATLO - 50);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

UstawKolorPozycji(ID_MENU_SWIATLA,5);

sprintf(buf, " - tl. katowe (%.1f)", swiatlo[5][0]);

glRasterPos2i(X_OFFSET_SWIATLO, Y_OFFSET_SWIATLO - 60);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

UstawKolorPozycji(ID_MENU_SWIATLA,6);

sprintf(buf, " - kat odciecia(%.1f)", swiatlo[6][0]);

glRasterPos2i(X_OFFSET_SWIATLO, Y_OFFSET_SWIATLO - 70);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

UstawKolorPozycji(ID_MENU_SWIATLA,7);

sprintf(buf, " - tl. stale (%.2f)", swiatlo[7][0]);

glRasterPos2i(X_OFFSET_SWIATLO, Y_OFFSET_SWIATLO - 80);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

UstawKolorPozycji(ID_MENU_SWIATLA,8);

sprintf(buf, " - tl. liniowe (%.2f)", swiatlo[8][0]);

glRasterPos2i(X_OFFSET_SWIATLO, Y_OFFSET_SWIATLO - 90);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

UstawKolorPozycji(ID_MENU_SWIATLA,9);

sprintf(buf, " - tl. kwadrat.(%.2f)", swiatlo[9][0]);

glRasterPos2i(X_OFFSET_SWIATLO, Y_OFFSET_SWIATLO - 100);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

// RYSOWANIE MENU PARAMETROW MATERIALU

glColor3f(1.0, 1.0, 1.0);

sprintf(buf, "Material");

glRasterPos2i(X_OFFSET_MAT, Y_OFFSET_MAT);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

UstawKolorPozycji(ID_MENU_MATERIALU,0);

sprintf(buf, " - otaczajace (%.1f, %.1f, %.1f, %.1f)", material[0][0], material[0][1],

material[0][2], material[0][3]);

glRasterPos2i(X_OFFSET_MAT, Y_OFFSET_MAT - 10);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

UstawKolorPozycji(ID_MENU_MATERIALU,1);

sprintf(buf, " - rozproszone (%.1f, %.1f, %.1f, %.1f)", material[1][0], material[1][1],

material[1][2], material[1][3]);

glRasterPos2i(X_OFFSET_MAT, Y_OFFSET_MAT - 20);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

UstawKolorPozycji(ID_MENU_MATERIALU,2);

sprintf(buf, " - kierunkowe (%.1f, %.1f, %.1f, %.1f)", material[2][0], material[2][1],

material[2][2], material[2][3]);

glRasterPos2i(X_OFFSET_MAT, Y_OFFSET_MAT - 30);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

UstawKolorPozycji(ID_MENU_MATERIALU,3);

sprintf(buf, " - polysk (%.2f)", material[3][0]);

glRasterPos2i(X_OFFSET_MAT, Y_OFFSET_MAT - 40);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

UstawKolorPozycji(ID_MENU_MATERIALU,4);

sprintf(buf, " - emitowane (%.1f, %.1f, %.1f, %.1f)", material[4][0], material[4][1],

material[4][2], material[4][3]);

glRasterPos2i(X_OFFSET_MAT, Y_OFFSET_MAT - 50);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

// RYSOWANIE MENU PARAMETROW WALCA

glColor3f(1.0, 1.0, 1.0);

sprintf(buf, "Walec:");

glRasterPos2i(X_OFFSET_OBIEKT, Y_OFFSET_OBIEKT);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

sprintf(buf, " - promien (%.1f)", promien);

glRasterPos2i(X_OFFSET_OBIEKT, Y_OFFSET_OBIEKT - 10);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

sprintf(buf, " - wysokosc (%.1f)", wysokosc);

glRasterPos2i(X_OFFSET_OBIEKT, Y_OFFSET_OBIEKT - 20);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

sprintf(buf, " - podzialow pionowych (%d)", lPionowych);

glRasterPos2i(X_OFFSET_OBIEKT, Y_OFFSET_OBIEKT - 30);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

sprintf(buf, " - podzialow poziomych (%d)", lPoziomych);

glRasterPos2i(X_OFFSET_OBIEKT, Y_OFFSET_OBIEKT - 40);

RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);

// Przywrocenie macierzy sprzed wywolania funkcji

glMatrixMode(GL_PROJECTION);

glPopMatrix();

glMatrixMode(GL_MODELVIEW);

glPopMatrix();

// Odblokowanie oswietlenia

glEnable(GL_LIGHTING);

}

//////////////////////////////////////////////////////////////////////////////////////////

// Funkcja generujaca pojedyncza klatke animacji

void WyswietlObraz(void)

{

// Wyczyszczenie bufora ramki i bufora glebokosci

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

// Okreslenie wielkosci widoku, wlaczenie rzutowania perspektywicznego

// i zainicjowanie stosu macierzy modelowania

UstawParametryWidoku(szerokoscOkna, wysokoscOkna);

// Ustawienie oswietlenia sceny (polozenie zrodla swiatla wyznaczane jest w ukladzie

// wspolrzednych obserwatora)

WlaczOswietlenie(z,q,a);

// Wyznaczenie polozenia obserwatora (przeksztalcenie uladu wspolrzednych

// sceny do ukladu wspolrzednych obserwatora). Obserwator obraca sie wokol punktu 0.0

// na osi OY. Promien obrotu = 20, pochylenie = 20 stopni,

// predkosc obrotu = 0.25 stopnia/ramke.

glTranslatef(0, 0, odl_obs);

glRotatef(obrot_y, 0, 1, 0);

glRotatef(obrot_x, 1, 0, 0);

glRotatef(kat, 0, 1, 0);

// Zdefiniowanie materialu walca

DefiniujMaterial();

// Generacja obrazu walca

RysujWalec(promien, lPoziomych, lPionowych);

// Narysowanie tekstow z opisem parametrow oswietlenia i materialu

RysujNakladke();

// Przelaczenie buforow ramki

glutSwapBuffers();

// Modyfikacja kata obrotu

//kat += 0.25;

}

//////////////////////////////////////////////////////////////////////////////////////////

// Funkcja obslugi klawiatury

void ObslugaKlawiatury(unsigned char klawisz, int x, int y)

{

switch(klawisz)

{

case 'd':

q=(q==0)?1:0;

break;

case 's':

z=(z==0)?1:0;

break;

case 'f':

a=(a==0)?1:0;

break;

case '[':

obrot_x=(obrot_x<45.0)?obrot_x+1.0:45.0;

break;

case '{':

obrot_x=(obrot_x>-90.0)?obrot_x-1.0:-90.0;

break;

case ']':

obrot_y=(obrot_y<360.0)?obrot_y+1.0:360.0;

break;

case '}':

obrot_y=(obrot_y>0.0)?obrot_y-1.0:0.0;

break;

case ';':

odl_obs=(odl_obs>-30.0)?odl_obs-1.0:-30.0;

break;

case ':':

odl_obs=(odl_obs<-10.0)?odl_obs+1.0:-10.0;

break;

case 'v':

lPionowych = (lPionowych == LPION_MAX)? LPION_MAX : lPionowych + 2;

break;

case 'V':

lPionowych = (lPionowych == LPION_MIN)? LPION_MIN : lPionowych - 2;

break;

case 'h':

lPoziomych = (lPoziomych == LPOZ_MAX)? LPOZ_MAX : lPoziomych + 2;

break;

case 'H':

lPoziomych = (lPoziomych == LPOZ_MIN)? LPOZ_MIN : lPoziomych - 2;

break;

case 'w':

wysokosc = (wysokosc == WYS_MAX) ? WYS_MAX : wysokosc + 1;

break;

case 'W':

wysokosc = (wysokosc == 1) ? wysokosc : wysokosc - 1;

break;

case 'p':

promien = (promien == R_MAX) ? R_MAX : promien + 1;

break;

case 'P':

promien = (promien == 1) ? promien : promien - 1;

break;

case 'r':

UstawDomyslneWartosciParametrow();

break;

case 'm':

menu = (menu == ID_MENU_SWIATLA) ? ID_MENU_MATERIALU : ID_MENU_SWIATLA;

break;

case '1':

case '!':

case '2':

case '@':

case '3':

case '#':

case '4':

case '$':

if (menu == ID_MENU_SWIATLA)

UstawParametryOswietlenia(sIndeks, klawisz);

else

UstawParametryMaterialu(mIndeks, klawisz);

break;

// Wcisniecie klawisza ESC powoduje wyjscie z programu

case 27:

exit(0);

}

}

//////////////////////////////////////////////////////////////////////////////////////////

// Funkcja klawiszy specjalnych

void ObslugaKlawiszySpecjalnych(int klawisz, int x, int y)

{

switch(klawisz)

{

case GLUT_KEY_UP:

if (menu == ID_MENU_SWIATLA)

sIndeks = (sIndeks > 0) ? sIndeks - 1 : 0;

else

mIndeks = (mIndeks > 0) ? mIndeks - 1 : 0;

break;

case GLUT_KEY_DOWN:

if (menu == ID_MENU_SWIATLA)

sIndeks = (sIndeks < LPOZ_MENU_SWIATLA - 1) ? sIndeks + 1 : LPOZ_MENU_SWIATLA - 1;

else

mIndeks = (mIndeks < LPOZ_MENU_MATERIALU - 1) ? mIndeks + 1 : LPOZ_MENU_MATERIALU - 1;

break;

}

}

//////////////////////////////////////////////////////////////////////////////////////////

// Glowna funkcja programu

int main(int argc, char **argv)

{

// Zainicjowanie biblioteki GLUT

glutInit(&argc, argv);

// Ustawienie trybu wyswietlania

glutInitDisplayMode (GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);

// Ustawienie polozenia dolenego lewego rogu okna

glutInitWindowPosition(100, 100);

// Ustawienie rozmiarow okna

glutInitWindowSize(szerokoscOkna, wysokoscOkna);

// Utworzenie okna

glutCreateWindow("Oswietlony walec");

// Odblokowanie bufora glebokosci

glEnable(GL_DEPTH_TEST);

// Ustawienie funkcji wykonywanej na danych w buforze glebokosci

glDepthFunc(GL_LEQUAL);

// Ustawienie wartosci czyszczacej zawartosc bufora glebokosci

glClearDepth(1000.0);

// Odblokowanie wykonywania operacji na skladowych "alfa"

glEnable(GL_BLEND);

// Wybor funkcji mieszajacej kolory

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

// Ustawienie koloru czyszczenia bufora ramki

glClearColor (0.0, 0.3, 0.0, 0.0);

// Zarejestrowanie funkcji (callback) wyswietlajacej

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);

// Zarejestrowanie funkcji obslugi klawiszy specjalnych

glutSpecialFunc(ObslugaKlawiszySpecjalnych);

// Ustawienie domyslnych wartosci parametrow

UstawDomyslneWartosciParametrow();

// Obsluga glownej petli programu (wywolywanie zarejestrowanych callbackow

// w odpowiedzi na odbierane zdarzenia lub obsluga stanu bezczynnosci)

glutMainLoop();

return 0;

}



Wyszukiwarka