[DirectInput] "Input-Ruckeln"
-
Hi,
ich stehe vor einem interessanten Problem bei dem ich jedoch selbst mit der Doku nicht mehr weiter komme:
Ich habe eine DirectInput-Klasse geschrieben für Tastatur und Maus, nichts großartiges also. Jedoch habe ich dort ständig eine Art Input-Ruckeln. Was bei der Grafikausgabe zu wenig FPS sind, habe ich hier mit dem Input, trotz optimaler FPS von 240.
Zur Erstellung: Ich habe die DirectInput Devices folgendermaßen erstellt:
// TASTATUR____________________________________________ // Tastaturobjekt erstellen if (directInput8_->CreateDevice (::GUID_SysKeyboard, &keyboard_, NULL) != DI_OK) EXCEPTION ("IDirectInput8::CreateDevice(); failed! (Keyboard)"); // Format setzen if (keyboard_->SetDataFormat (&c_dfDIKeyboard) != DI_OK) EXCEPTION ("IDirectInputDevice8::SetDataFormat(); failed! (Keyboard)"); // Kooperativen level setzen if (keyboard_->SetCooperativeLevel (hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE) != DI_OK) EXCEPTION ("IDirectInputDevice8::SetCooperativeLevel(); failed! (Keyboard)"); // Capabilities abfragen für die Tastatur if (keyboard_->GetCapabilities (&caps) != DI_OK) EXCEPTION ("IDirectInputDevice8::GetCapabilities(); failed! (Keyboard)"); // Teste ob Tastatur überhaupt angeschlossen ist! if (!(caps.dwFlags & DIDC_ATTACHED)) EXCEPTION ("Keyboard is currently not attached!"); // Tastatur aktivieren if (keyboard_->Acquire () != DI_OK) EXCEPTION ("IDirectInputDevice8::Acquire(); failed! (Keyboard)"); // MOUSE_______________________________________________ // Tastaturobjekt erstellen if (directInput8_->CreateDevice (::GUID_SysMouse, &mouse_, NULL) != DI_OK) EXCEPTION ("IDirectInput8::CreateDevice(); failed! (Mouse)"); // Format setzen if (mouse_->SetDataFormat (&c_dfDIMouse2) != DI_OK) EXCEPTION ("IDirectInputDevice8::SetDataFormat(); failed! (Mouse)"); // Kooperativen level setzen if (mouse_->SetCooperativeLevel (hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE) != DI_OK) EXCEPTION ("IDirectInputDevice8::SetCooperativeLevel(); failed! (Mouse)"); // Capabilities abfragen für die Maus if (mouse_->GetCapabilities (&caps) != DI_OK) EXCEPTION ("IDirectInputDevice8::GetCapabilities(); failed! (Mouse)"); // Teste ob Maus überhaupt angeschlossen ist! if (!(caps.dwFlags & DIDC_ATTACHED)) EXCEPTION ("Mouse is currently not attached!"); // Maus aktivieren if (mouse_->Acquire () != DI_OK) EXCEPTION ("IDirectInputDevice8::Acquire(); failed! (Mouse)");Funktioniert einwandfrei, lässt sich wunderbar erstellen. Jedoch egal was ich daran verändere (Thema: Flags) das ruckeln geht nicht fort!
Also dachte ich es würde mit dem Updaten zusammen hängen, dass dort zuviel Zeit verschwendet wird, jedoch dort war auch nichts! Und die Profilerergebnisse ergaben das er dort wie Butter durchgeht.
Hier trotzdem mal der Code:
// Haben wir den Fokus für die Eingabe? if ((keyboard_->Acquire() == DIERR_OTHERAPPHASPRIO) || (mouse_->Acquire () == DIERR_OTHERAPPHASPRIO)) { // Nein, also alles auf Default setzen. for (unsigned long i=0; i<256; ++i) currKey_[i] = oldKey_[i] = false; // Maus auf default setzen. ::ZeroMemory (&oldMouseState_, sizeof (::DIMOUSESTATE2)); ::ZeroMemory (&currMouseState_, sizeof (::DIMOUSESTATE2)); // Funktion beenden! return; } // TASTATUR____________________________________________ // Aus neu mach alt: for (unsigned long i=0; i<256; ++i) oldKey_[i] = currKey_[i]; // Status der Tasten abfragen und speichern if((retval = keyboard_->GetDeviceState (sizeof(bool)*256, (void*)&currKey_)) != DI_OK) { DEBUG_STACK; // Fokus verloren? if (retval == DIERR_INPUTLOST) { // Versuchen Fokus wieder zu holen keyboard_->Acquire (); // Status der Tasten abfragen und speichern if (keyboard_->GetDeviceState (sizeof(bool)*256, (void*)&currKey_) != DI_OK) EXCEPTION ("IDirectInputDevice8::GetDeviceState(); failed! (Keyboard)"); } else EXCEPTION ("IDirectInputDevice8::GetDeviceState(); failed! Invalid params. (Keyboard)"); } // MOUSE_______________________________________________ // Aus neu mach alt: ::CopyMemory (&oldMouseState_, &currMouseState_, sizeof (::DIMOUSESTATE2)); // Status der Tasten abfragen und speichern if((retval = mouse_->GetDeviceState (sizeof(::DIMOUSESTATE2), (void*)&currMouseState_)) != DI_OK) { DEBUG_STACK; // Fokus verloren? if (retval == DIERR_INPUTLOST) { // Versuchen Fokus wieder zu holen mouse_->Acquire (); // Status der Tasten abfragen und speichern if (mouse_->GetDeviceState (sizeof(::DIMOUSESTATE2), (void*)&currMouseState_) != DI_OK) EXCEPTION ("IDirectInputDevice8::GetDeviceState(); failed! (Mouse)"); } else EXCEPTION ("IDirectInputDevice8::GetDeviceState(); failed! Invalid params. (Mouse)"); }Und ich weiß wirklich nicht mehr woran es liegen könnte? Ich benutze in der Hauptschleife ebenfalls PeekMessage statt GetMessage.
Ich dachte auch das es evtl. bei meiner Direct3D Anwendung lag, jedoch bei anderen Anwendungen mit anderen GrafikAPIs wie z.B. OpenGL oder DirectDraw das selbe Ergebnis! Auch die Timer für die neuen Positionierungen der Darstellungs-Objekte habe ich ausgewechselt und alle waren in Ordnung. (Getestet mit Profiler und anderen InputAPIs darunter auch die Fensternachrichten Methode)
Selbst in der Dokumentation und in deren Tutorials stand zu diesem Vorfall nichts (der auch bei anderen Auftritt, denen ich die Testprogramme gebe).
Interessanterweise tritt dieser Fehler jedoch extrem stark auf (Man kann nichtmal eine Bitmap mehr per Tastatur bewegen) wenn ich den VSync der Grafik API deaktiviere, lasse ich den VSync an, merkt man es schon aber nicht mehr so extrem stark.
Ich bin für jede konstruktive Theorie offen, die mir bei diesem Problem hilft.
Danke im voraus!
- Patrick
edit: Selbst wenn ich diese if-Abfrage wegen DIERR_OTHERAPPHASPRIO herausnehme, das Problem bleibt bestehen.
-
Hi,
bestimmt eine unnötige Frage aber, machst du sowas
while(1) { if(PeekMessage(usw. )) { ... } }oder eher sowas
while(1) { while (PeekMessage(usw.)) { ... } } ?
-
Generell die 1. Variante, habe jedoch Beide ausprobiert und bei Beiden das selbe Ergebnis: Ruckeln
-
Wa genau fängt den nun an zu ruckeln? Vibriert die Tastatur oder wie soll ich mir das vorstellen?
Bye, TGGC (Keine Macht den Dummen)
-
TGGC
Nehmen wir an ich habe eine Bitmap die ich nach Rechts bewegen will. Ich frage jeden Frame per if ab ob die Rechte Pfeiltaste gedrückt wurde.Addiere auf die X-Position dann seine Geschwindigkeit * VergangeneFrameZeit. Die Bewegung ist einfach nicht "flüssig" sondern sehr ruckartig. Das selbe auch wenn ich die ESCAPE-Taste abfrage um das Programm zu beenden! Irgendwann nach 2 sec. beendet sich das Programm weil es glaubt die Escape-Taste wurde gedrückt.
-
Patrick schrieb:
Generell die 1. Variante, habe jedoch Beide ausprobiert und bei Beiden das selbe Ergebnis: Ruckeln
Hm tja, war nur so eine Idee.
Die erste Variante ist mindestens im Buffered-Mode Müll und ich hatte deswegen mal Ruckler.
Sogar Microsoft macht es übrigens in ihren DI-Samples falsch.
-
Wo ist denn der Unterschied, ob du jeden Frame fragst, dass rechts noch gedrückt ist und das Objekt bewegst, oder ob du es einfach immer bewegst? Wieso also Input-Ruckeln?
Bye, TGGC (Wähle deine Helden)