Ĺadny brzuch
Witam!
W czasopiśmie Komputer Świat Ekspert numer 1/2005 był artykuł dotyczący wykożystania OpenGL'a w C++ [cz.2]. "Przekonwerterowałem" podany kod (C++) w artykule na kod w Delphi. Kłopot w tym że nie wiem jak "rozgryźć" niektóre rzeczy z C++. Mam już ładnie wyrenderowane pomieszczenie w Delphi tylko mam problem z poruszaniem się po nim. Podam fragment kody w C++ odpowiedzialny (moim zdaniem) za poruszanie się w pomieszczeniu (mało się znam na C++ i zdecywowanie wolę delphi). Kod:
bool GranicaRuchu( GLfloat rLewoPrawo, GLfloat rPrzodTyl, GLfloat rozmiarX, GLfloat rozmiarZ ) { /* do funkcji podajemy kolejno ogranizcenia ruchu: rLewoPrawo, rPrzodTyl oraz rozmiar pomieszczenia, w ktorym powinnismy byc ograniczeni */ //zwracana jest wartosc true (false) gdy jestesmy w (na zewnatrz) pomieszcz. return ( fabs( rLewoPrawo ) >= rozmiarX || fabs( rPrzodTyl ) >= rozmiarZ ); }
void Ruch( int klawisz, int x, int y ) { //zmienna okreslajaca czy jest wcisniety dodatkowy klawisz (ctrl) int dodatkowyKlawisz = glutGetModifiers(); //zmienne okreslajace szybkosc obracania i poruszania sie w pomieszczeniu const GLfloat deltaKatY = 5.0f, deltaXZ = 15.0f; //zmienne pomocnicze const double r = M_PI / 180.0; GLfloat dx = cos( katY * r ) * deltaXZ, dz = sin( katY * r ) * deltaXZ; /* w zaleznosci od wcisnietego klawisza lub kombinacji klawiszy wykonujemy odpowiednie instrukcje */ switch ( klawisz ) { //dla klawisza "lewy" case GLUT_KEY_LEFT: //sprawdzenie czy wcisniety jest rownoczesnie klawisz ctrl if ( dodatkowyKlawisz == GLUT_ACTIVE_CTRL ) katY -= deltaKatY; else //sprawdzenie czy nie znajdujemy sie poza pomieszczniem if ( !GranicaRuchu( ruchLewoPrawo + dx, ruchPrzodTyl + dz, 300.0f, 300.0f ) ) { ruchLewoPrawo += dx; ruchPrzodTyl += dz; } break; case GLUT_KEY_RIGHT: if ( dodatkowyKlawisz == GLUT_ACTIVE_CTRL ) katY += deltaKatY; else if ( !GranicaRuchu( ruchLewoPrawo - dx, ruchPrzodTyl - dz, 300.0f, 300.0f ) ) { ruchLewoPrawo -= dx; ruchPrzodTyl -= dz; } break; case GLUT_KEY_DOWN: if ( !GranicaRuchu( ruchLewoPrawo + dz, ruchPrzodTyl - dx, 300.0f, 300.0f ) ) { ruchLewoPrawo += dz; ruchPrzodTyl -= dx; } break; case GLUT_KEY_UP: if ( !GranicaRuchu( ruchLewoPrawo - dz, ruchPrzodTyl + dx, 300.0f, 300.f ) ) { ruchLewoPrawo -= dz; ruchPrzodTyl += dx; } break; } }
Kłopot w tym że nie wiem jak to "zamienić" na delphi. Jak już będę wiedzieć to myślę, że już rozgryzę jak się poruszać w moim pomieszczeniu. Nie jest tego wiele więc jeśli ktoś mógłby to "przetłumaczyć" na kod delphi to byłbym niezmiernie wdzięczny ;)
Pozdrawiam serdecznie i z góry baaaaardzo dziękuję ;)
Użytkownik Reiko edytował ten post 06 maj 2007, 19:37
Pierwsza funkcja:
//to moze bedzie tak, nie wiem, jak z ta funckja 'fabs' function GranicaRuchu(rLewoPrawo, rPrzodTyl, rozmiarX, rozmiarZ: GLfloat): boolean; begin result := ((fabs(rLewoPrawo) >= rozmiarX) or (fabs(rPrzodTyl) >= rozmiarZ)); end;
Jak napisałem w komentarzu - nie wiem, co z funkcją fabs (na Ubuntu nie ma Delphi, żeby sprawdzić ^^).
Druga funkcja jest niepełna. Przełożyłem tylko 1/4 bloku switch - sądzę, że na tej podstawie spokojnie przełożysz resztę :)
procedure Ruch(klawisz, x, y: integer); const deltaKatY = 5.0f; deltaXZ = 15.0f; r = M_PI / 180.0; var dodatkowyKlawisz: integer; dx, dz: GLfloat; begin dodatkowyKlawisz := glutGetModifiers(); dx := cos(katY * r) * deltaXZ; dz := sin(katY * r) * deltaXZ; case klawisz of GLUT_KEY_LEFT: begin //sprawdzenie czy wcisniety jest rownoczesnie klawisz ctrl if dodatkowyKlawisz == GLUT_ACTIVE_CTRL then katY := katY - deltaKatY else //sprawdzenie czy nie znajdujemy sie poza pomieszczniem if not GranicaRuchu(ruchLewoPrawo + dx, ruchPrzodTyl + dz, 300.0f, 300.0f) then begin ruchLewoPrawo := ruchLewoPrawo + dx; ruchPrzodTyl := ruchPrzodTyl +dz; end; break; end; /////////////////////////////////////////////////itd end;
Za ewentualne błędy przepraszam, ale się hmmm spieszę na 'tron' :D
Zamiast x.0f wystarczy x :) abs() zamiast fabs().
Tak, wiem. Problem w tym że przy linii:
if GranicaRuchu( (ruchLewoPrawo + dx), (ruchPrzodTyl + dz), 300.0, 300.0) = FALSE then
Wyskakuje mi komunikat "[Error] Pomieszczenie.dpr(116): Types of actual and formal var parameters must be identical". Sprawdziłem typy danych i niby wszystko się zgadza. Co może być nie tak?
PS. Tego IF'a troszkę zmodyfikowałem. Ale jak próbowałem zrobić tak jak Ty to wyskakiwał mi ten sam komunikat :/
A to takie porąbane jest :|
Może dodaj zmienną boolean i do niej przypisuj wynik tuż przed porównaniem, a potem tylko:
if zmienna then // if not zmienna then
Ach, no i może przypisanie takie:
zmienna := GranicaRuchu(ruchLewoPrawo + dx, ruchPrzodTyl + dz, 300.0, 300.0);
Niestety, wciąż to samo :(
zanotowane.pl doc.pisz.pl pdf.pisz.pl zsf.htw.pl
W czasopiśmie Komputer Świat Ekspert numer 1/2005 był artykuł dotyczący wykożystania OpenGL'a w C++ [cz.2]. "Przekonwerterowałem" podany kod (C++) w artykule na kod w Delphi. Kłopot w tym że nie wiem jak "rozgryźć" niektóre rzeczy z C++. Mam już ładnie wyrenderowane pomieszczenie w Delphi tylko mam problem z poruszaniem się po nim. Podam fragment kody w C++ odpowiedzialny (moim zdaniem) za poruszanie się w pomieszczeniu (mało się znam na C++ i zdecywowanie wolę delphi). Kod:
bool GranicaRuchu( GLfloat rLewoPrawo, GLfloat rPrzodTyl, GLfloat rozmiarX, GLfloat rozmiarZ ) { /* do funkcji podajemy kolejno ogranizcenia ruchu: rLewoPrawo, rPrzodTyl oraz rozmiar pomieszczenia, w ktorym powinnismy byc ograniczeni */ //zwracana jest wartosc true (false) gdy jestesmy w (na zewnatrz) pomieszcz. return ( fabs( rLewoPrawo ) >= rozmiarX || fabs( rPrzodTyl ) >= rozmiarZ ); }
void Ruch( int klawisz, int x, int y ) { //zmienna okreslajaca czy jest wcisniety dodatkowy klawisz (ctrl) int dodatkowyKlawisz = glutGetModifiers(); //zmienne okreslajace szybkosc obracania i poruszania sie w pomieszczeniu const GLfloat deltaKatY = 5.0f, deltaXZ = 15.0f; //zmienne pomocnicze const double r = M_PI / 180.0; GLfloat dx = cos( katY * r ) * deltaXZ, dz = sin( katY * r ) * deltaXZ; /* w zaleznosci od wcisnietego klawisza lub kombinacji klawiszy wykonujemy odpowiednie instrukcje */ switch ( klawisz ) { //dla klawisza "lewy" case GLUT_KEY_LEFT: //sprawdzenie czy wcisniety jest rownoczesnie klawisz ctrl if ( dodatkowyKlawisz == GLUT_ACTIVE_CTRL ) katY -= deltaKatY; else //sprawdzenie czy nie znajdujemy sie poza pomieszczniem if ( !GranicaRuchu( ruchLewoPrawo + dx, ruchPrzodTyl + dz, 300.0f, 300.0f ) ) { ruchLewoPrawo += dx; ruchPrzodTyl += dz; } break; case GLUT_KEY_RIGHT: if ( dodatkowyKlawisz == GLUT_ACTIVE_CTRL ) katY += deltaKatY; else if ( !GranicaRuchu( ruchLewoPrawo - dx, ruchPrzodTyl - dz, 300.0f, 300.0f ) ) { ruchLewoPrawo -= dx; ruchPrzodTyl -= dz; } break; case GLUT_KEY_DOWN: if ( !GranicaRuchu( ruchLewoPrawo + dz, ruchPrzodTyl - dx, 300.0f, 300.0f ) ) { ruchLewoPrawo += dz; ruchPrzodTyl -= dx; } break; case GLUT_KEY_UP: if ( !GranicaRuchu( ruchLewoPrawo - dz, ruchPrzodTyl + dx, 300.0f, 300.f ) ) { ruchLewoPrawo -= dz; ruchPrzodTyl += dx; } break; } }
Kłopot w tym że nie wiem jak to "zamienić" na delphi. Jak już będę wiedzieć to myślę, że już rozgryzę jak się poruszać w moim pomieszczeniu. Nie jest tego wiele więc jeśli ktoś mógłby to "przetłumaczyć" na kod delphi to byłbym niezmiernie wdzięczny ;)
Pozdrawiam serdecznie i z góry baaaaardzo dziękuję ;)
Użytkownik Reiko edytował ten post 06 maj 2007, 19:37
Pierwsza funkcja:
//to moze bedzie tak, nie wiem, jak z ta funckja 'fabs' function GranicaRuchu(rLewoPrawo, rPrzodTyl, rozmiarX, rozmiarZ: GLfloat): boolean; begin result := ((fabs(rLewoPrawo) >= rozmiarX) or (fabs(rPrzodTyl) >= rozmiarZ)); end;
Jak napisałem w komentarzu - nie wiem, co z funkcją fabs (na Ubuntu nie ma Delphi, żeby sprawdzić ^^).
Druga funkcja jest niepełna. Przełożyłem tylko 1/4 bloku switch - sądzę, że na tej podstawie spokojnie przełożysz resztę :)
procedure Ruch(klawisz, x, y: integer); const deltaKatY = 5.0f; deltaXZ = 15.0f; r = M_PI / 180.0; var dodatkowyKlawisz: integer; dx, dz: GLfloat; begin dodatkowyKlawisz := glutGetModifiers(); dx := cos(katY * r) * deltaXZ; dz := sin(katY * r) * deltaXZ; case klawisz of GLUT_KEY_LEFT: begin //sprawdzenie czy wcisniety jest rownoczesnie klawisz ctrl if dodatkowyKlawisz == GLUT_ACTIVE_CTRL then katY := katY - deltaKatY else //sprawdzenie czy nie znajdujemy sie poza pomieszczniem if not GranicaRuchu(ruchLewoPrawo + dx, ruchPrzodTyl + dz, 300.0f, 300.0f) then begin ruchLewoPrawo := ruchLewoPrawo + dx; ruchPrzodTyl := ruchPrzodTyl +dz; end; break; end; /////////////////////////////////////////////////itd end;
Za ewentualne błędy przepraszam, ale się hmmm spieszę na 'tron' :D
Zamiast x.0f wystarczy x :) abs() zamiast fabs().
Tak, wiem. Problem w tym że przy linii:
if GranicaRuchu( (ruchLewoPrawo + dx), (ruchPrzodTyl + dz), 300.0, 300.0) = FALSE then
Wyskakuje mi komunikat "[Error] Pomieszczenie.dpr(116): Types of actual and formal var parameters must be identical". Sprawdziłem typy danych i niby wszystko się zgadza. Co może być nie tak?
PS. Tego IF'a troszkę zmodyfikowałem. Ale jak próbowałem zrobić tak jak Ty to wyskakiwał mi ten sam komunikat :/
A to takie porąbane jest :|
Może dodaj zmienną boolean i do niej przypisuj wynik tuż przed porównaniem, a potem tylko:
if zmienna then // if not zmienna then
Ach, no i może przypisanie takie:
zmienna := GranicaRuchu(ruchLewoPrawo + dx, ruchPrzodTyl + dz, 300.0, 300.0);
Niestety, wciąż to samo :(