2013-06-22 6 views
0

내 렌더링 루프에 문제가 있습니다. 움직이는 물체가있는 동안 나는 eglSwapBuffers 스왑의 같은 버퍼가 두 번 보이는 것 같은 작은 흔적을 보았습니다. 내 FPS는 지속적으로 59 - 60FPS입니다. 새로운 위치를 계산할 때 이동은 deltaTime을 고려합니다.Android OpenGL stuttering - vsync?

그게 뭐죠? 이중 버퍼링으로이 문제를 해결할 수 있습니까 ???

여기에 작은 동영상이 있습니다. (잘하면 내 뜻을 알 수 있습니다.) http://youtu.be/bQYiqHUzPuI

여기에 내 렌더링 루프

BOOL CEngine::OnStep() 
{ 
    BOOL bResult = TRUE; 
    UINT32 u32CurrFrameStartTime = GetTime(); 
    FLOAT32 f32DeltaTime; 

    f32DeltaTime = (u32CurrFrameStartTime - m_u32LastFrameStartTime)/1000000000.0f; 
    m_u32LastFrameStartTime = u32CurrFrameStartTime; 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    GLERROR(); 

    if (m_pScreenBase == NULL) 
    { 
     if (eglSwapBuffers(m_pDisplay, m_pSurface) == EGL_FALSE) 
     { 
      LogError("eglSwapBuffers function failed."); 
     } 

     if ((m_pScreenBase = new CStartScreen()) == NULL) 
      LogError("Can't allocate memory for CStartScreen."); 

     m_pScreenBase->Initialize(); 
    } 

    m_pScreenBase->Update(f32DeltaTime); 
    m_pScreenBase->Render(); 

    if (eglSwapBuffers(m_pDisplay, m_pSurface) == EGL_FALSE) 
    { 
     LogError("eglSwapBuffers function failed."); 
    } 

    m_i32FramesPerSecond += 1; 

    if (GetTime() - m_u32FPSResetTimer >= 1000000000) 
    { 
     LogFPS("%d", m_i32FramesPerSecond); 
     m_i32FramesPerSecond = 0; 
     m_u32FPSResetTimer = GetTime(); 
    } 

    // return false when app should be exit 
    return bResult; 
} 

여기가 필요한 경우, 내가 너무 내 EGLOpenGL 설정을 게시 할 수있는 업데이트 기능

void CStartScreen::Update(FLOAT32 f32DeltaTime) 
{ 
    for (INT32 i = 0; i < MAX_SQUARES; i++) 
    { 
     m_pSquare[ i ]->IncPosX((400.0f * f32DeltaTime)); 

     if (m_pSquare[ i ]->GetPosX() >= 800.0f) 
     { 
      m_pSquare[ i ]->IncPosX(-(800.0f + m_pSquare[ i ]->GetWidth())); 
     } 
    } 
} 

입니다.

UPDATE 1

UINT32가

부호의 INT UINT32 타입 정의

으로 정의된다;

inline UINT32 GetTime() 
{ 
    timespec sTime; 
    UINT32  u32Return = 0; 

    clock_gettime(CLOCK_MONOTONIC, &sTime); 
    u32Return = (sTime.tv_sec * 1000000000LL) + sTime.tv_nsec; 

    return u32Return; 
} 

그리고 여기에 1 초

