|
|
V prvním díle tohoto mini-tutoriálu jsme si ukázali ovládání pohybu v openGL pomocí klávesnice (tzn. pohyb vpřed, vzad a úkroky). Nyní navážeme na onu první část a ukážeme si, jak se pohybovat ve scéně pomocí myši – tím myslím otáčení se kolem stálé pozice.
Pokud jste ještě nečetli první část, a chystáte se rovnou skočit na tuto, pak Vás musím varovat, že se možná nezorientujete v některých věcech, proto si raději nejprve nastudujte první část.
A teď tedy konečně začněme:
Opět si nadefinujeme nám již známé proměnné:
#define DEG_TO_RAD (3.14159/180.0)
GLdouble pozice[3]={0.0, 0.0, 7.0};
GLdouble smerPohledu[3]={0.0, 0.0, -1.0};
bool kameraVlevo, kameraVpravo, kameraDopredu, kameraDozadu;
GLdouble uhelPohledu = 270;
Přibyla nám zde jedna nová proměnná jménem uhelPohledu, která nám bude uchovávat úhel natočení kamery do boku (nabývá hodnot z intervalu ). Jeho počáteční hodnota je vysvětlena později.
Taktéž se zde objevuje konstanta DEG_TO_RAD, která nám zastupuje číslo pro převod ze stupňů na radiány, se kterými pracují goniometrické fuknce.
Stejně jako v první části bude též vypadat funkce gluLookAt(), kterou nemá smysl znova zmiňovat.
V main() funkci nám ale přibydou dvě nové volání funkcí, jimiž jsou:
glutMotionFunc(myMouseMotion);
glutMouseFunc(myMouse);
Obě funkce mají za parametr odkaz na obsluhující funkci. První slouží k obsloužení myši, pokud je zmáčknuto nějaké tlačítko myši a je proveden pohyb myši (změna souřadnic polohy myši) a druhá slouží pouze k detekci stisknutí či uvolnění tlačítka.
Nejprve se podíváme na detekci tlačítek. Fuknce má následující tvar:
void myMouse(int tlac, int stav, int x, int y){
if ((tlac == GLUT_LEFT_BUTTON) && (stav == GLUT_DOWN)){
stareX = x;
stareY = y;
}
}
Jejími parametry jsou:
Při stisknutí „myšítka“ dojde k zaznamenání aktuální pozice ukazatele myši. Pro toto jsem si zvolil dvě proměnné typu int a to jsou stareX a stareY. Myslím, že k pochopení hodnot GLUT_LEFT_BUTTON a GLUT_DOWN není třeba žádného vysvětlení. Stejně bychom mohli provádět jiné akce při uvolnění levého tlačítka a nebo při zmáčknutí/uvolnění ostatních tlačítek myši.
Nyní druhá funkce. Tj. funkce pro obsluhu pohybu myši:
void myMouseMotion(int x, int y){
if (x > stareX) {
uhelPohledu += (x - stareX);
if (uhelPohledu > 360) uhelPohledu -= 360;
smerPohledu[0] = cos(uhelPohledu*DEG_TO_RAD);
smerPohledu[2] = sin(uhelPohledu*DEG_TO_RAD);
stareX = x;
}
if (x 0) uhelPohledu += 360;
smerPohledu[0] = cos(uhelPohledu*DEG_TO_RAD);
smerPohledu[2] = sin(uhelPohledu*DEG_TO_RAD);
stareX = x;
}
if (y > stareY) {
if (smerPohledu[1] > -2)
smerPohledu[1] -= 0.02;
stareY = y;
}
if (y < stareY) {
if (smerPohledu[1] < 2)
smerPohledu[1] += 0.02;
stareY = y;
}
}
Tato funkce má pouze dva parametry, jimiž jsou hodnoty na osách x a y. Funkce je volána vždy při pohybu myši při stisknutém tlačítku myši, proto parametr typu tlac či stav nepotřebuje.
Zde tedy vždy porovnáváme námi zaznamenanou hodnotu při stisknutí tlačítka (stareX a stareY) s nově získanou hodnotou po pohybu myši.
Při změně souřadnice na ose y dojde ke změně pouze jedné proměnné, a tou je smerPohledu[1], která zastupuje hodnotu směru pohledu na ose y (svislé). Zvětšuji ji o hodnotu 0.02 jen tak náhodně, protože jinak se mi zdá pohyb buď to rychlý nebo naopak zase pomalý. Je jen na Vás, jakou hodnotu si zvolíte. Taktéž je zde omezení pro maximální možné naklonění, a tím je právě hodnota 2. Přijde mi to taktéž vhodné omezení, protože pak by mohlo docházet k zbytečně velkým hodnotám u této proměnné.
Nesmíme zapomenout znova přepsat hodnoty u proměnné stareY na námi nově získanou hodnotu.
Nyní na tu těžší část, kterou je změna souřadnic u osy x. Naši proměnnou uhelPohledu zvětšíme/zmenšíme o rozdíl staré souřadnice s novou souřadnicí. Pokud jsme se dostali mimo rozsah intervalu , tak se do něj zase dostaneme přičtením či odečtením 360.
Pro výpočet jedné osy (zde x) použijeme goniometrickou funkci cos a pro druhou (zde z) použijeme sin. Z tohoto důvodu je počáteční hodnota proměnné uhelPohledu rovna 270. Pohled míří dozadu, tudíž hodnota osy x musí být rovna 0 (což je u cosinu 90° nebo 270°) a hodnota osy z musí být rovna -1 (což je u sinu pouze 270°) => počáteční hodnota pro uhelPohledu musí být 270. Nesmíme zase zapomenout zapsat do proměnné stareX nově získanou hodnotu.
Pro ukázku výsledku si můžete stáhnout tento jednoduchý program, ilustrující pohyb klávesnicí (klávesami W, S, A, D) i myší.
Stáhněte ZDE.
Štítky: c++, kamera, OpenGL, pohyb
Nic ve zlém, ale nechtěl bys psát trochu jinam?
Tady je to zbytečné mrhání tvého talentu. Na odbornějších stránkách bude větší zájem a rádi ti za tvé články zaplatí. Zde zbytečně zapadnou, ale je to tvoje věc.
Jejda, tak to dekuju. No treba vyhraju notebook a budu to mit zaplacene ![]()
Když koukám na tvoje články (zaachi.com), kdybys to všechno poslal na http://programujte.com/ , už jsi net notebook mohl mít vyděláno (nadsázka, ale … ) ;-).
2: Tak jo, dostals mě :-D. Máš ho. Gratuluji velice, je to zasloužená výhra.
Když si procházím tento zdrojový kód tak vidím v části myMouseMotion chybu v podmínce if (x 0), která nic neznamená.
Možná by se hodilo sem umístit i celkový zdrojový kód v textovém souboru a ne jen výsledný spustitelný soubor a ještě nějaké soubory, které se mi jen tak nedaří otevřít.
Zaachi blog využívá WordPress MU a běží na Blog.zive.cz. Vytvořte si svůj vlastní blog
Sledování přes RSS: články
a komentáře
Partnerská sekce pro IT profesionály:
Microsoft TechNet/MSDN