2010-02-14 4 views
2

게임에서 초당 프레임을 추적하려고합니다. 나는 fps가 평균으로 보이기를 원하지 않습니다. 키를 밀고 모델 등을 추가 할 때 프레임 속도가 어떻게 영향을 받는지보고 싶습니다. 그래서 현재 시간과 이전 시간을 저장하는 변수를 사용하고 있고, 1 초 차이가 나는 경우 fps를 업데이트합니다.이 fps 카운터가 정확하지 않은 이유를 모르겠습니다.

내 문제는 약 33fps로 보이지만 실제로 마우스를 빠르게 움직이면 fps가 최대 49fps로 올라갑니다. 다른 경우, 프레임 카운터와 관련이없는 간단한 코드 줄을 변경하거나 나중에 프로젝트를 닫고 나중에 열면 fps는 약 60이됩니다. Vsync가 켜져있어 마우스가 여전히 영향을 미치는지 알 수 없습니다. fps.

int FrameCount; 
double fps, currentTime, prevTime, TimeDelta, TimeElapsed; 

는 오해 여기 방법이 무엇인지 알려 주시기 바랍니다 : 여기에

FrameCount++; 
currentTime = timeGetTime(); 
static unsigned long prevTime = currentTime; 
TimeDelta = (currentTime - prevTime)/1000; 
if (TimeDelta > 1.0f) 
{ 
fps = FrameCount/TimeDelta; 
prevTime = currentTime; 
FrameCount = 0; 
    TimeDelta = 0; 
} 

변수 선언은 다음과 같습니다 여기

는 모든 프레임을 어떻게 업데이트 기능에 내 코드입니다 수정하거나 fps를 더 잘 계산할 수있는 방법이 있는지 확인하십시오. 감사!!!!!!

저는 DirectX 9 btw를 사용하고 있지만 관련성이 의심스럽고 PeekMessage를 사용하고 있습니다. 대신 if else 문을 사용해야합니까?

MSG msg; 
ZeroMemory (&msg, sizeof (MSG)); 

while (msg.message != WM_QUIT) 
{ 
    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
    { 
     TranslateMessage (&msg); 
     DispatchMessage (&msg); 
    } 

    Update(); 
    RenderFrame(); 
} 
+0

이 답변은 프레임을 생성하는 방법과이 코드가 렌더링 루프에있는 위치에 따라 달라집니다. – ChrisF

답변

1

이 더 많은 마우스 메시지를받을 귀하의 메시지 처리 루프는 FPS가 증가함에 따라, 엿이나 폴링 대신 차단하는 기호는 다음과 같습니다 여기 내 메시지 처리 루프입니다. GetMessage 대신 PeekMessage을 사용해야합니다.

EDIT : 또한 CPU를 호깅하고 싶다면 PM_NOYIELD을 추가하여 시스템에서 PeekMessage 동안 다른 스레드를 실행할 수 없도록 할 수 있습니다. From PeekMessage's documentation :

선택적 PM_NOREMOVE 또는 PM_REMOVE 중 하나에 값 PM_NOYIELD을 결합 할 수 있습니다. 이 플래그는 시스템이 발신자가 (WaitForInputIdle 참조)이 될 때까지 기다리는 스레드를 해제하지 못하게합니다.

+0

메시지 처리 루프를 게시하고 싶습니다. 형식을 지정할 코드를 가져올 수 없습니다. 이 주석 상자. 질문 상자와 다르게 형식을 지정해야합니까? – rmetzger

+0

@rmetzger, 원래 질문 게시글에 추가하십시오. – MSN

0

귀하의 문제에 대한 답변보다 많은 부작용이 있지만, 프레임 속도를 평균화하고 싶지는 않다고 말하지만, 그렇게 계산하면 1 초 이상 효과적으로 평균화 할 수 있습니다. 당신이 프레임 속도는 모든 프레임을 업데이트 한 싶은 경우에, 당신이 뭔가를 시도 할 수 있습니다 : 비록 timeGetTime이 숫자가 작을 가능성으로,이 시점에서 조금 부정확하기 시작하는 것입니다

currentTime = timeGetTime(); 
fps = 1000.0f/(currentTime - prevTime); 
prevTime = currentTime; 

. QueryPerformanceCounter는 사용할 더 나은 타이머 일 수 있습니다.

+0

1 초 ond 평균이기 때문에 읽을 수있는 것보다 빨리 화면에서 업데이트되지 않습니다. 저는 프로그램 시작 이래로 평균 fps를 취하고 싶지 않습니다. 예를 들어, 다른 스레드에서 이것을 보았습니다. "평활화 된 평균이 필요합니다. 가장 쉬운 방법은 현재 답변 (마지막 프레임을 그릴 시간)을 가져 와서 이전 답변과 결합하는 것입니다. time = 시간 * 0.9 + last_frame * 0.1 " 내가 이것을 오해하고있는 경우가 아니면 마지막 fps와 모든 fps의 평균을 결합하지 않습니까? – rmetzger

+0

위 서식에 죄송합니다. 왜 블록 견적이나 코드 서식을 사용하지 못하게 될지 모르겠습니다. – rmetzger

+0

당신이 말하는 평균은 최신 타이밍을 자세히 추적 할 수있는 가중치 평균이지만, 프로세스 초기에 스파이크의 영향을 항상받습니다. 나는 당신의 타이밍 코드에 대해서는 걱정할 필요가 없다. 업데이트 속도를 초당 2 배로 높이거나 막대 그래프로 그리면 효과를 더 쉽게 볼 수 있습니다. – Kylotan

0

메시지 처리 루프와 관련하여 if-else 문을 사용해야합니다.

if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
{ 
    TranslateMessage (&msg); 
    DispatchMessage (&msg); 
} 
else 
{ 
    Update(); 
    RenderFrame(); 
} 

그렇지 않으면 프레임 당 하나의 메시지 만 처리되어 프레임이 렌더링하는 데 오랜 시간이 걸리면 심각한 입력 지연이 발생할 수 있습니다.

FPS 수치와 관련해서는별로 중요하지 않지만 많은 것들이 영향을 미칠 수 있습니다. fps 카운터 코드가 목적을 수행하는 것처럼 보이지만 (정밀도가 떨어지는 경우) ...

마우스가 카메라를 제어하고 있습니까? 그렇다면 fps가 증가하는 마우스 입력인지, 앞으로 향하는 방향이 아닌지 확인하십시오.

fps 코드가 프레임 당 한 번만 실행됩니다.

어딘가에 입력을 처리합니까? 그렇다면 해당 코드를 비활성화하고 마우스를 빠르게 움직이면 어떻게됩니까? 아직도 같은가요?

+0

그럼 이제 if-else 문을 사용하고 있습니다. 나는 프레임 당 한 번만 fps 카운터를 업데이트한다는 것이 긍정적이다. 화살표 키를 사용하여 이전에 카메라를 움직이고있었습니다. 키 처리 코드와 fps가 변경되지 않았다고 설명했습니다. 내 프로그램에서 마우스 입력을 가져 오거나 처리하지 않습니다. 내 fps 카운터가 31-34fps로 표시됩니다. 그러나 마우스를 움직이면 여전히 최대 48-50 점프가됩니다. 이것이 관련이 있는지는 잘 모르겠지만 모델을 그릴 때 내 fps는 40-48이며 매우 일치하지 않습니다. 마우스를 움직이면 fps는 48-50으로 다시 이동합니다. – rmetzger

0

메시지 루프 정보 - 메시지가 나타나지 않을 때까지 메시지를 청취하여 다음에 프레임을 렌더링하는 것이 좋습니다.

의사 :

bool renderFrame = true; if (PeekMessage (...)) { // 처리하십시오. renderFrame = false; 은}

(renderFrame) 렌더링하여 프레임

그렇지 않으면 메시지 루프 기능을 종료 (다시 입력하거나 잠시 그것을 해결하는 경우

, 당신은 당신의 주회 돌이의 나머지 부분을 구조 한 방법에 약간 의존

관련 문제