f32DeltaTime : 0.012029 
f32DeltaTime : 0.016487 
f32DeltaTime : 0.016548 
f32DeltaTime : 0.023608 
f32DeltaTime : 0.017631 
f32DeltaTime : 0.023363 
f32DeltaTime : 0.012963 
f32DeltaTime : 0.026373 
f32DeltaTime : 0.016470 
f32DeltaTime : 0.012811 
f32DeltaTime : 0.016439 
f32DeltaTime : 0.016852 
f32DeltaTime : 0.025931 
f32DeltaTime : 0.012679 
f32DeltaTime : 0.013243 
f32DeltaTime : 0.014694 
f32DeltaTime : 0.016561 
f32DeltaTime : 0.016589 
f32DeltaTime : 0.020299 
f32DeltaTime : 0.014101 
f32DeltaTime : 0.016626 
f32DeltaTime : 0.016892 
f32DeltaTime : 0.016347 
f32DeltaTime : 0.018130 
f32DeltaTime : 0.019623 
f32DeltaTime : 0.012288 
f32DeltaTime : 0.016677 
f32DeltaTime : 0.016895 
f32DeltaTime : 0.016405 
f32DeltaTime : 0.018474 
f32DeltaTime : 0.017564 
f32DeltaTime : 0.014213 
f32DeltaTime : 0.016659 
f32DeltaTime : 0.016830 
f32DeltaTime : 0.016486 
f32DeltaTime : 0.018657 
f32DeltaTime : 0.026178 
**f32DeltaTime : 0.006349** 
f32DeltaTime : 0.014091 
f32DeltaTime : 0.016504 
f32DeltaTime : 0.016617 
f32DeltaTime : 0.024325 
f32DeltaTime : 0.013866 
f32DeltaTime : 0.015417 
f32DeltaTime : 0.014500 
f32DeltaTime : 0.016950 
f32DeltaTime : 0.016418 
f32DeltaTime : 0.018194 
f32DeltaTime : 0.016803 
f32DeltaTime : 0.017097 
f32DeltaTime : 0.013594 
f32DeltaTime : 0.016732 
f32DeltaTime : 0.016599 
f32DeltaTime : 0.017600 
f32DeltaTime : 0.021286 
f32DeltaTime : 0.012039 
f32DeltaTime : 0.016735 
f32DeltaTime : 0.017146 
f32DeltaTime : 0.020083 

확실하지에 대한 델타 시간입니다하지만 난 줄 생각 : f32DeltaTime 너무 작은 이유 "f32DeltaTime는 0.006349"문제가 될 수 ...하지만 일부 프레임에 ??? eglSwapBuffers는이 프레임에서 아무 것도하지 않습니까 ??? 그런데 왜 ??? 질문과 대답 :

+0

'm_pScreenBase'를 NULL로 재설정하는 것이 아무것도 아닙니까? – fadden

+0

안녕하세요, 저는 m_pScreenBase를 다시 설정하지 않고 있습니다. 나는 미쳐 가고있다. (이 문제를 일으킬 수있는 것은 무엇입니까? –

+0

작은 델타가 더 큰 델타의 발 뒤꿈치에 오는 것을 예상 할 수 있습니다 .607ps에서 .0167, 0.026178 + .006349 == .032527, averaging .0163 – fadden

답변

0

시간 기준은 나노초이지만 32 비트 정수로 보입니다. GetTime() 함수에서 clock_gettime()의 값을 가져 오는 경우 초와 나노초가 모두 필요하며 64 비트 정수로 유지해야합니다. 그렇지 않으면 델타 계산시 때때로 시간이 뒤로 도약합니다. 예를 들어

, 당신은 단지 tv_nsec 사용하는 경우 :

  • 이전 프레임의 시작 시간은 0 900000ns
  • 현재 프레임의 시작 시간이 1 초 100000ns

입니다 당신은 단지 나노초를 뺄 경우 , 200000ns의 forward step 대신 800000ns의 역방향 도약을 얻을 수 있습니다.

f32DeltaTime 값을 로깅하여 일치하는지 확인할 수 있습니다.

+0

안녕하세요, 내 질문을 업데이 트하고 GetTime 함수를 추가하십시오. 나는 또한 64 비트 정수로 시간 계산을 시도했지만 문제가 여전히 존재 ... : ( –

+0

안녕하세요 , 나는 나의 포스트를 다시 업데이트했다. .. 나를 도와 주려고 고맙다. :) –

+0

다음은이 모양이 아니었다. :-( – fadden