|
|
Idézet gaborlabor :
Amik most az egérmozgáshoz voltak rendelve azok régebben a nyílbillentyűkhöz voltak, és úgy működött rendesen.
felfele nyíllal feljebb fordult a kamera, lefelével lefelé, jobbra nyíllal elfordult jobbra, balrával balra, a w-a-s-d -vel pedig lehet haladni. Ez így egy működő koncepció volt mindenféle szempontból, és nincs is teli számításokkal. Szal ezért gondoltam hogyha már ezt kibővítettem akkor megmaradok ennél és csak a nyílbillentyűk szerepét átadom az egér mozgásának.
Az sosem jó, ha az egér mozgását úgy akarod megvalósítani, mint a billentyűzetét, valahogy "másabb" lesz a mozgás. Ezt én is egyszer megcsináltam (igaz, DDrawban), de nem volt az igazi, de legalább egy kicsi blur-ös effektet hagyott maga után mozgás közben  . Utána rátaláltam egy jó kis megoldásra, onnantól kezdve azt használom.
|
|
|
Matekból hát szóval izé... nem vagyok rossz belőle voltam már versenyen is  de mondjuk inkább úgy hogy még képzetlen vagyok mivel mégcsak a középsulit nyomom. Azokkal a fügvényekkel már énis találkoztam. 
De amúgy az, hogy az én progimban a számítások, forgatások, stb jó, az 100%, mivel azt sem én irtam teljesen  Volt egy példaprogram valahol a neten, abban ugy lehetett mozogni mint a doom2-ben. én csak annyit irtam át benne hogy oldalazni is lehessen meg hogy a kamerát felfelé is el lehessen mozgatni és akkor az előremozgásnál felfelé is emelkedjen, szóval mindig a kamera nézőpontja felé haladjon. az úgy működik, hogy mikor elfordulok, akkor eltárolom az elfordulás nagyságát, aztán valami sinussal meg cosinussal variál és azt hozzáadja a nézőpont megfelelő koordinátájához. ezt csak annyival egészítettem ki hogy a függőleges forgáshoz létrehoztam 2 új változót és a vizszintes alapján megirtam. rövid, és még nekem is érthető, szal nem szivesen válnék meg ettől a megoldástól.  itt van a kód:
Kód: void orientMe(float ang1)
{
lx = sin(ang1); // Forgáshoz kell
lz = -cos(ang1); // Forgáshoz kell
ly = sin(angle2); // Forgáshoz kell
lxx = sin(ang2); // Oldalazáshoz kell
lzz = -cos(ang2); // Oldalazáshoz kell
}
void moveMeFlat()
{
// ELŐRE - HÁTRA
if (deltaMove < 2, vagyis 1, vagy -1)
{
x = x + deltaMove*(lx)*0.1*speed_elorehatra;
z = z + deltaMove*(lz)*0.1*speed_elorehatra;
y = y + deltaMove*(ly)*0.1*speed_elorehatra;
}
//ez az én kiegészítésem
// OLDALAZÁS - BALRA
if (deltaMove == 2)
{
x = x + 1*(lxx)*0.1*speed_oldalazas;;
z = z + 1*(lzz)*0.1*speed_oldalazas;
}
// OLDALAZÁS - JOBBRA
if (deltaMove == 3)
{
x = x + -1*(lxx)*0.1*speed_oldalazas;
z = z + -1*(lzz)*0.1*speed_oldalazas;
}
}
Aztán a renderelő függvény elején meghívom ezeket:
Kód: moveMeFlat();
angle += deltaAngle;
angle2 += deltaAngle2;
orientMe(angle);
//és elhelyezem a "kamerát"
glLoadIdentity();
gluLookAt(x, y, z,
x + lx,y + ly,z + lz,
0.0f,1.0f,0.0f);
És így mozgok:
Kód: void keyboardfunc(unsigned char key, int x, int y)
{
switch(key)
{
case 27 : exit(0); break; // esc
case 97 : deltaMove = 2; break; // a -balra oldalazás
case 100 : deltaMove = 3; break; // d -jobbra oldalazás
case 119 : deltaMove = 1; break; // w
case 115 : deltaMove = -1; break; // s
}
}
void keyboardupfunc(unsigned char key, int x, int y)
{
switch(key)
{
case 97 : deltaMove = 0; break;
case 100 : deltaMove = 0; break;
case 119 : deltaMove = 0; break;
case 115 : deltaMove = 0; break;
}
}
Amik most az egérmozgáshoz voltak rendelve azok régebben a nyílbillentyűkhöz voltak, és úgy működött rendesen.
felfele nyíllal feljebb fordult a kamera, lefelével lefelé, jobbra nyíllal elfordult jobbra, balrával balra, a w-a-s-d -vel pedig lehet haladni. Ez így egy működő koncepció volt mindenféle szempontból, és nincs is teli számításokkal. Szal ezért gondoltam hogyha már ezt kibővítettem akkor megmaradok ennél és csak a nyílbillentyűk szerepét átadom az egér mozgásának.
|
|
|
Egyébként, ha szabad egy megjegyzést: a 3D.exe-dben az egér mozgása lemarad a valós mozgás mögött, a kurzor egy adott pályán tud csak mozogni átlósan (vagy csak én nem tudtam irányítani rendesen  ). Ezek a fg-ek, amiket ide bemásoltam (régi gerzSonka forrkódból, ami meg állítólag gamedev-es, én nem tudom, de ha működik, és megérti az ember a lényeget, vajmi keveset számít, honnan való  ), elég bonyolult matematikai egyenleteket használ (legalábbis első látásra), de ha jó vagy matekból, akkor hamar elsajátíthatod!
|
|
|
Igaz, kiegészítő függvények:
Kód: struct CVektor
{
public:
CVektor() {}
CVektor(float X, float Y, float Z)
{
x = X; y = Y; z = Z;
}
CVektor operator+(CVektor vVector)
{
return CVektor(vVector.x + x, vVector.y + y, vVector.z + z);
}
CVektor operator-(CVektor vVector)
{
return CVektor(x - vVector.x, y - vVector.y, z - vVector.z);
}
CVektor operator*(float num)
{
return CVektor(x * num, y * num, z * num);
}
CVektor operator/(float num)
{
return CVektor(x / num, y / num, z / num);
}
float x, y, z;
};
CVektor m_vPosition;
CVektor m_vView;
CVektor m_vUpVector;
CVektor Cross(CVektor vVector1, CVektor vVector2)
{
CVektor vNormal;
vNormal.x = ((vVector1.y * vVector2.z) - (vVector1.z * vVector2.y));
vNormal.y = ((vVector1.z * vVector2.x) - (vVector1.x * vVector2.z));
vNormal.z = ((vVector1.x * vVector2.y) - (vVector1.y * vVector2.x));
return vNormal;
}
float NormalVek(CVektor vNormal)
{
return (float)sqrt( (vNormal.x * vNormal.x) +
(vNormal.y * vNormal.y) +
(vNormal.z * vNormal.z) );
}
CVektor Normalize(CVektor vVector)
{
float magnitude = NormalVek(vVector);
vVector = vVector / magnitude;
return vVector;
}
void RotateView(float angle, float x, float y, float z)
{
CVektor vNewView;
CVektor vView;
vView.x = m_vView.x - m_vPosition.x;
vView.y = m_vView.y - m_vPosition.y;
vView.z = m_vView.z - m_vPosition.z;
float cosTheta = (float)cos(angle);
float sinTheta = (float)sin(angle);
vNewView.x = (cosTheta + (1 - cosTheta) * x * x) * vView.x;
vNewView.x += ((1 - cosTheta) * x * y - z * sinTheta) * vView.y;
vNewView.x += ((1 - cosTheta) * x * z + y * sinTheta) * vView.z;
vNewView.y = ((1 - cosTheta) * x * y + z * sinTheta) * vView.x;
vNewView.y += (cosTheta + (1 - cosTheta) * y * y) * vView.y;
vNewView.y += ((1 - cosTheta) * y * z - x * sinTheta) * vView.z;
vNewView.z = ((1 - cosTheta) * x * z - y * sinTheta) * vView.x;
vNewView.z += ((1 - cosTheta) * y * z + x * sinTheta) * vView.y;
vNewView.z += (cosTheta + (1 - cosTheta) * z * z) * vView.z;
m_vView.x = m_vPosition.x + vNewView.x;
m_vView.y = m_vPosition.y + vNewView.y;
m_vView.z = m_vPosition.z + vNewView.z;
}
Ez kissé bonyolult, de mindenképpen müxik! De ha gondolod, írhatsz saját Cross, Normalize, és RotateView függvényeket, bár ehhez tényleg erős matek kell (ami pl. nálam nem kimondottan lelhető fel  ).
|
|
|
Idézet Csaba42 :
Kód: void CCamera::SetViewByMouse()
{
POINT mousePos;
int middleX = SCREEN_WIDTH / 2;
int middleY = SCREEN_HEIGHT / 2;
float angleY = 0.0f;
float angleZ = 0.0f;
static float currentRotX = 0.0f;
GetCursorPos(&mousePos);
if( (mousePos.x == middleX) && (mousePos.y == middleY) ) return;
SetCursorPos(middleX, middleY);
// Kiszámoljuk az elfordulás szögét, amit radiánban (valós számként) tárolunk.
// A radián alapja a pi! A pi értéke 180 fok, amely radiánban 3,14! Ez kapcsolatba
// hozható a kör kerületével. Ennek következtében pi/2 = 90 fok, stb. Így tárolunk
// szögeket valós számként.
angleY = (float)( (middleX - mousePos.x) ) / 1000.0f;
angleZ = (float)( (middleY - mousePos.y) ) / 1000.0f;
currentRotX -= angleZ;
if(currentRotX > 1.0f)
currentRotX = 1.0f;
else if(currentRotX < -1.0f)
currentRotX = -1.0f;
else
{
CVektor vAxis = Cross(m_vView - m_vPosition, m_vUpVector);
vAxis = Normalize(vAxis);
RotateView(angleZ, vAxis.x, vAxis.y, vAxis.z);
RotateView(angleY, 0, 1, 0);
}
}
Erre gondoltam
|
|
|
Idézet Csaba42 :
Tudtommal az OpenGL koordinátarendszreében a bal alsó az origó.
Már kicsit belegabalyodtam ezekbe a koordinátákba, de asszem énis ezt mondtam. OpenGL-ben a 0,0 a bal alsó, GLUT-ban meg a bal felső.
|
|
|
Idézet gaborlabor :
Idézet Csaba42 :
Nálam ugyanúgy viselkedik, mint az előző.
Az érdekes. És az egérkurzor hogy viselkedik, mert nálam az is elég furcsán. Mindegy, mostmár nem csodálkozok azon hogy ez nem müxik rendesen. Az előző postod után csoda hogy egyáltalán megmozdul.
Akkor majd ujrairom a mouse függvényt, és megírom a fejleményeket!
Még régebben bedobtam egy egérkezelő függvényt, próbáld meg azt átalakítani, és használni!
|
|
|
Idézet gaborlabor :
Csak azt nem értem, hogyha flfelé mozog, akkor miért az x értéke változik meg, miért nem az y?
Bocsi, én írtam el, valóban az y változik, és az x nem
|
|
|
Idézet Csaba42 :
Nálam ugyanúgy viselkedik, mint az előző.
Az érdekes.  És az egérkurzor hogy viselkedik, mert nálam az is elég furcsán. Mindegy, mostmár nem csodálkozok azon hogy ez nem müxik rendesen. Az előző postod után csoda hogy egyáltalán megmozdul.
Akkor majd ujrairom a mouse függvényt, és megírom a fejleményeket!
|
|
|
Idézet gaborlabor :
Amúgy nem lehet hogy az ablakrelatív koordinátákban a 0,0 az nem a bal alsó sarok, hanem a bal felső sarok? Csak mert van egy loading függvény ami a program elején lefut és beállítja a kurzort középre. (SetCursorPos(middleX, middleY) És mikor elindul a program, akkor az egérkurzor a bal felső sarokban van.
Tudtommal az OpenGL koordinátarendszreében a bal alsó az origó.
|
|
|
Idézet Csaba42 :
A realítv koordináta az nem egyenlő az abszolút koordinátával! Az utóbbi a bal felső sarokban van (OpenGL ablakban azt hiszem a jobb alsó az origó), míg relatív esetén ha nem mozog az egér, akkor az x és y értéke 0. Így ha felfelé mozog a kurzor, az x érzéke megváltozik (y nem, de csak akkor ha pontosan felfelé, ami elég nehéz megvalósítani ).
Más szóval: ha x!=0 és/vagy y!=0, akkor mozog az egér, a mozgás sebessége adva van x-ben és y-ban, az irány az előjel. Ugyanilyen pl. DInputban is az DIMouse->SetProperty(DIPROP_AXISMODE, DIPROPAXISMODE_REL); beállítás.
Legalábbis, legjobb tudásom szerint így vagyon, de ha keverek valamit, nyugodtan szóljatok rám. 
Hoppá. Tudtam én hogy itt lesz a gubanc ezekkel a koordinátákkal. Tehát az abszolút 0,0 koordináta az a bal felső sarok. Gondolom a GLUT miatt, mert OpenGL-ben a bal alsó sarok a 0,0 GLUT-ban meg a bal felső. (ha jól emléxem).
Akkor valszeg azzal van a gond, hogy ha nem mozog az egér akkor az értéke 0,0. Csak azt nem értem, hogyha flfelé mozog, akkor miért az x értéke változik meg, miért nem az y?
"ha x!=0 és/vagy y!=0, akkor mozog az egér"
Asszem ez alapján kell ujrairnom a mouse függvényemet. De azért nézd meg az előző postomat is. 
Köszi szépen, már most sokat segítettél!
|
|
|
Nálam ugyanúgy viselkedik, mint az előző.
|
|
|
Itt valami nem stimmel 
Most meg nem is reagál a mozgatásra, egészen addig, amég le nem nyomom valamelyik gombot. Akkor meg megbolonul és folyamatosan forog, átlósan ide-oda.
A függvény prototípusa:
Kód: void mouse(int button, int state, int x, int y);
A main függvényben:
Kód: glutMouseFunc(mouse);
És a mouse függvény:
Kód: void mouse(int button, int state, int x, int y)
{
//Ha középen van
if (x == middleX && y == middleY)
{
deltaAngle = 0;
deltaAngle2 = 0;
}
if (x < middleX)
{
deltaAngle = -0.01f*speed_forgas_w;
}
if (x > middleX)
{
deltaAngle = 0.01f*speed_forgas_w;
}
if (y < middleY)
{
deltaAngle2 = 0.01f*speed_forgas_h;
}
if (y > middleY)
{
deltaAngle2 = -0.01f*speed_forgas_h;
}
SetCursorPos(middleX, middleY);
}
Itt van az exe is, nézd meg, hogy viselkedik.
3D.exe
Amúgy nem lehet hogy az ablakrelatív koordinátákban a 0,0 az nem a bal alsó sarok, hanem a bal felső sarok? Csak mert van egy loading függvény ami a program elején lefut és beállítja a kurzort középre. (SetCursorPos(middleX, middleY) És mikor elindul a program, akkor az egérkurzor a bal felső sarokban van.
|
|
|
A realítv koordináta az nem egyenlő az abszolút koordinátával! Az utóbbi a bal felső sarokban van (OpenGL ablakban azt hiszem a jobb alsó az origó), míg relatív esetén ha nem mozog az egér, akkor az x és y értéke 0. Így ha felfelé mozog a kurzor, az x érzéke megváltozik (y nem, de csak akkor ha pontosan felfelé, ami elég nehéz megvalósítani  ).
Más szóval: ha x!=0 és/vagy y!=0, akkor mozog az egér, a mozgás sebessége adva van x-ben és y-ban, az irány az előjel. Ugyanilyen pl. DInputban is az DIMouse->SetProperty(DIPROP_AXISMODE, DIPROPAXISMODE_REL); beállítás.
Legalábbis, legjobb tudásom szerint így vagyon, de ha keverek valamit, nyugodtan szóljatok rám.
|
|
|
Köszi a segítséget! Mindjárt lekódolom, és meglátjuk hogy működik. De amúgy a mouse függvény az elvileg nem lehet hibás, mert ugynezek voltak a nyílbillentyűkhöz is rendelve.
Na, mindjárt meglátjuk. Addig is egy kérdés:
Az ablak relatív koordinátákban hol van a 0,0 ? Az ablak közepén, vagy a bal alsó sarokban?
|
|
|
Hmm, ez valóban nem az igazi. Az a lényeg, hogy késik a kurzor mozgása az egér valós mozgásához képest. Ajánlom a glut függvényét használni, vagy legalábbis ezzel hívd meg a
Kód: void mouse(int x, int y);
függvényed:
Kód: glutMouseFunc(void (*func)(int button, int state, int x, int y));
A függvényt specifikálja, amely egy egér gomb lenyomásakor illetve elengedésekor hívódik meg. A button callback paraméter a GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON illetve a GLUT_RIGHT_BUTTON egyike. A state callback paraméter a GLUT_UP és a GLUT_DOWN szimbolikus konstansok egyike. Az x és y callback paraméterek az egér pozícióját jelzik az egér esemény megtörténtekor (ablak relatív koordinátákban). Az int main()-be kerüljön a glutMouseFunc(mouse); bejegyzés, az egérkezelő függvényed prototípusa pedig ilyen legyen:
Kód: void mouse(int button, int state, int x, int y);
Ebbe helyezd el a void mouse(int x, int y); függvényed törzsét, és tájékoztass a fejleményekről  .
|
|
|
Csaba42:
Itt van az exe:
3D.exe
És itt van a kód is, hogy most hogyan van megoldva:
Kód: //Időzített függvény, ami 20 ms-enként lekérdezi az egér pozicioját
//és meghívja a mouse függvényt
void timer1(int value)
{
glutTimerFunc(20, (timer1), 1);
GetCursorPos(&MousePos);
mouse(MousePos.x, MousePos.y);
}
...
//mouse függvény
void mouse(int x, int y)
{
//Ha középen van
if (x == middleX && y == middleY)
{
deltaAngle = 0;
deltaAngle2 = 0;
}
if (x < middleX)
{
deltaAngle = -0.01f*speed_forgas_w;
}
if (x > middleX)
{
deltaAngle = 0.01f*speed_forgas_w;
}
if (y < middleY)
{
deltaAngle2 = 0.01f*speed_forgas_h;
}
if (y > middleY)
{
deltaAngle2 = -0.01f*speed_forgas_h;
}
//A kurzort visszahelyezzük középre
SetCursorPos(middleX, middleY);
}
Szerintem nézd meg az exét, hogy hogyan működik. Nem igazán tudom hogy mi, de valami furcsa rajta... Talán az hogy a függőleges forgás lassabb mint a vízszintes és azért ilyen furcsa?
|
|
|
nem ezt akartam, azt már megoldottam  , viszont most kipihenve és belegondolva nem tom mér tettem fel a kérdést, na mind1, azér köszi
|
|
|
Ezt akartad kerdezni tegnap este MSN-en? Ha igen, a valaszom:
Elsore nem nagyon vagtam le, mi köze lenne a display listnek a bump maphez. De ha a bump maped nem annyiban merül ki, h rahuzol egy texturat + egy masikat, s a ketto blendelese kiemeli az eleket, hanem pl. shaderrel csinalod full dinamikusra, amit befolyasol a per-pixel feny, etc. akkor tenyleg nem lehet... Szerintem.
|
|
|
Nehe tutorban olvastam, hogy Bump Mappingnél nem használható Display List ez igaz?
|
|
|
Ok, holnap, vagyis még ma megpróbálom minél jobban helyrerázni a kódot, aztán majd bemásolom ide.
Ja, egy kis gond már most is van. Az egérkezelő függvényt a
glutPassiveMotionFunc()-kal akartam először kezeltetni. Viszont ha ez
Kód: glutPassiveMotionFunc(mouse) ;
benne volt a main függvényben, akkor a program főablaka, vagyis a teljes képernyős megjelenítés meg sem jelent, csak a konzol ablak. 
Ezért az egér kezelését kénytelen voltam ideiglenes úgy megoldani, hogy van egy időzített függvény, ami 20 ezredmásodpercenként meghívja a mouse(int x, int y) függvényt. A 20 ms nem lehet túl sok, mert kipróbáltam hogy billentyűzetet is így kezelek és az megy rendesen. Aztán megpróbáltam úgy is, hogy az időzített függvényt kidobtam, és helyette a renderelő függvény elején hívom meg a mouse(int x, int y) függvényt. Ez meg még rosszabb, mert nagyon szaggat az egérkezelés.
A legjobb az lenne, ha meg tudnám csinálni, hogy a glutPassiveMotionFunc() kezelje az egérkezelő függvényt.
|
|
|
Hát csak akkor láttam utoljára ilyet, amikor ezt tesztképpen 90-re állítottam. ^o)
Igen, furcsán viselkedik és lassan követi az egér mozgását. Jó lenne ha tudnál kódot is másolni, mert csak tippelgetni tudok/tudunk, az meg nem elég jó
|
|
|
Jó is hogy felvetetted, mert ezt még nem értem teljesen. Valami oylasmit olvastam azzal a parméterrel kapcsolatban, hogy az az a szög, amekkorát a felhasználó zár be a monitorral. Ha mondjuk képzeletben húzok egy vonalat köztem és a monitor közepe között, akkor az a vonal 90°-ot zár be a monitorral. Viszont ha köztem és a monitor egyik széle között húzok egy vonalat, akkor az a szög lehet akár 45°-os is. Azért nem értettem, mert láttam példaprogramot amiben 90 volt, meg láttam olyat is amiben meg 45. Ezt tisztázhatná valaki egy kicsit. 
De te honnét gondoltad, hogy nálam 90-re van állítva? Mert 45-ön van:
Kód: gluPerspective(45, w / h, 0.01, 1000);
Úgyhogy nem ezzel van a probléma. Nálad is olyan furcsán viselkedett az egérlezelés? Úgy tűnik, mintha az átlós mozgásra érzékenyebb lenne mint a függőleges vagy vízsszintes mozgatásra, pedig elvileg nem lehetne ilyen.
|
|
|
gluPerspective első paramétere (Field of View) mekkorára van állítva?
90 fok az egy picit sok, állítsd át mondjuk 45-re.
|
|
|
Újabb fejlemények. Rájöttem mitől volt a függőleges irányú forgás darabossága. Abban nem az egérkezelő volt a hibás, hanem azt az egész részt én rontottam el úgy hogy van. Azt kompletten újraírtam a vizszintes forgás alapján. Ezután a darabosság megszűnt, normálisan forog minden irányba. Viszont ez az egérkezelési módszer nem tutti, vagy csak az én függvényem rossz, mert néha nagyon belassul tőle a program, néha meg rakoncátlankodik.
Kódot azért nem rakok be, mert annyira gány az az egész a sok átirogatástól, vagdosástól, hogy még énis alig igazodok ki rajta.
Inkább nézzétek meg az exét, ha kipofoztam a kódot, majd rakhatok be azt is.
3D.exe
|
|
|
Na, asszem sínen vagyok.  Ahogy az előző hsz-emben irtam, ugy most lekódoltam és a lényege müxik. Bár a kamrea forgatása lassú mégis darabos, de legalább müxik és az egérrel lehet irányítani. Már bevezettem néhány változót, amikkel a sebességeket lehet állítani, de még nem sikerült belőnöm úgy hogy normálisan lehessen irányítani. Remélem ez már csak apróbb munkálatokat fog igényelni.
Köszönöm az ötleteket és a segítséget!
|
|
|
igen, tudom, a spectator móddal kapcsolatban igazad van, azért irtam utána, hogy mire is gondolok. (bár asszem cs1.6-ban nincs ütközésvizsgálat olyankor, a pályáról is ki lehet "repülni"  .
Megpróbálom ugy megoldani, hogy a program legelején az egérkurzort elhelyezem a képernyő közepére. Ezután ciklikusan megvizsgálom hogy az x és az y mennyivel változott meg, és ennek megfelelően járok el, végül pedig visszahelyezem középre az egérkurzort, és kezdődik előlről. Ennek igy müködnie kell, remélem meg tudom oldani.
Köszi a segítséget!
|
|
|
Ütközésvizsgálat van, legalábbis a JK2-ben - spectator módban is  (Q3 motor)
A DirectInputnak semmi köze az itt felvetett kérdéshez  Főleg mert ez az OpenGL topic 
De amúgy beast is írta, a legegyszerőbb ha minden egérmozgás lekezelésekor megnézed mennyi az elmozdulás a képernyő közepéhez, ehhez asszociálsz egy megfelelő szöggel történő elforgatást (egérérzékenység, stb figyelembevételével), forgatsz, az egérkurzort pedig visszadobod középre és kezdődhet a móka elölről.
|
|
|
Köszi mindenkinek!
Csaba42: A feladat azon része mr meg van oldva. De mondjuk az sem elég jó első ránézésre, mert én kezdetnek olyan progit szeretnék írni ami olyan mint mikor egy fps-ben spectator vagy, vagy be van kapcsolva a fly meg a falonátjárás.  Szóval nincs ütközésdetektálás és gravitáció. Kezdetben azt gondoltam, meg tudom irni magamtól, de ahogy belekezdtem, felismertem a buktatóit. A legtöbb szívás azzal volt, hogyha a FEL nyilat lenyomva a nézőpontot megemeltem (mintha felfelé néznél) és úgy nyomtam le a W-t, akkor már nem csak előre kellett mennie, hanem felfelé is, tehát a center felé kell haladnia mindeképp. Ehhez kell itt is az elfordulási szöggel kalkulálni. A lényeg, hogy találtam egy példaprogit, amiben úgy lehetett mozogni mint a doom2-ben. Azt sikeresen megbuheráltam úgy, hogy legyen benne oldalazás is, ne csak forgás, és megcsináltam azt is, hogy a fel-le nyilakkal az előbb említett függőleges irányú elmozdulás is lehetséges legyen. Annak a programnak is az a lelke, hogy az elfordulási szögekkel és sinussal és cosinussal számolgat. Tehát már mindem megvan ami a mozgást és nézelődést illeti:
W - előre
A - oldalazás balra
S - hátra
D - oldalazás jobbra
FEL - nézés felfelé
LE - nézés lefelé
BALRA - forgás balra
JOBBRA - forgás jobbra.
Na, ezek közül kéne nekem a fel, le, jobbra, balra gombok akcióit átírnom egérre, és kész is lennék.
Dinputtól meg nem azért idegenkedek, mert nem szeretem a directx-et, de úgy gondolom, hogyha eddig mindent megoldottam a directx és directinput nélkül, akkor valahogy biztosan meglehet oldani az egérkezelést is, csak lehet hogy kicsivel nehezebb.
|
|
|
De ha jól elolvastad, akkor látod, hogy a középpontól (width/2, height/2) való elmozdulással alapszik. Ha mozgatod az egeret, akkor csak pár pixeles elétrésekkel dolgozik, majd megint a képernyő közepére dobja a kurzort. NIncs semmi 1023->0. Vagy mi a kérdés? 
Amúgy sztem ez nem GerzSonka saját kódja, inkább gametutorialos...
|
|
|
Én arra gondoltam, hogy amint eléri vmelyik határt, 0-zod az adott számot (pl.: 1023->0), és veheted ezt is mozgásnak. Persze, ez csak egy futó gondolat volt, talán nem is működik (bevallom, OpenGLben nem vagyok otthon).
Kód: void CCamera::SetViewByMouse()
{
POINT mousePos;
int middleX = SCREEN_WIDTH / 2;
int middleY = SCREEN_HEIGHT / 2;
float angleY = 0.0f;
float angleZ = 0.0f;
static float currentRotX = 0.0f;
GetCursorPos(&mousePos);
if( (mousePos.x == middleX) && (mousePos.y == middleY) ) return;
SetCursorPos(middleX, middleY);
// Kiszámoljuk az elfordulás szögét, amit radiánban (valós számként) tárolunk.
// A radián alapja a pi! A pi értéke 180 fok, amely radiánban 3,14! Ez kapcsolatba
// hozható a kör kerületével. Ennek következtében pi/2 = 90 fok, stb. Így tárolunk
// szögeket valós számként.
angleY = (float)( (middleX - mousePos.x) ) / 1000.0f;
angleZ = (float)( (middleY - mousePos.y) ) / 1000.0f;
currentRotX -= angleZ;
if(currentRotX > 1.0f)
currentRotX = 1.0f;
else if(currentRotX < -1.0f)
currentRotX = -1.0f;
else
{
CVektor vAxis = Cross(m_vView - m_vPosition, m_vUpVector);
vAxis = Normalize(vAxis);
RotateView(angleZ, vAxis.x, vAxis.y, vAxis.z);
RotateView(angleY, 0, 1, 0);
}
}
Ez persze nem az enyém, GerzSonka tulajdona, de hátha segít!
|
|
|
DInputot, ha eddig mellőztem (billentyűzetkezelés müxik rendesen glut-tal), nem most fogom elővenni. Igen, énis igy oldanám meg glut-ban. Az aktuális mousecoordot azt le tudom kérdezni, mozgatásnál ezt vehetjük a réginek. Ehhez viszonyítva meg tudom állapítani hogy az egér új x, és y koordinátája nőtt vagy csökkent. Egészen addig amíg el nem érem az ablak határait, vagyis teljes képernyős módnál az 1023 és a 767 a max, és ha onnét húzza tovább, azt is kezelni kéne valahogy. Még dolgozok rajta. Ha bárkinek eszébe jut valami, ne habozzon írni.
|
|
|
DirectInput  . GLUT-vel eléggé nehéz lesz, de nem megoldhatatlan. Csak tudni kell a régi mouse coord-ot és az újjal összehasonlítani és úgy mozgatni. Vagyis én így oldanám meg DirectInput nélkül.
No [img] !
Programozz ne háborúzz!!!!
|
|
|
Na, sikeresen megoldottam a mozgást a 3d-s térben, minden irányba, mint egy fps játékban. Csak most még billentyűzettel lehet irányítani. A forgást át szeretném írni, hogy egérrel lehessen irányítani.
Valamelyik GLUT-os egérkezelő függvényre gondoltam. Azt kéne meghatározni, hogy az egér melyik irányba mozdult el, a kurzor ablakbeli relativ pozicioja és a gombok lenyomva tartása nem lényeges. Ti melyik függvénnyel/módszerrel oldanátok meg?
THX
|
|
|
Igen, pont erre gondoltam énis mikor belegondoltam és rájöttem, hogy én ezt nemtudom megcsinálni. Szerintem a középiskolás matek az a minimum a 3d-hez, csakhogy én még azon sem vagyok ám túl...
Addigis maradnak másoktól ellesett megoldások. De mint mondtam abban a példaprogiban nem tűnt olyan bonyolultnak. Asszem 1-2 sin() meg cos() függvény az alapja az egésznek.
|
|
|
Trigonometriára szükséged lesz mindenképpen, ajánlatos körbenézni a gömbi koordináták háza táján ha mouselookot akarsz csinálni.
|
|
|
Megnéztem a progi kódját, és ahogy elnéztem elég bonyolult matematikai számításokkal oldja meg a mozgatást. Egyenlőre nem siekrült teljesen átlátnom az egész működését, de persze nem várok csodát 30 perc alatt.  Viszont a LightHouse3d-n találtam egy hóemberes példaprogramot, ami ugyanazt csinálja, csak sokkal rövidebb, egyszerűbb, és átláthatóbb számításokat/megoldásokat használ. Valszeg abból fogok kiindulni, de azért köszi a segítséget és a linket!
|
|
|
THX a lot! Letöltöttem, még csak az exe-t néztem meg, de nagyon tetszik, pont ilyenre gondoltam! 
Beleásom magam a kódba, hátha sikerül megtalálnom benne a nekem fontos részt. Köszi mégegyszer!
|
|
|
Szerintem ezt nézd meg, hátha találsz valami érdekeset benne!
|
|
|
Köszi a választ! A mozgást nagyjából sikerült megoldanom. Viszont az egérrel már nem volt könnyű dolgom. Úgy próbáltam megoldani, hogy a program legelején a
Kód: GetCursorPos(&mouse);
kóddal lekérdezem az egér x és y koordinátáját és azokat a mouse.x és mouse.y-ban tárolom,
és a glut-os mousefunc()-kal pedig megvizsgálom, hogy ez egér új pozicioja hogyan tér el az indulási koordinátáktól és ez alapján a center-t módosítom, mintha forogna a kamera:
Kód: void mousemove(int x, int y)
{
if (mouse.x < x)
{
centerx -= 3;
}
if (mouse.x > x)
{
centerx += 3;
}
}
Elvileg működnie kéne, de nem tökéletes, mert néha akdozik, néha az ellenkező irányba forog, néha pedig nem is reagál a mozgatásra. Ezt majd még talán meg tudom oldani valahogy, de van egy ennél nagyobb gondom is.
Ha pl az egérrel a "kamerát" elforgattam kicsit jobbra meg kicsit felfelé, és utána nyomom le az előre nyilat, akkor már nem csak az eyez -t kell módosítanom, mert a "kamera" már nem a negatív z tengely irányába néz. És erre nem tudtam még rájönni, hogy hogyan számítsam ki, hogy az eyex,eyey,eyez közül melyiket és hogyan kell módosítanom, hogy a szem pozíciója úgy mozduljon el, hogy a center felé halad, ahová nézek. Tehát hogy olyasmi legyen, mint mikor egy fps-ben spectator vagy és tudsz menni akármerre.
Ha bárki tudna segíteni, annak nagyon örülnék!
Köszi.
|
|
|
****** cenzúrázva, én voltam figyelmetlen
|
|
|
Nem csak az eyex, eyey, eyez-t kell módosítani, hanem a center-eket is.
A gluLookAt-re úgy gondolj, mint egy kamerára, ahol meg van adva az a pont, ahol van a kamera, és az as pont, ahová néz. Hogyha pl a center a kamera előtt van, te mozgatod előre a kamerát, de a centert nem, akkor amint a kamera túljut a centeren, megfordul, és már nem jó az egész. 
Persze az opengl-ben nincs kamera, illetve mindig a (0,0,0) pontban van, tehát nem a nézőpont változik a gluLookAt-tel, hanem a színtér lesz eltolva, forgatva, stb.
|
|
|
Hy all! Első 3d-s progimat szeretném megírni, de akadt néhány problémám. Olyan progit szeretnék irni, ami egy-két egyszerű objektumot, pl kockát rajzol ki, és a nyilak segítségével tudom a kamerát, azaz a nézőpontot mozgatni, úgy mint az FPS játékokban.
A rajzoló függvényem csak egy kockát rajzol ki:
Kód: glBegin(GL_QUADS);
//szemközti oldal
glVertex3f(0, 0, 0);
glVertex3f(5, 0, 0);
glVertex3f(5, 5, 0);
glVertex3f(0, 5, 0);
//jobb oldal
glVertex3f(5, 0, 0);
glVertex3f(5, 0, -5);
glVertex3f(5, 5, -5);
glVertex3f(5, 5, 0);
//bal oldal
glVertex3f(0, 0, 0);
glVertex3f(0, 5, 0);
glVertex3f(0, 5, -5);
glVertex3f(0, 0, -5);
//alsó oldal
glVertex3f(0, 0, 0);
glVertex3f(5, 0, 0);
glVertex3f(5, 0, -5);
glVertex3f(0, 0, -5);
//felső oldal
glVertex3f(0, 5, 0);
glVertex3f(5, 5, 0);
glVertex3f(5, 5, -5);
glVertex3f(0, 5, -5);
//hátsó oldal
glVertex3f(0, 0, -5);
glVertex3f(5, 0, -5);
glVertex3f(5, 5, -5);
glVertex3f(0, 5, -5);
glEnd();
A látóteret a gluPerspective()-vel akartam specifikálni, mert a glFrustum-mal nem siekrült úgy, hogy meg is jelenjen a kocka (nem találtam normális leírást, vagy működő példát). Tehát a látóteret így állítom be:
Kód: glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.0f, 4/3 , 0.01f ,1000.0f);
Ezzel megjelenik egy négyzet, úgy, hogy a bal alsó sarka a képernyő közepén van. Úgy terveztem, hogy a kameramozgást a gluLookAt()-tel fogom megoldani, de ehhez megintcsak elég szegényes leírást találtam.  Próbálkoztam többféleképpen, de nem sikerült úgy megoldanom, hogy a kockát a képernyő közepén lássam szemből. A kameramozgást pedig úgy próbáltam megoldani, hogy a rajzoló függvény elején ottvannak a
Kód: glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz);
sorok, és a billentyűzetkezelő függvényben módosítom a az eyex, eyey, eyez értékeket, de ezt sem sikerült megoldanom úgy, hogy a mozgás megfelelő legyen (pl néha forgás lett, néha meg nem abba az irányba ment amerre szeretném stb).
Ehhez szeretnék segítséget kérni, hogy a gluPerspective-et és a gluLookAt-et hogyan specifikáljam az elején, és hogy mely változókat hogyan módosítsam az egyes mozgásokhoz.
A segítséget előre is köszönöm!
|
|
|
Kipróbáltam amit mondtál. Az idlefunc-ot teljesen kivettem és a glutPostRedisplay-t beirtam a renderelő függvény végére. Valószínűleg nem azzal volt a baj. Az eredmény:
- A program általánosságban hozzányúlás nélkül 10 fps-sel kevesebbel megy mint eddig. Most igy 130-cal ment átlagban.
- A jelenség továbbra is fentáll, csak azzal a különbséggel hogy most nem 300-ra ugrik fel az fps, hanem csak 260-ra.
Ez jelenség nem is igazán probléma nálam, mert müködik igy is a program. Viszont sehogy nem fér a fejembe, hogy hogy képes megduplázódni az fps érték. Meg ha egyszer tud menni 260-300 FPS-sel, akkor alapból miért nem megy annyival?
|
|
|
Egy GLUT-ot használó (és működő) alkalmazás (nevezetesen a lib3ds példa programja) a DisplayFunc vége:
...
glutSwapBuffers();
glutPostRedisplay();
...
Szerintem ha ezeket berakod a DisplayFunc végére te is, és az Idle-ben nem renderelsz, akkor komoly esély van rá hogy megjavul.
|
|
|
Az IdleFunc-kal kapcsolatban lehet hogy igazad van, de ezt nem magamtól vettem hogy ott rendereltetem ujra. Rengeteg tutorialban és leirásban láttam, hogy a glutIdleFunc()-ban ez áll:
glutPostRedisplay(); vagyis ujrarajzoltatja a képernyőt. Leggyakrabban ezt azért nem használják számításokra, mert ez akkor hívódik meg ha a proci "ráér", és így minden gépen más sebességgel futna a program, a proci órajelétől függően, ezt meg senki nem akarja. Kipróbáltam hogy nem használo az IdleFunc-ot, úgy meg nem frissíti a képetm tehát 1 FPS-sel megy és nem frissül a tartalom. Ezért gondolom kell az oda. Még mindíg azt furcsállom hogy miért ugrik meg az fps érték.
|
|
|
A figyelmetlenségért elnézést kérek.
Ha teljes képernyős, és átváltasz, akkor nincs már hova rendereljen. Ezért továbbra is fenn tartom hogy akkor nem kéne renderelnie, legfeljebb off-screen bufferekre.
Nem emlékszem sokra a glut használatából, de a glutIdleFunc() mintha kisebb számításokra lenne, és nem további renderelésre. Talán éppen ez a gond. Próbáld meg hogy ott nem renderelsz semmit, csak a DisplayFunc-ban.
|
|
|
Köszi, értem mire gondolsz.  Csakhogy zárójelben ott van hogy Fraps-szel mérve.  Tehát az értékek valószínűleg reálisak.
Nekem nem tűnik furcsának hogy inaktív állapotban is renderel. Nem a tálcán van csak inaktiv mert átváltok a konzol ablakra. Viszont a glutIdleFunc() miatt amikor "ráér" akkor renderel ujra. És a helyzet továbbra is ez, függetlenül a program összetettségétől és méretétől.
|
|
|
Eleve értelmetlen fps-ről beszélni, ha inaktív, hiszen nem kéne rajzolnia semmit. Ha mégis rajzol, akkor kezdd itt a javítgatását a proginak. A 80-90 fura, mert ha rendes program inaktív állapotban nagyon hamar végigér a main loop-on, és a 80-90 helyett nagyságrendekkel magasabb érték kéne. A felgyorsulásra azt javaslom nézd meg FRAPS-szel, vagy valami megbízható cuccal, hátha csak az fps számlálód rossz.
|
|
|
Hi. Van egy dolog, amit már régóta nem tudok megérteni, és kicsit furcsállom.
Van egy win32 console application projektem, és abban irtam az opengl-es progit. GLUT-ot használ alakozáshoz, és teljes képernyős módhoz. Ez a progi átlag 140-150 FPS-sel megy (Fraps-szel mérve). Ha alt+tabbal átváltok a console ablakra, akkor látom, hogy a háttérben lévő teljes képernyős ablak kb 80-90 FPS-sel megy. És azt nem értem, hogy miért van az, hogy mikor visszaváltok alt+tabbal, akkor a megszokott 140-15 FPS helyett felugrik 290-310-re, és úgy is marad egészen a kilépésig. Szal nekem ez egy kicsit furcsa. Miért lesz attól gyorsabb hogy átváltok róla, aztán meg visszaváltok? Tudtok erre valami magyarázatot?
Köszi!
|
|
|
Legújabb project:
Smashed Potatoes
Legutóbb frissített project:
Treasure Measure
Friss kép a galériából:
|