PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress( "wglSwapIntervalEXT" );
if(wglSwapIntervalEXT) {
wglSwapIntervalEXT(1);
} else {
std::cout << "No vsync";
}
I am using win32 api for my window.
My movement is based on deltaTime.
I am using the QueryPerformanceCounter to calculate the deltaTime.
Am I missing something here? I haven't been able to find any difference between my vsync code and other peoples'.
Thanks.
Jerky movement when vsync turned on (wglSwapIntervalEXT).
Hi,
I've been searching previous posts here, but I can't find anything to explain my problem.
My problem is that with vsync on, my movement is very jerky.
I enabled vsync in my program like so:
You need to interpolate between one frame to the next or else you will always have jerky motion even if you are moving based on delta time.
I have a video in the Physics series that describes this in details (see space ship motion).
I have a video in the Physics series that describes this in details (see space ship motion).
Like if I move forward it will freeze for a quarter of a second and then move, though for some reason it seems to be doing with less frequency now.
My movement code is:
My timer is:
Edit:
I just noticed that the jerkiness stopped when I outputted text to the console window every loop.
My movement code is:
float walk = (keyDown(VkKeyScan(k[0]))?-1.0f:0.0f)+ (keyDown(VkKeyScan(k[2]))?1.0f:0.0f);float strafe = (keyDown(VkKeyScan(k[1]))?-1.0f:0.0f)+ (keyDown(VkKeyScan(k[3]))?1.0f:0.0f);Vector3 dir = camera.front*walk*-1.0f + camera.right*strafe;if(dir.length2()) { camera.position += dir.normalise()*6.0f*dt;}
My timer is:
QueryPerformanceCounter((LARGE_INTEGER*)&startTime); /*game run code*/_int64 freq;QueryPerformanceFrequency((LARGE_INTEGER*)&freq);_int64 stopTime;QueryPerformanceCounter((LARGE_INTEGER*)&stopTime);dt = (startTime)?float(stopTime-startTime)/(float)freq:0;
Edit:
I just noticed that the jerkiness stopped when I outputted text to the console window every loop.
are you by chance moving the mouse whilst the jerkiness occurs?
Ive noticed that.
Also try a difference timer than QueryPerformanceFrequency, eg timeGetTime() + report back here your results
cheers zed
Ive noticed that.
Also try a difference timer than QueryPerformanceFrequency, eg timeGetTime() + report back here your results
cheers zed
Yeah I've got that problem too.
Ok I'll let you know when I get home.
Quote:Original post by zedz
Also try a difference timer than QueryPerformanceFrequency, eg timeGetTime() + report back here your results
cheers zed
Ok I'll let you know when I get home.
Ok so same problem with using timeGetTime().
Also the problem is more like this:
* moving the mouse seems a little shakey or jerky, but not too bad
* movement pauses for a moment every now and then, and then jumps forward to pos+=movementDir*deltaTime
* when I output the dt every loop to console, the jumping on the movement seems to disapear
* with vsync off I get finer movements, and not so with it on
I'll post most of the related code:
This is my winmain code
And this is my movement code
The camera code is just
Also the Main::run() is
Thanks.
[Edited by - andrew111 on August 15, 2009 12:24:27 AM]
Also the problem is more like this:
* moving the mouse seems a little shakey or jerky, but not too bad
* movement pauses for a moment every now and then, and then jumps forward to pos+=movementDir*deltaTime
* when I output the dt every loop to console, the jumping on the movement seems to disapear
* with vsync off I get finer movements, and not so with it on
I'll post most of the related code:
This is my winmain code
/*#if defined(_DEBUG)#define CRTDBG_MAP_ALLOC#include <stdlib.h>#include <crtdbg.h>#endif*/#pragma comment(linker, "/subsystem:\"console\" /entry:\"WinMainCRTStartup\"")#include <windows.h>#include <GL/gl.h>#include "Timer.h"#include "Main.h"#include "Window.h"#include <iostream>#include "wglext.h"//HWND windowHandle;//RECT clientRect;RECT windowRect;//BYTE keyState[256];BYTE keyPrevState[256];//POINT cursor = {0,0};POINT prevCursor = {0,0};float mx = 0, my = 0;//Timer timer;//bool lockCursorEnabled = false;////int Window::clientWidth() { return clientRect.right;}int Window::clientHeight() { return clientRect.bottom;}//bool Window::keyDown(int key) { return (keyState[key] & 0x80) && 1;}bool Window::keyUpped(int key) { return (!(keyState[key] & 0x80) && (keyPrevState[key] & 0x80));}bool Window::keyDowned(int key) { return ((keyState[key] & 0x80) && !(keyPrevState[key] & 0x80));}//int Window::cursorX() { return cursor.x;}int Window::cursorY() { return cursor.y;}//float Window::mouseMoveX() { return mx;}float Window::mouseMoveY() { return my;}//float Window::deltaTime() { return timer.get();}//int Window::left() { return windowRect.left;}int Window::top() { return windowRect.top;}int Window::width() { return windowRect.right-windowRect.left;}int Window::height() { return windowRect.bottom-windowRect.top;}//void Window::lockCursor(bool enabled) { lockCursorEnabled = enabled; if(!enabled) { ClipCursor(0); }}//LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { //for mouse move if(msg == WM_INPUT) { UINT dwSize = 40; static BYTE lpb[40]; GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)); RAWINPUT* raw = (RAWINPUT*)lpb; if (raw->header.dwType == RIM_TYPEMOUSE) { int x =raw->data.mouse.lLastX; int y = raw->data.mouse.lLastY; mx = (float)x; my = (float)y; } } static bool in = false; if(msg == WM_MOUSEMOVE) { in = true; } if(msg == WM_MOUSELEAVE) { in = false; } //escape key if(msg == WM_KEYDOWN && wParam == VK_ESCAPE) { DestroyWindow(hWnd); } // if(msg == WM_KEYDOWN && wParam == VK_CONTROL) { } //close button if(msg == WM_DESTROY) { PostQuitMessage(0); return 0; } // return DefWindowProc(hWnd, msg, wParam, lParam);}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { /*#if defined(_DEBUG) _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)|_CRTDBG_DELAY_FREE_MEM_DF|_CRTDBG_LEAK_CHECK_DF); #endif*/ // const char title[] = "title"; int windowWidth = 1024; int windowHeight = 800; //desktop size RECT desktopRect; GetWindowRect(GetDesktopWindow(), &desktopRect); //init window WNDCLASS wc = {CS_CLASSDC|CS_DBLCLKS, WndProc, 0, 0, hInstance, 0, LoadCursor(0, IDC_ARROW), 0, 0, "abc"}; RegisterClass(&wc); windowHandle = CreateWindow(wc.lpszClassName, title, WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_THICKFRAME|WS_VISIBLE, (desktopRect.right-windowWidth)/2/*CW_USEDEFAULT*/, (desktopRect.bottom-windowHeight)/2/*CW_USEDEFAULT*/, windowWidth, windowHeight, 0, 0, hInstance, 0); //window dc HDC windowDc = GetDC(windowHandle); //for mouse move RAWINPUTDEVICE Rid[1]; Rid[0].usUsagePage = 0x01; //HID_USAGE_PAGE_GENERIC Rid[0].usUsage = 0x02; //HID_USAGE_GENERIC_MOUSE Rid[0].dwFlags = RIDEV_INPUTSINK; Rid[0].hwndTarget = windowHandle; RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])); //init opengl PIXELFORMATDESCRIPTOR pfd; ZeroMemory( &pfd, sizeof(pfd)); pfd.nSize = sizeof(pfd); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; pfd.cDepthBits = 16; pfd.iLayerType = PFD_MAIN_PLANE; int iFormat = ChoosePixelFormat(windowDc, &pfd); SetPixelFormat(windowDc, iFormat, &pfd); SwapBuffers(windowDc); HGLRC rc = wglCreateContext(windowDc); wglMakeCurrent(windowDc, rc); //turn on vsync PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress( "wglSwapIntervalEXT" ); PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC) wglGetProcAddress("wglGetSwapIntervalEXT"); if(!wglSwapIntervalEXT) { std::cout << "No vsync"; } else { wglSwapIntervalEXT(1); std::cout << "vsync " << wglGetSwapIntervalEXT() << std::endl; } // //init key state ZeroMemory(keyState, sizeof(keyState)); ZeroMemory(keyPrevState, sizeof(keyPrevState)); // if(Main::create()) { // MSG msg; ZeroMemory(&msg, sizeof(msg)); while(msg.message != WM_QUIT) { if(IsIconic(windowHandle) || (GetForegroundWindow() != windowHandle /*&& GetForegroundWindow() != GetConsoleWindow()*/)) { if(GetMessage(&msg, 0,0,0) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); } // ClipCursor(0); // //mx = 0; //my = 0; } else { if(PeekMessage(&msg, 0,0,0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { // timer.stop(); //edit timer.start(); // GetClientRect(windowHandle, &clientRect); GetWindowRect(windowHandle, &windowRect); //keystate memcpy(&keyPrevState, &keyState, sizeof(keyPrevState)); GetKeyboardState(keyState); //cursor if(!lockCursorEnabled) { prevCursor = cursor; GetCursorPos(&cursor); ScreenToClient(windowHandle, &cursor); } // if(lockCursorEnabled) { POINT clientTopLeft = {0,0}; POINT clientBottomRight = {clientRect.right, clientRect.bottom}; ClientToScreen(windowHandle, &clientTopLeft); ClientToScreen(windowHandle, &clientBottomRight); RECT clipRect; SetRect(&clipRect, clientTopLeft.x, clientTopLeft.y, clientBottomRight.x, clientBottomRight.y); ClipCursor(&clipRect); POINT clientMid = cursor;//{clientRect.right/2, clientRect.bottom/2}; ClientToScreen(windowHandle, &clientMid); SetCursorPos(clientMid.x, clientMid.y); } // if(!Main::run()) { break; } // mx=0; my=0; // SwapBuffers(windowDc); } } } } // Main::destroy(); //cleanup opengl wglMakeCurrent(0, 0); wglDeleteContext(rc); // ReleaseDC(windowHandle, windowDc); // OutputDebugString("\nexited.\n\n"); //system("pause"); return 0;}
And this is my movement code
void runPlayer() { static bool mouseView = false; static bool mouseRightView = false; int lookKey = VK_LBUTTON; int heightKey = VK_RBUTTON; if(Window::keyDowned(lookKey) || Window::keyDowned(heightKey)) { Window::lockCursor(true); ShowCursor(false); } if(Window::keyUpped(lookKey) || Window::keyUpped(heightKey)) { Window::lockCursor(false); ShowCursor(true); } if(Window::keyDowned(lookKey)) { mouseView = true; } if(Window::keyUpped(lookKey)) { mouseView = false; } if(Window::keyDowned(heightKey)) { mouseRightView = true; } if(Window::keyUpped(heightKey)) { mouseRightView = false; } const char *k = "esdf" // "wasd" ; // float walk = (Window::keyDown(VkKeyScan(k[0]))?-1.0f:0.0f)+ (Window::keyDown(VkKeyScan(k[2]))?1.0f:0.0f); float strafe = (Window::keyDown(VkKeyScan(k[1]))?-1.0f:0.0f)+ (Window::keyDown(VkKeyScan(k[3]))?1.0f:0.0f); Vector3 dir = camera.front*walk*-1.0f + camera.right*strafe; if(mouseRightView) { dir.y = 0; } if(dir.length2()) { camera.position += dir.normalise()*((Window::keyDown(VK_SHIFT))?26.0f:13.0f)*Window::deltaTime(); } const float lookSpeed = 3.0f; camera.rotateAngle += ((Window::keyDown(VK_UP)?1.0f:0.0f)+ (Window::keyDown(VK_DOWN)?-1.0f:0.0f))*lookSpeed*Window::deltaTime(); camera.aroundAngle += ((Window::keyDown(VK_LEFT)?1.0f:0.0f)+ (Window::keyDown(VK_RIGHT)?-1.0f:0.0f))*lookSpeed*Window::deltaTime(); static float yawVel = 0; static float pitchVel = 0; if(mouseView || mouseRightView) { camera.aroundAngle -= (float)Window::mouseMoveX()*lookSpeed*Window::deltaTime();//*0.5f; camera.rotateAngle -= (float)Window::mouseMoveY()*lookSpeed*Window::deltaTime();//*0.5f; } const float pi2 = 1.5707f; if(camera.rotateAngle > pi2) { camera.rotateAngle = pi2; } if(camera.rotateAngle < -pi2) { camera.rotateAngle = -pi2; } camera.calculate();}
The camera code is just
Camera::Camera(): transform(4), aroundAngle(0), aroundBack(0), rotateAngle(0){ transform.setIdentity();}void Camera::calculate() {Camera::Camera(): transform(4), aroundAngle(0), aroundBack(0), rotateAngle(0){ transform.setIdentity();}void Camera::calculate() { Matrix positionMat(4), rotateMat(4), aroundMat(4), aroundBackMat(4); positionMat.setPosition(position); rotateMat.setRotation(rotateAxis, rotateAngle); aroundMat.setRotation(aroundAxis, aroundAngle); aroundBackMat.setPosition(Vector3(0,0,aroundBack)); transform = (positionMat*(aroundMat*aroundBackMat))*rotateMat; // front = transform.getZAxis()*-1.0f; at = position + front; right = transform.getXAxis(); up = transform.getYAxis();}
Also the Main::run() is
bool Main::run() { std::cout << Window::deltaTime() << std::endl; runPlayer(); // glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glViewport(0, 0, Window::clientWidth(), Window::clientHeight()); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, float(Window::clientWidth())/float(Window::clientHeight()), 0.1f, 950); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //sky glUseProgram(0); glPushMatrix(); gluLookAt(0,0,0, camera.front.x,camera.front.y,camera.front.z, camera.up.x,camera.up.y,camera.up.z); glActiveTexture(GL_TEXTURE1); glEnable(GL_TEXTURE_CUBE_MAP); glBindTexture(GL_TEXTURE_CUBE_MAP, skyTexture); renderSky(); glDisable(GL_TEXTURE_CUBE_MAP); glPopMatrix(); // gluLookAt(camera.position.x,camera.position.y,camera.position.z, camera.at.x,camera.at.y,camera.at.z, camera.up.x,camera.up.y,camera.up.z); //light glPushMatrix(); glTranslatef(2,3,0); Light light; light.position[3] = 1; light.run(GL_LIGHT0); light.render(quadratic); glPopMatrix(); //test glPushMatrix(); glColor4f(1,1,1,1); testMesh->render(); glPopMatrix(); //other glUseProgram(0); runFps(); renderAxises(); // return true;}
Thanks.
[Edited by - andrew111 on August 15, 2009 12:24:27 AM]
I was just about to suggest to turn vsync off + then I notice having it on causes the problem (from your post)
>>My movement is based on deltaTime.
u say your FPS is 800-1200, in this case u really should use a fixed loop update, i.e. ditch the deltaTime stuff
something else to try is stick a sleep(1)/SDL_Delay(1); command somewhere in your main loop (so it gets called once per bufferswap)
>>My movement is based on deltaTime.
u say your FPS is 800-1200, in this case u really should use a fixed loop update, i.e. ditch the deltaTime stuff
something else to try is stick a sleep(1)/SDL_Delay(1); command somewhere in your main loop (so it gets called once per bufferswap)
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement