DirectX sprite movement seems 'glitchy'

Started by
34 comments, last by Interminable 11 years, 8 months ago
I believe that this is your answer.

If you have a Window of 800x600 for example. The client area is less (eg 792x594 or something like that).

If you have set your D3DPRESENTPARAMETERS to 800 x 600 the DX screen will differ from your actual client area.

So, your sprites will be getting resized to fit and you will definately get the phenomenon that you are having.

If you run full screen, do you have the same problem (I am guessing not).
Advertisement

I believe that this is your answer.

If you have a Window of 800x600 for example. The client area is less (eg 792x594 or something like that).

If you have set your D3DPRESENTPARAMETERS to 800 x 600 the DX screen will differ from your actual client area.

So, your sprites will be getting resized to fit and you will definately get the phenomenon that you are having.

If you run full screen, do you have the same problem (I am guessing not).


You're right, in fullscreen the issue does not appear to be present!

However, when trying to set the present parameters to the client area size, it didn't fix the issue when running it in a window.

This is what I was doing:


RECT tempRect;
GetClientRect(hwndInput, &tempRect);
d3dPresentationParameters.BackBufferWidth = tempRect.right;
d3dPresentationParameters.BackBufferHeight = tempRect.bottom;

[quote name='lonewolff' timestamp='1343649700' post='4964463']
I believe that this is your answer.

If you have a Window of 800x600 for example. The client area is less (eg 792x594 or something like that).

If you have set your D3DPRESENTPARAMETERS to 800 x 600 the DX screen will differ from your actual client area.

So, your sprites will be getting resized to fit and you will definately get the phenomenon that you are having.

If you run full screen, do you have the same problem (I am guessing not).


You're right, in fullscreen the issue does not appear to be present!

However, when trying to set the present parameters to the client area size, it didn't fix the issue when running it in a window.

This is what I was doing:


RECT tempRect;
GetClientRect(hwndInput, &tempRect);
d3dPresentationParameters.BackBufferWidth = tempRect.right;
d3dPresentationParameters.BackBufferHeight = tempRect.bottom;

[/quote]

How are you building your window? You have to do some math in order to get the client size correct by taking into accound the size of the windows border, its been a while since i have programmed that kind of thing, but lets see your window creation.

[quote name='Interminable' timestamp='1343652839' post='4964473']
[quote name='lonewolff' timestamp='1343649700' post='4964463']
I believe that this is your answer.

If you have a Window of 800x600 for example. The client area is less (eg 792x594 or something like that).

If you have set your D3DPRESENTPARAMETERS to 800 x 600 the DX screen will differ from your actual client area.

So, your sprites will be getting resized to fit and you will definately get the phenomenon that you are having.

If you run full screen, do you have the same problem (I am guessing not).


You're right, in fullscreen the issue does not appear to be present!

However, when trying to set the present parameters to the client area size, it didn't fix the issue when running it in a window.

This is what I was doing:


RECT tempRect;
GetClientRect(hwndInput, &tempRect);
d3dPresentationParameters.BackBufferWidth = tempRect.right;
d3dPresentationParameters.BackBufferHeight = tempRect.bottom;

[/quote]

How are you building your window? You have to do some math in order to get the client size correct by taking into accound the size of the windows border, its been a while since i have programmed that kind of thing, but lets see your window creation.
[/quote]

This is what GetClientRect() does, or at least that's my understanding of it. GetWindowRect() would get the size including the border, etc.

EDIT: Interestingly, if I run it fullscreen at a resolution other than my native one (or the one I'm currently on I'm assuming), IDirect3DDevice9::Present() fails, but checking the HRESULT says the operation completed successfully. I have no idea what's wrong there.
Anyway, we are on the right track. We just need to find the correct value of the client area.
I fixed the crashing issue by altering my code to use DirectX's extended functions and structs, ie LPDIRECT3DDEVICE9EX, etc. I also found out how to enable DirectX's special debugging outputs which I recently learned about (I actually did this before converting my code to use extended functions to fix the crashing issue). I also used the debugging output to fix a few memory leaks.

The graphical issue in windowed mode still exists however. I'm wondering though, could it not be a client-area size issue and instead be some rendering process DirectX performs in fullscreen but not in a window?
Nope, It will be the client area size.

You can test this by changing your window class style to WS_EX_TOPMOST | WS_POPUP. This way your client window size will be what you specify (but with no borders).

Nope, It will be the client area size.

You can test this by changing your window class style to WS_EX_TOPMOST | WS_POPUP. This way your client window size will be what you specify (but with no borders).


The issue still exists in windowed mode despite using those styles to remove the borders, title bar, etc.
Any chance you can share your D3DPPRESENTPARAMETERS structure and you windows creation code?
Certainly. Here are the D3DPRESENT_PARAMETERS:


ZeroMemory(&d3dPresentationParameters, sizeof(d3dPresentationParameters));
d3dPresentationParameters.BackBufferFormat = d3dDisplayMode.Format;
d3dPresentationParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dPresentationParameters.Windowed = TRUE;

RECT tempRect;
GetClientRect(hwndInput, &tempRect);
if(d3dPresentationParameters.Windowed == FALSE)
{
d3dDisplayMode.Width = window_width;
d3dDisplayMode.Height = window_height;
}
d3dPresentationParameters.BackBufferWidth = d3dDisplayMode.Width;///*tempRect.right;*/window_width;
d3dPresentationParameters.BackBufferHeight = d3dDisplayMode.Height;///*tempRect.bottom;*/window_height;

if(d3dPresentationParameters.Windowed == FALSE)
{
d3dPresentationParameters.FullScreen_RefreshRateInHz = d3dDisplayMode.RefreshRate;
}
d3dPresentationParameters.EnableAutoDepthStencil = TRUE; // Not sure if needed.
d3dPresentationParameters.AutoDepthStencilFormat = D3DFMT_D16;
d3dPresentationParameters.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;


My window creation code:


Window::Window(const wchar_t *szAppNameImport)
{
szAppName = szAppNameImport;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = NULL;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szAppName;
wc.hIconSm = LoadIcon(wc.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
created = true;
}

VOID Window::Create(LPCWSTR windowTitle,unsigned int window_width, unsigned int window_height, HWND parent)
{
windowRect.left = GetSystemMetrics(SM_CXSCREEN)/2-window_width/2;
windowRect.top = GetSystemMetrics(SM_CYSCREEN)/2-window_height/2;
windowRect.right = window_width;
windowRect.bottom = window_height;
AdjustWindowRect(&windowRect, NULL, NULL); // So we can have the window at the correct size based on the desired client area size.
if(!RegisterClassEx(&wc))
{
throw std::exception();
}

if((mHwnd = CreateWindowEx
(
0,
szAppName,
windowTitle,
WS_EX_TOPMOST | WS_POPUP,//WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
windowRect.left,windowRect.top,
windowRect.right,windowRect.bottom,
GetDesktopWindow(),
NULL,
wc.hInstance,
NULL))==NULL)
{
throw std::exception();
}
SetWindowLongPtr(mHwnd, GWLP_USERDATA, (LONG_PTR)this);
ShowWindow(mHwnd, SW_SHOWDEFAULT);

UpdateWindow(mHwnd);
}

This topic is closed to new replies.

Advertisement