2010-03-03 2 views
3

기본적으로 화면 (1 인칭)을 돌며 실행할 수있는 학습용으로 프로그램을 작성했습니다 (C++에서는 gl/glut을 사용함). 장면. 나는 다른 컴퓨터에서 실행하려고하고 속도는 완전히 다른, 그래서 나는 주제에 대한 검색 나는 현재이 같은 일을 해요 :어떤 컴퓨터에서든 동일한 속도로 프로그램을 실행하는 것에 관한 질문

유휴 기능 :

start = glutGet (GLUT_ELAPSED_TIME); 
    double dt = (start-end)*30/1000; 

    <all the movement*dt> 

    glutPostRedisplay(); 

    end = glutGet (GLUT_ELAPSED_TIME); 

표시 기능 :

<rendering for all objects> 

    glutSwapBuffers(); 

내 질문은 : 적절한 방법입니까? 유휴 기능 후 장면이 제대로 표시되고 있습니까?

glutSwapBuffers() 전에 end = glutGet (GLUT_ELAPSED_TIME) 배치를 시도했지만 변경 사항을 알지 못했지만 glutSwapBuffers() 이후에 배치하면 속도가 느려지고 때로는 중지되기도합니다.

편집 : 방금 생각한 방식으로 모든 드로잉이 끝나고 운동 업데이트가 끝난 후부터 idle()이 곧 호출 될 것이라고 생각한 것 같습니다. display()가 끝나면, 여기에 설명되지 않은 유일한 시간은 컴퓨터가 모든 동작을 수행하는 데 걸린 시간이라는 것입니다. (어떤 거의 아무것도해야합니까?)

죄송이 너무 혼란 경우 .. 미리

감사합니다.

답변

4

"Glut"이 무엇인지는 모르겠지만 게임 개발의 일반적인 규칙으로 컴퓨터가 지시를 처리하는 속도가 이동 속도에 미치지 못하게합니다. 그것이 80 년대 후반에했던 것과 같습니다. 그래서 당신이 오래된 게임을 할 때, 사물은 가벼운 속도로 움직입니다.

저는 타이머를 설정하고 모든 움직임을 분명하고 구체적인 시간 지정 이벤트로 만듭니다.

+1

GLUT. http://www.opengl.org/resources/libraries/glut/ – kennytm

+3

'80 년대 후반에 그들이했던 것과 그게 바로 오래된 게임을 할 때 상황이 가벼운 속도로 움직이는 이유입니다. 아아, 그리고 그 이유는 악명 높은 "터보"버튼. 컴퓨터가 너무 빠르면 터보를 꺼서 느리게 재생할 수 있습니다. –

+0

@ Eric LOL - 나는 터보 버튼이 무엇인지 알지 못했다! 마침내 20 년이 지난 후에 저는 답을 얻었습니다. :) –

1

Windows에서 QueryPerformanceCounter와 같은 고해상도 타이머를 설정하고 모든 프레임 사이의 시간을 측정하십시오. 델타 시간 (dt)이라고하는이 시간은 모든 이동 계산에 사용되어야합니다. DT의 합은 항상 1 초 이상이어야하기 때문에 아무리 프레임 레이트가 무엇인지, 100 초마다 의해

obj.x += 100.0f * dt; // to move 100 units every second 

상기 코드 단위의 X가 : 모든 프레임에 객체의 위치를 ​​설정할 수 없다. 시간이 지남에 따라 변하는 모든 값에 대해이 작업을 수행해야합니다. 이렇게하면 컴퓨터가 로직을 처리하는 속도 (프레임에 따라 다름)에 의존하기보다는 게임이 모든 시스템 (프레임 독립적 인)에서 동일한 비율로 진행됩니다. 이것은 프레임 속도가 떨어지기 시작하는 경우에도 유용합니다. 게임이 갑자기 슬로우 모션으로 시작하지 않고 동일한 속도로 계속 움직이며 덜 자주 렌더링됩니다.

+0

그가 벌써하고있는 것이다. – meagar

1

나는 타이머를 사용하지 않을 것이다. 상황이 잘못 될 수 있으며 PC가 너무 느리거나 너무 바빠서 필요한 속도로 작동하지 않으면 이벤트가 쌓일 수 있습니다. 루프가 허용되는 한 빨리 실행되도록하고, 매번 얼마나 많은 시간이 경과했는지 계산하고이를 운동/논리 계산에 넣습니다.

내부적으로 가변 시간 단계에서 모든 작업을 올바르게 수행하려고하면 x + = v * dt만큼 간단하지 않으므로 내부적으로 작은 고정 시간 하위 단계를 구현할 수 있습니다.

