I'm using Win32 messages to capture keyboard movement. Whenever my WndProc recieves a WM_KEYDOWN message, i move the camera by 1 unit. However, this causes the camera to 'jump' positions and not move smoothly. I don't understand why this is happening?
Input and smooth movement?
I already use the elapsed time to regulate movement. When i move the camera inside the rendering loop, the movement is smooth. The problem is when i move the camera inside the WndProc function. The camera sorts of suddenly jerks into movement.
I think that is due to the fact that windows API messages are not necessarily called at say 60FPS or however frames your game is running at. I am not going to say that it belongs in the rendering loop as you should have your rendering and update logic separate but I think it is better suited there than in the windows function.
I would check how your processing your message pump, you might be only processing 1 windows message per frame.
Make sure its like this:
Make sure its like this:
for(;;) //message pump
{
//look for a message
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
//check that we arent quitting
if(msg.message==WM_QUIT) break;
//translate message
TranslateMessage(&msg);
//dispatch message
DispatchMessage(&msg);
}
else
{
if ( Program_Running() == 0) // good call
{
}
else //bail out we had a error
{
MessageBox(NULL, "Failed in Program_Running()" , "Fatal Error", MB_OK);
PostQuitMessage(99);
}
}
}
My loop is the same.
Game loop
WndProc
Game loop
void Renderer::StartRendering()
{
MSG msg;
while (true)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if(msg.message == WM_QUIT)
break;
}
mImmediateContext->ClearRenderTargetView(mRenderTargetView, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));
mImmediateContext->ClearDepthStencilView(mZBuffer, D3D11_CLEAR_DEPTH, 1.0f, 0);
if (mFrameListener)
if (!mFrameListener->OnRenderStart())
break;
mSwapChain->Present(0, 0);
}
}
WndProc
LRESULT Framework::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_KEYDOWN:
{
if (wParam == 'S')
{
mCamera->TransZ(-1);
}
else if (wParam == 'D')
{
mCamera->TransX(1);
}
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(mhWnd, uMsg, wParam, lParam);
}
Your code below will check peekmessage() 1 time per render frame, you need to make it a if else and only render if there is no windows message.
It should be like this: (edit sorry for formatting)
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if(msg.message == WM_QUIT)
break;
}
It should be like this: (edit sorry for formatting)
void Renderer::StartRendering()
{
MSG msg;
while (true)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if(msg.message == WM_QUIT)
break;
}
else
{
mImmediateContext->ClearRenderTargetView(mRenderTargetView, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));
mImmediateContext->ClearDepthStencilView(mZBuffer, D3D11_CLEAR_DEPTH, 1.0f, 0);
if (mFrameListener)
if (!mFrameListener->OnRenderStart())
break;
mSwapChain->Present(0, 0);
}
}
}
Instead of responding to input directly in your WndProc, collect a list of active keys. Update this list whenever you get a KEYUP or KEYDOWN message. Then, in your game logic, check the list of currently-pressed keys and update your camera position each game frame using that information. Should solve your problem.
More details here if you're interested.
More details here if you're interested.
Sorry i should have said so, but i already tried to add the 'else' statement. Didn't work.
EDIT: ApochPiQ, yes i know i can do that. I was just wondering why WndProc behaves like i described. Am i doing it wrong or what?
EDIT: ApochPiQ, yes i know i can do that. I was just wondering why WndProc behaves like i described. Am i doing it wrong or what?
Sorry i should have said so, but i already tried to add the 'else' statement. Didn't work.
, you still should process all of your windows messages every frame =p
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement