DirectInput Problem...
-
Hallo liebe Community ich wollte mittels DirectInput einen Cursor malen, aber aus irgendwelchen Gründen bleibt die Mausposition immer gleich...
#include "FInput.h" FInput::FInput() { } FInput::FInput( HWND winHandle ) { WindowHandle = winHandle; MouseX = 400; MouseY = 400; } FInput::~FInput() { } void FInput::Initialize( void ) { if ( DirectInput8Create( GetModuleHandle(0), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**) &DirectInput, 0) != D3D_OK ) { MessageBoxA( 0, "Failed Creating DirectInput8", "Error", MB_OK ); // Error } if (DirectInput->CreateDevice(GUID_SysMouse, (LPDIRECTINPUTDEVICE*)&MouseDevice, NULL) != D3D_OK) { MessageBoxA( 0, "Failed Creating Mouse Device", "Error", MB_OK ); // Error } if ( MouseDevice->SetDataFormat(&c_dfDIMouse) != D3D_OK ) { MessageBoxA( 0, "Failed Setting Data Format", "Error", MB_OK ); // Error } if ( MouseDevice->SetCooperativeLevel(WindowHandle, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND) != D3D_OK ) { MessageBoxA( 0, "Failed Setting Cooperative Level", "Error", MB_OK ); // Error } if ( MouseDevice->Acquire() != D3D_OK ) { MessageBoxA( 0, "Failed to Acquire", "Error", MB_OK ); // Error } } void FInput::Refresh( void ) { DIMOUSESTATE MouseState; memset(&MouseState, 0, sizeof(DIMOUSESTATE)); if ( !MouseDevice ) return; HRESULT result = MouseDevice->GetDeviceState(sizeof(DIMOUSESTATE), &MouseState); if (result != D3D_OK) { MouseDevice->Acquire(); return; } MouseX += MouseState.lX; MouseY += MouseState.lY; } void FInput::GetMousePosition(int &x, int &y) { x = MouseX; y = MouseY; }
#pragma once #include "FInclude.h" LPDIRECT3D9 g_pD3D = NULL; // Used to create the D3DDevice LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering device FGraphics Draw; FInput Input; HRESULT InitD3D( HWND hWnd ) { if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) ) return E_FAIL; D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof( d3dpp ) ); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) ) { return E_FAIL; } Draw = FGraphics( g_pd3dDevice ); Draw.Initalize(); Input = FInput( hWnd ); Input.Initialize(); return S_OK; } VOID Cleanup() { if( g_pd3dDevice != NULL ) g_pd3dDevice->Release(); if( g_pD3D != NULL ) g_pD3D->Release(); } void Render( void ) { if( NULL == g_pd3dDevice ) return; //Input.Refresh(); // Clear the backbuffer to a blue color g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 100, 149, 237 ), 1.0f, 0 ); // Begin the scene if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) { // Rendering of scene objects can happen here int x, y; Input.GetMousePosition( x, y ); Draw.DrawFilledRect( x, y, 10, 10, 0xFFFF0000 ); // End the scene g_pd3dDevice->EndScene(); } // Present the backbuffer contents to the display g_pd3dDevice->Present( NULL, NULL, NULL, NULL ); } LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_DESTROY: Cleanup(); PostQuitMessage( 0 ); return 0; case WM_PAINT: Render(); ValidateRect( hWnd, NULL ); return 0; case WM_MOUSEMOVE: Input.Refresh(); return 0; } return DefWindowProc( hWnd, msg, wParam, lParam ); } INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT ) { // Register the window class WNDCLASSEX wc = { sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle( NULL ), NULL, NULL, NULL, NULL, "Mouse Menu", NULL }; RegisterClassEx( &wc ); // Create the application's window HWND hWnd = CreateWindow( "f", "fd", WS_OVERLAPPEDWINDOW, 100, 100, 1000, 800, NULL, NULL, wc.hInstance, NULL ); // Initialize Direct3D if( SUCCEEDED( InitD3D( hWnd ) ) ) { // Show the window ShowWindow( hWnd, SW_SHOWDEFAULT ); UpdateWindow( hWnd ); // Enter the message loop MSG msg; while( GetMessage( &msg, NULL, 0, 0 ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } } UnregisterClass( "f", wc.hInstance ); return 0; }
Danke schonal im Vorraus
dxlol
-
Ich würde Mouse und Tastatur Input eh nicht über DirectInput lösen, was auch Microsoft mittlerweilen nicht mehr empfiehlt. Du kannst die Position über die Message WM_MOUSEMOVE holen.
http://msdn.microsoft.com/en-us/library/ms645616(VS.85).aspx
Da befindet sich die Mausposition im lParam. (siehe Link, wie du das ausliest).
-
drakon schrieb:
Ich würde Mouse und Tastatur Input eh nicht über DirectInput lösen, was auch Microsoft mittlerweilen nicht mehr empfiehlt.
Aus reiner Neugier, aus welcher Quelle hast Du das? ..und falls es jemand weiß, wieso ist das so? Was ist schlecht an DInput?
-
iop schrieb:
drakon schrieb:
Ich würde Mouse und Tastatur Input eh nicht über DirectInput lösen, was auch Microsoft mittlerweilen nicht mehr empfiehlt.
Aus reiner Neugier, aus welcher Quelle hast Du das? ..und falls es jemand weiß, wieso ist das so? Was ist schlecht an DInput?
Lies dich mal ein weing hier ein:
http://msdn.microsoft.com/en-us/library/bb206292(VS.85).aspxDirect Input ist grundsätzlich nichts schlechtes. Wenn du lediglich Maus und Tastatur brauchst, dann benutzt du besser das Message System. Wenn du allerdings auch andere Controler hast, dann benutzt du dafür Direct Input.
-
drakon schrieb:
Lies dich mal ein weing hier ein:
http://msdn.microsoft.com/en-us/library/bb206292(VS.85).aspxKenn ich, habe DInput schon benutzt, deshalb ja auch meine Neugier
drakon schrieb:
Wenn du lediglich Maus und Tastatur brauchst, dann benutzt du besser das Message System.
Also ich denke, das stimmt soweit für einfach Anwendungen, in denen man Maus und Tastatur wirklich nicht mehr beansprucht als in "normalen" Programmen wie zB Word.
Für Spiele sehe ich es zB als Vorteil an, alle Buttons frei belegbar zu haben und außerdem finde ich den Gedanken, per DInput Windows zu umgehen und durch die Hardwarenahe Schnittstelle schneller zu sein, richtig spannend.....auch wenn ich noch nie einen Zeitunterschied gemerkt und gemessen habe.
..naja, man kann sich wahrscheinlich drüber streiten.Edit: Habe gerade mal hier http://www.directxtutorial.com/ geguckt wegen eines Tutorials zum Vergleich, der schreibt jetzt was von Raw Input.. vielleicht sollte ich mich nochmal einlesen...
Um mal zum Thema auch etwas beizutragen:
@dxlol, hast Du schon einmal im Debugger geschaut, was mit den Mauskoordinaten passiert, wenn Du in Zeile 62 einen Haltepunkt setzt? Wenn ich Dich richtig verstehe, werden nur die Koordinaten nicht geändert, das heißt, die Draw-Funktion ist Zeile 64 ist soweit in Ordnung?!
Schau Dir doch mal im Vergleich das Mouse Sample aus der DX Doku an, oder das hier http://www.two-kings.de/tutorials/dinput/dinput03.html um noch eine Alternative zum oberen Link zu zeigen - wenn Du das durcharbeitest, kommst Du bestimmt auf das Problem, das wird Dir wohl keiner abnehmen
-
iop schrieb:
Für Spiele sehe ich es zB als Vorteil an, alle Buttons frei belegbar zu haben und außerdem finde ich den Gedanken, per DInput Windows zu umgehen und durch die Hardwarenahe Schnittstelle schneller zu sein, richtig spannend...
..auch wenn ich noch nie einen Zeitunterschied gemerkt und gemessen habe.
..naja, man kann sich wahrscheinlich drüber streiten.DirectInput umgeht Windows nicht, es öffnet schlicht einen thread und liest WM_INPUT aus und setzt damit auf RAWINPUT auf. Es ist damit also auch nicht schneller.
MS schreibt darüber übrigends hier im Absatz DirectInput
http://msdn.microsoft.com/en-us/library/bb206183(VS.85).aspx
Außerdem nachzulesen hier, das DirectInput nichtmehr Empfohlen wird.
http://msdn.microsoft.com/en-us/library/bb219802(VS.85).aspxSofern du also keinen Joystick hast, beid enenn kenne ich mich nciht aus, biste mit RAWINPUT besser dran. Und was die Freie Belegung angeht, das is am Ende auch nur ne Interne Sache die man auch gut selber machen kann.
-
Das Problem ist, du rufst nirgendwo deine Refresh-Methode auf.
In der Renderfunktion ist sie ausgeklammert.void Render( void ) { if( NULL == g_pd3dDevice ) return; // ----------------------------------------------------------------- //Input.Refresh(); // <-------------------------------------------- // ----------------------------------------------------------------- // Clear the backbuffer to a blue color g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 100, 149, 237 ), 1.0f, 0 );
EDIT:
Oh, hatte nicht gesehen, dass du diese Methode bei einer WM_MOUSEMOVE Methode aufrufst.Ich hatte aber auch schon das eine oder andere Mal Probleme als ich versuchte DirectX - Kram mit der Windows-Callback funktion zu verbinden.
Auch wenn ich es mir nicht erklären konnte.Naja, auf jeden Fall ist meine Vorgehensweise deiner ziemlich ähnlich und bei mir funktioniert es.
Wenn das mit dem Input korrekt ist, könnte ich mir vorstellen, dass die Renderfunktion gar nicht oft genug aufgerufen wird, da sie ja nur ausgeführt wird, wenn eine WM_PAINT nachricht auftritt.
Testen kannst du das in dem du einfach mal ein wenig die Maus bewegst und das Fenster dann kurz minimierst und wieder maximierst. Die Position des Cursors sollte sich dann geändert haben.
Um das Problem zu beheben könntest du deine Programmschleife ein wenig verändern.while(msg.message != WM_QUIT) { if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { Render(); } }
anstelle von
while( GetMessage( &msg, NULL, 0, 0 ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); }
-
Ja, danke an alle
So siehts nun aus bei mir
MSG msg; while( GetMessage( &msg, NULL, 0, 0 ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); Update(); Render(); }
dxlol