이와 비슷한 것들에 대해 gamedev.net을 시도해보십시오. 많은 기사와 바쁜 포럼.

0

저는 게임 프로그래머이며 여러 번했습니다.

대부분의 게임은 AI를 예를 들어 60hz와 같은 고정 시간 단위로 실행합니다. 또한 대부분의 화면이 화면 새로 고침과 동기화되어 화면이 끊어지는 것을 방지하므로 컴퓨터가 매우 빠르며 1000fps를 처리 할 수있는 경우에도 최대 속도는 60입니다. 따라서 시스템이 느리고 20fps로 실행 중이면 렌더링 당 3 번 업데이트 ai 함수를 호출합니다. 이 방법을 사용하면 작은 값으로 반올림 오류 문제를 해결할 수 있으며 AI 업데이트 속도가 컴퓨터 속도와 분리되어 (온라인 멀티 플레이어 게임에 필수) 여러 AI 시스템에서 AI를 결정적으로 처리 할 수 ​​있습니다.

+0

앱이 다른 업데이트 속도로 실행되도록하면서 작은 고정 타임 스텝을 여전히 수행 할 수있는 이유에 대한 좋은 예입니다. 이렇게하면 프레임 속도 독립성의 이점을 얻을 수있을뿐 아니라 각 실제 단계가 같은 간격 일 때 결정론의 이점을 누릴 수 있습니다. 충돌 탐지는 다른 주요한 예입니다. –

0

이것은 매우 어려운 질문입니다.

먼저 자신에게 필요한 것은 응용 프로그램이 실제로 같은 속도로 실행되거나 동일한 속도로 실행되도록하는 것입니까? 99 %는 같은 속도로만 실행되기를 원합니다.

이제는 두 가지 문제가 있습니다. 애플리케이션 속도가 빨라지거나 속도가 느려집니다.

현재 속도를 조정하는 동적 LOD 같은 것이 필요하기 때문에 애플리케이션 속도가 매우 빠릅니다. 이것은 그래픽뿐만 아니라 모든 것에있어 LOD를 의미합니다.

응용 프로그램을 느려지 게하는 것은 매우 쉽습니다. 당신은 두 가지 옵션을 취하거나 "바쁜 대기 중"입니다. 기본적으로 시뮬레이션의 타겟 프레임 속도에 따라 다릅니다. 시뮬레이션이 50ms 이상인 경우 잠을 잘 수 있습니다. 문제는 자고있을 때 프로세스 스케줄러에 의존하고 평균 시스템에서 10ms 단위로 작동한다는 것입니다.

게임에서 바쁜 대기는 그렇게 나쁘지 않습니다. 당신이하는 일은 시뮬레이션을 업데이트하고 프레임을 렌더링 한 다음 다음 프레임에 시간 누산기를 사용하는 것입니다. 시뮬레이션없이 프레임을 렌더링 할 때 상태를 보간하여 부드러운 애니메이션을 얻습니다. 주제에 관한 정말 훌륭한 기사는 http://gafferongames.com/game-physics/fix-your-timestep/에서 찾을 수 있습니다.

1

필요한 모든 정보를 제공해야하는 게임 루프에 대해 perfect article이 있습니다.

1

"올바른"방법을 사용하는 방법에 대한 많은 답변을 가지고 있지만 GLUT를 사용하고 있으며 GLUT는 간결하고 플랫폼 독립성을 유지하기 위해 때때로 "올바른"방법을 희생합니다. GLUT 방법은 glutTimerFunc()에 타이머 콜백 함수를 등록하는 것입니다.

static void timerCallback (int value) 
{ 
    // Calculate the deltas 

    glutPostRedisplay(); // Have GLUT call your display function 
    glutTimerFunc(elapsedMilliseconds, timerCallback, value); 
} 

elapsedMilliseconds를 40으로 설정하면이 함수가 1 초에 25 회보다 약간 적게 호출됩니다. 델타 계산 코드를 처리하는 데 컴퓨터가 걸린 시간에 따라 다소 차이가 있습니다. 이 코드를 단순하게 유지하면 각 시스템이 40 밀리 초 미만으로 디스플레이 기능을 처리 할 수있는 한 모든 시스템에서 동일한 속도로 애니메이션이 실행됩니다. 유연성을 높이기 위해 명령 행 옵션을 사용하거나 인터페이스에 컨트롤을 추가하여 런타임에 프레임 속도를 조정할 수 있습니다.

초기화 프로세스에서 glutTimerFunc(elapsedMilliseconds, timerCallback, value);을 호출하여 타이머 루프를 시작합니다.

관련 문제