Sign in to follow this  
utilae

When moving object around it moves smoothly but with jaggies and refresh artifiacts

Recommended Posts

Hi, I am using C++ and Direct3D9. When I move an object around on the screen at speed, I get the jaggies and refresh artifacts (possible blurring). Putting Vertical Sync on fixes this and makes it smooth, but everything is slow and the mouse movement is 'late' in terms of where you direct it. So V_Sync is not an option. I am working on a laptop with a good graphics card. The refresh rate is at 60Hz and I notice that when I move a notepad window around in windows xp sp2 it also does the same thing. But when playing games, ie guild wars, its perfect, no jaggies etc. So is this common for laptops? Would all games made for laptops do this. Or is there some way to cater for those on laptops. Edit: ok Guild Wars is using wait for vertical sync, but it is not as slow as my program when my program uses vertical sync. Help?

Share this post


Link to post
Share on other sites
What you are experiencing is called "tearing". It is unavoidable if you are not synching with vertical retrace.

I'm not sure why everything slows down when you turn on vsync. Are you moving things a fixed distance per frame or a fixed distance per second? When you turn on vsync, you may be slowing down the frame rate (to match the refresh rate) and if you are moving a fixed amount per frame that will also slow down movement. In that case, your movement should be based on time instead.

Share this post


Link to post
Share on other sites
Yeah, I have implemented what I think is a time based game loop, but I don't know if it is working properly. I am pretty sure I have the interpolation part working. The main point of issue is the ticks per second and max frame skip. I'm not sure what those two are. I guess the ticks per second is the frames per second, cause if i set it to 60 or 120 I can move the mouse faster with vertical sync but it still is slow.

The game loop is based on this article:
http://dewitters.koonsolo.com/gameloop.html
"Fixed Update and Variable Rendering"

//message pump
MSG msg;
//start game with the Game_Core gamestate
if(Game_Core_Load()==false) return(0);

//set game state pointers to initial game states
sCurrentGameState="Game_Core";
fnptrCurrentUpdateGameState=Game_Core_Update;
fnptrCurrentRenderGameState=Game_Core_Render;

//frame rate indepenent game loop variables
const int nTICKS_PER_SECOND=25;
const int nSKIP_TICKS=1000 / nTICKS_PER_SECOND;
const int nMAX_FRAMESKIP=5;
DWORD dwNextGameTick=timeGetTime();
int nLoops=0;
float fInterpolation=0;

//GAME LOOP
while(true)
{
//PEEK MESSAGE
//look for a message
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))//there is a message
{
if(msg.message==WM_QUIT) break;//quit if that is the message
TranslateMessage(&msg);//translate message
DispatchMessage(&msg);//dispatch message
}

//FRAME RATE INDEPENDENT GAME LOOP
//fixed update
nLoops=0;
while(timeGetTime() > dwNextGameTick && nLoops < nMAX_FRAMESKIP)
{
//current update gamestate
fnptrCurrentUpdateGameState();

dwNextGameTick += nSKIP_TICKS;
nLoops++;
}
//need other while loops for different updates at different speeds

//variable render
fInterpolation=float(timeGetTime() + nSKIP_TICKS - dwNextGameTick) / float(nSKIP_TICKS);
fnptrCurrentRenderGameState(fInterpolation);//current render gamestate
}
Game_Core_Unload();//clean up program data
return(msg.wParam);//return the wparam from the WM_QUIT message

Share this post


Link to post
Share on other sites
what are you using to capture mouse movement?

the tearing can sometimes be solved by lowering fps down to around 60, but it depends on the monitor as well. All computers do this, v sync is the only way to fix it, but that usually puts fps max at 60.

Share this post


Link to post
Share on other sites
Activating Vertical Sync defintatly removes the tearing. But the problem I guess is that it makes the mouse and other things go slow. Most notably the mouse, since upon moving it really fast, it is 'late' and gets to its destination slower then it would in windows or without vertical sync.

In my game loop, by putting the const int nTICKS_PER_SECOND=60; or =120; the mouse moves faster, but it still slower then I would like. In guild wars, with vertical sync on the mouse seems to move as it should, really fast and really responsive.



For mouse movement I hide the mouse cursor and use an image (D3DXSprite) in its place. So I can set my own mouse icons.

In the windows procedure I do this:

case WM_MOUSEMOVE:
{
//mouse has moved
GUIManager.m_pMouse->UpdateCurrentPos();
}break;
case WM_LBUTTONDOWN:
{
//left button is down
GUIManager.m_pMouse->SetMouseState(1);
}break;
case WM_LBUTTONUP:
{
//left button is up
GUIManager.m_pMouse->SetMouseState(2);
}break;
case WM_RBUTTONDOWN:
{
//right button is down
GUIManager.m_pMouse->SetMouseState(3);
}break;
case WM_RBUTTONUP:
{
//right button is up
GUIManager.m_pMouse->SetMouseState(4);
}break;




In the GUIManager.m_pMouse->UpdateCurrentPos() function the code is basically this:

//get mouse position on screen
POINT ptMousePos;
GetCursorPos(&ptMousePos);

//calculate current mouse position
m_ptCurrentMousePos.x=ptMousePos.x-16+m_ptHotSpot.x;
m_ptCurrentMousePos.y=ptMousePos.y-16+m_ptHotSpot.y;

//update screen rect position
m_recPos.top=ptMousePos.y-16;
m_recPos.left=ptMousePos.x-16;
m_recPos.right=m_recPos.left+32;
m_recPos.bottom=m_recPos.top+32;


Share this post


Link to post
Share on other sites
the problem is using WM_MOUSEMOVE:

Don't call your function in that, just take it out of that case statement and call it every frame (doesn't matter where you place it really).

windows messages are known for being slow.

and if you wan't to increase your click speed (usually this isn't an issue on windows messages, but just in case)

use

GetAsyncKeyState(VK_LBUTTON) etc

doesn't capture mouse wheel movements :(

going to need to use case WM_MOUSEWHEEL:

unless you switch completely over to directx input.

ALSO:

change your
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))//there is a message

too:

while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))//there is a message

reason:
windows can send more than 1 message at a time to your application during a update in your game loop, using if, you can only update 1 message at a time.
using while will process all available messages during a loop.


Share this post


Link to post
Share on other sites
Ok, so I took the update mouse function out of teh WM_MOUSEMOVE case and put it in the GUI update loop. Now (with VSync) when I put the game loop ticks per second at 120, the mouse goes blazing fast, which is excellent, so thats that problem solved.

EDIT: Ok, thank you. Problem sorted.

[Edited by - utilae on February 23, 2008 3:06:02 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this