[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)


Anmelden zum Antworten