OIS vs. SDL
-
Hallo, wie der Titel schon sagt geht es mir um die Frage welches InputSystem meinen Ansprüchen eher entspricht.
Zur Fragestellung, ich habe bisher Irrlicht genutzt welches Nativ die Events des Betriebssystemes genutzt hat, da ich nun aber auch parrallel das selbe Project mittels OGRE entwickeln möchte wo eben kein InputSystem Integriert ist stellt sich mir die Frage welches zu empfehlen ist.
Die Tutorials bauen alle auf OIS auf und bisher habe ich dies auch genutzt, dies ist recht überschaubar aber meiner subjektiven Empfindung nach auch recht langsam.
SDL schaut von der API-Dokumentation etwas umfangreicher aus und soll (soweit ich las) auch Cross-Plattform einsetzbar sein.
Was mich momentan bei OIS nervt, sind einerseite die Geschwindigkeit und zum Zweiten das es für die Personalisierte Anzeige eines CursorIcons(bzw zum ausblenden des SystemCursors bei Mouseover des Renderbereiches) welches zur Anzeige des Systemcursor´s zurückkehrt alsbald es das RenderWindow verlässt nur den Weg über die windows.h mittels showCursor() bzw. die xlib.h mittels XDefineCursor() und XUndefineCursor() und einem transparenten CursorIcon gibt.
Darum würd ich gerne bezüglich dieser zwei Punkte Meinungen von Leuten "hören" (lesen) die beides bereits eigensetzt haben, gerne schaue ich mir auch andere Alternativen an.
Danke im Vorhinein.
-
WeakPeak schrieb:
Die Tutorials bauen alle auf OIS auf und bisher habe ich dies auch genutzt, dies ist recht überschaubar aber meiner subjektiven Empfindung nach auch recht langsam.
Woran machst du das fest? Rufst du einmal pro Frame mouse->capture() und keyboard->capture() auf? Tendenziell sollte OIS sogar schneller als Irrlicht sein, da OIS DirectInput verwendet. Du musst dich aber noch nichtmal zwischen OIS und SDL entscheiden... OIS bietet nämlich auch einen SDLInputManager. Das ist ein Wrapper um das SDL-Input-Modul und implementiert das InputManager-Interface, d.h. du kannst nach wie vor mit InputManager, MouseListener und KeyboardListener arbeiten. Andererseits verwendet SDL bestimmt auch DirectInput aber du kannst es ja mal probieren.
In /src/OISInputManager.cpp steht folgendes
InputManager* InputManager::createInputSystem( ParamList ¶mList ) { InputManager* im = 0; #if defined OIS_SDL_PLATFORM im = new SDLInputManager();
Eventuell musst du OIS mit SDL-Support neu kompilieren (->Doku).
Also und zum Zweiten das es für die Personalisierte Anzeige eines CursorIcons(bzw zum ausblenden des SystemCursors bei Mouseover des Renderbereiches) welches zur Anzeige des Systemcursor´s zurückkehrt alsbald es das RenderWindow verlässt nur den Weg über die windows.h mittels showCursor() bzw. die xlib.h mittels XDefineCursor() und XUndefineCursor() und einem transparenten CursorIcon gibt.
Verstehe den Satz nicht so ganz
... ich probiers trotzdem mal: Du musst den Maus-Cursor selbst zeichnen, wenn du einen eigenen willst oder ein GUI-Framework verwenden wie bspw. CEGUI. Dazu findest du auch einiges im Ogre-Wiki.
-
dark orbit schrieb:
Verstehe den Satz nicht so ganz
... ich probiers trotzdem mal: Du musst den Maus-Cursor selbst zeichnen, wenn du einen eigenen willst oder ein GUI-Framework verwenden wie bspw. CEGUI. Dazu findest du auch einiges im Ogre-Wiki.
oki thx, ich werd mich gleich mal mit OIS_SDL_PLATFORM beschäftigen.
Keyboard und Mouse capture rufe ich im frameRenderingQueued auf und mache die subjektiv langsame Geschindigkeit daran fest das wenn ich mit der Mouse das RenderWindow verlasse der Cursor von CeGUI nicht unbedingt ganz bis zum Rand fährt, evt. ist hier mein verständniss falsch.
Was ich bezüglich deines Zitats oben meinte:
BEI OIS ist als default ja
DISCL_EXCLUSIVE
eingestellt, was dann ermöglicht das man via CeGUI oder mittels OgrePanelOverlayElement einen benutzer definierten Cursor innerhalb des RenderWindows erstellt.
Das Problem hierbei ist das der Cursor niemals das render Window verlässt.
Ich hab das Ganze nun aber bisher so gelöst das ich folgendes deffiniere:
#if defined OIS_WIN32_PLATFORM pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" ))); pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE"))); pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND"))); pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE"))); #elif defined OIS_LINUX_PLATFORM pl.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("false"))); pl.insert(std::make_pair(std::string("x11_mouse_hide"), std::string("false"))); pl.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false"))); pl.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true"))); #endif
dadurch wird der SystemCursor angezeigt, natürlich auch im RenderWindow ABER man kann mit dem Cursor das RenderWindow verlassen!
Momentan benutze ich folgendes:
bool gameClient::mouseMoved( const OIS::MouseEvent &arg ) { if (mMouse->getMouseState().X.abs <= 0 || mMouse->getMouseState().X.abs >= mMouse->getMouseState().width || mMouse->getMouseState().Y.abs <= 0 || mMouse->getMouseState().Y.abs >= mMouse->getMouseState().height) { showSysCursor(true); outOfWindow = true; //!Reset MouseButtons to Up mTrayMgr->injectMouseUp(arg, OIS::MB_Left); mTrayMgr->injectMouseUp(arg, OIS::MB_Right); mCameraMan->injectMouseUp(arg, OIS::MB_Left); mCameraMan->injectMouseUp(arg, OIS::MB_Right); return false; } else { outOfWindow = false; showSysCursor(false); if (mTrayMgr->injectMouseMove(arg)) return true; mCameraMan->injectMouseMove(arg); return true; } }
um eine Flag zu setzen outOfWindow die nur dann die verarbeitung von Events zulässt wenn sich der Cursor innerhalb des RenderWindows befindet, das Pseudo-Weiterleiten von MouseButton Up events hat übrigens denn sinn das beim Verlassen des RenderWindows automatisch MouseButton UP event bzw dessen verarbeitung eingeleitet wird sonst ergeben sich da Probleme.
Die Funktion , showSysCursor() blendet mir dann beim verlassen des RenderWindows des SystemCursor wieder ein, bzw aus beim betreten des RenderWindows:
void gameClient::showSysCursor(bool visible) { #ifdef _WIN32 CURSORINFO info; info.cbSize = sizeof(CURSORINFO); BOOL gotCursorInfo = GetCursorInfo(&info); while ( gotCursorInfo ) { if ( (visible && info.flags == CURSOR_SHOWING) // visible || (!visible && info.flags == 0 ) ) // hidden { break; } int showResult = ShowCursor(visible); // this only increases an internal display counter in windows, so it might have to be called some more if ( showResult < 0 ) { break; } info.cbSize = sizeof(CURSORINFO); // yes, it really must be set each time gotCursorInfo = GetCursorInfo(&info); } #else //!!!!!x11____if ( Visible ) //!!!!!x11____XDefineCursor( Device->display, mWindow, invisCursor ); //!!!!!x11____else //!!!!!x11____XUndefineCursor( Device->display, Device->window ); #endif }
den X11 part muss ich noch umbauen. aber das ganze klappt dann auch soweit.
Sinn ist halt das der SystemCursor das renderWindow verlassen kann und dann auch als solcher zu sehen ist. und innerhalb des RenderWindows ein benutzerdefinierter Cursor sichtbar wird.
Ich hoffte halt das es eine einfachere Lösung hierfür gibt.
Hoffe das war nun klarer zu verstehen.