Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


DirectX sprite movement seems 'glitchy'


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
35 replies to this topic

#21 DarkRonin   Members   -  Reputation: 613

Like
0Likes
Like

Posted 30 July 2012 - 06:01 AM

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

Sponsor:

#22 Interminable   Members   -  Reputation: 127

Like
0Likes
Like

Posted 30 July 2012 - 06:53 AM

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;

Edited by Interminable, 30 July 2012 - 06:54 AM.


#23 JWBaker   Members   -  Reputation: 235

Like
0Likes
Like

Posted 30 July 2012 - 08:56 AM


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;


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.

#24 Interminable   Members   -  Reputation: 127

Like
0Likes
Like

Posted 30 July 2012 - 08:59 AM



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;


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.


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.

Edited by Interminable, 30 July 2012 - 09:46 AM.


#25 DarkRonin   Members   -  Reputation: 613

Like
0Likes
Like

Posted 30 July 2012 - 03:56 PM

Anyway, we are on the right track. We just need to find the correct value of the client area.

#26 Interminable   Members   -  Reputation: 127

Like
0Likes
Like

Posted 31 July 2012 - 09:03 AM

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?

#27 DarkRonin   Members   -  Reputation: 613

Like
0Likes
Like

Posted 31 July 2012 - 03:41 PM

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

#28 Interminable   Members   -  Reputation: 127

Like
0Likes
Like

Posted 31 July 2012 - 05:11 PM

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.

Edited by Interminable, 31 July 2012 - 05:13 PM.


#29 DarkRonin   Members   -  Reputation: 613

Like
0Likes
Like

Posted 31 July 2012 - 06:14 PM

Any chance you can share your D3DPPRESENTPARAMETERS structure and you windows creation code?

#30 Interminable   Members   -  Reputation: 127

Like
0Likes
Like

Posted 01 August 2012 - 05:11 AM

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);
}

Edited by Interminable, 01 August 2012 - 05:11 AM.


#31 DarkRonin   Members   -  Reputation: 613

Like
0Likes
Like

Posted 01 August 2012 - 05:33 AM

You haven't specified a window style in AdjustWindowRect() and you are also only assuming that the call succeeded as there is no error checking there.

And these don't match the calculated window size because it should be 'Windowed==TRUE'

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;


#32 Interminable   Members   -  Reputation: 127

Like
0Likes
Like

Posted 01 August 2012 - 06:14 AM

That 'd3dPresentationParameters.Windowed == FALSE' was an unfortunate typo, sorry about that. Changing it to what it was supposed to be, TRUE, means that sprites now properly move across the screen in windowed mode without the borders.

As for AdjustClientRect()...if memory serves it used to work fine for what I was using it for without any styles being specified, however I'm not sure I was using it with DirectX. I have a feeling it may just be left over. It doesn't appear to actually do anything, I can comment it out entirely or specify the styles I'm using and it makes no difference to the issue with borders displayed.

The altered code for window creation:

if(!AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN/*WS_EX_TOPMOST | WS_POPUP*/, NULL)) // So we can have the window at the correct size based on the desired client area size.
{
  logWindow.AddLogEntry(3, TEXT("AdjustWindowRect() FAILED"), GetLastError());
  MessageBox(mHwnd, TEXT("AdjustWindowRect() failed!  This program will now close."), TEXT("CRITICAL FAILURE"), MB_OK | MB_ICONERROR | MB_TOPMOST);
  GlobalFunctions::CheckCriticalExit();
}

if(!RegisterClassEx(&wc)) // Has a pointer to wc, above.
{
  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();
}


#33 DarkRonin   Members   -  Reputation: 613

Like
0Likes
Like

Posted 01 August 2012 - 03:42 PM

So, things are now displaying correctly in a borderless window?

#34 Interminable   Members   -  Reputation: 127

Like
0Likes
Like

Posted 01 August 2012 - 06:07 PM

So, things are now displaying correctly in a borderless window?


They appear to be, yes.

#35 Interminable   Members   -  Reputation: 127

Like
0Likes
Like

Posted 02 August 2012 - 03:31 AM

I worked out I was not making proper use of the values AdjustWindowRect() was setting. So now my sprites can move horizontally across the screen in bordered mode and look fine, but there's a problem: Everything looks squashed and sprites moving vertically still have the issue, because it's adjusting the top by -30 pixels and the left by -8 (because of the title bar). Ideally I'd like to have the window sized so that stuff within it is not squashed, unfortunately if I do it:

windowRect.right - windowRect.left,
windowRect.bottom - windowRect.left,

It looks fine and sprites move perfectly when moving horizontally, but the issue still exists when they move up or down.

I think this may be about solved now though, I just want to try and get the window sized correctly so sprites are not stretched and at the same time have their movement appear glitch free.

Edited by Interminable, 02 August 2012 - 03:57 AM.


#36 Interminable   Members   -  Reputation: 127

Like
-1Likes
Like

Posted 05 August 2012 - 04:11 AM

So I didn't touch my code for a couple of days, but I'm SURE it was working. However I've come back to it to try and fix the sizing issue once and for all but when I ran it (without changing anything today), it looks like this:

Posted Image

To clarify, the purple sprite should have the red and white dotted line on the top only, not the bottom, and part of it seems to have been spliced part way across the screen. Does anyone have any ideas what I may have changed to cause this? I've not touched the vertices aspects of the code, etc for a while as I've been working on the client width thing. So far I can't think what I've done wrong.

EDIT: I've found what was causing it, it's because I'd force-enabled anti-aliasing with the Catalyst Control Center (for something else). It seems my application didn't like that. :S

Setting it back to Application Preference fixed it.


EDIT2: I'm still struggling with trying to get the damned client size correct though.

I first have a RECT with the following:

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

Which sets the values:

left = 328
top = 141
right = 1024
bottom = 768

Following AdjustWindowRect() being called with the following arguments:

AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN/*WS_EX_TOPMOST | WS_POPUP*/, NULL)

Which adjusts the original values to the following:

left = 320
top = 111
right = 1032
bottom = 776

The window is then created using those values like this:

CreateWindowEx
   (
   0,
   szAppName,
   windowTitle,
   WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
   windowRect.left,
   windowRect.top,
   windowRect.right,
   windowRect.bottom,
   GetDesktopWindow(),
   NULL, 
   wc.hInstance,
   NULL))==NULL)

Then, in my rendering code I have:

d3dDisplayMode.Width = window_width;
d3dDisplayMode.Height = window_height;

d3dPresentationParameters.BackBufferWidth = d3dDisplayMode.Width;
d3dPresentationParameters.BackBufferHeight = d3dDisplayMode.Height;

(window_width is still 1024 and window_height is still 768).

The issue still exists with what I'm doing here, but I'm not sure what I'm doing wrong. The client area SHOULD be 1024x768, which is what I should be setting d3dDisplayMode.Width and d3dDisplayMode.Height with, and d3dPresentationParameters.BackBufferWidth and d3dPresentationParameters.BackBufferHeight with, right?

I cannot see where I'm going wrong.

Edited by Interminable, 05 August 2012 - 05:10 AM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS