2010-08-03 4 views
0

천천히 "채워지는"순환 진행 표시기를 그리는 응용 프로그램에서 작업 중이므로 여기서 a couple of images을 볼 수 있습니다. 중간 모드를 사용하고 있으며 각 프레임 업데이트에서 꼭지점을 그려서이 원형 모양을 그리는 것입니다 (아래 코드 참조). 원이 채워지면 흰색과 회색 사이의 경계선이 약간 깜박이며 어떻게하면 더 부드럽게 만들 수 있는지 궁금합니다.OpenGL을 사용하여 매우 부드러운 움직이는 물체를 얻는 방법

이것은 구체적인 예입니다. 그러나 일반적으로 매우 단순한 라인 에어 보간을 사용할 때도 가장 매끄러운 동작을 얻는 방법에 대해 궁금합니다. 내가 내 아이폰의 페이지 사이를 뒤집을 때 모션을 볼 때 그것은 내 (빠른) Mac에서 어떻게 이것을 달성 할 수 있을지 궁금하게 만드는 너무 극단적으로 부드럽습니까? flickery, 앨리어싱, 부드러운 움직임이나 유물을 그리기 -

감사
Roxlu는

PhotoBoothCountdown::PhotoBoothCountdown(float fMillisDuration) 
    :duration(fMillisDuration) 
    ,start_time(0) 
{ 
    setActionCommand("take_picture"); 
} 

void PhotoBoothCountdown::update() { 
    if(start_time != 0) { 
     float cur = ofGetElapsedTimeMillis(); 
     perc = (cur-start_time)/duration; 

    } 
} 

void PhotoBoothCountdown::draw() { 
    float resolution = 150; 
    int parts_filled = resolution * perc; 
    int parts_unfilled = (resolution - parts_filled); 
    float part_angle = TWO_PI/resolution; 
    //printf("filled: %i/%i/%i\n", parts_filled, parts_unfilled, (parts_filled+parts_unfilled)); 
    float radius = 300.0f; 
    float width = 100; 
    float radius_inner = radius-width; 
    float center_x = ofGetWidth()/2; 
    float center_y = ofGetHeight()/2; 
    float angle = 0; 

    glBegin(GL_TRIANGLE_STRIP); 
     glColor4f(0.2f, 0.2f, 0.2f,0.9f); 
     for(int i = 0; i <= parts_filled; ++i) { 
      float cosa = cos(angle); 
      float sina = sin(angle); 
      glVertex2f(center_x + cosa * radius,center_y + sina * radius); 
      glVertex2f(center_x + cosa * radius_inner,center_y + sina * radius_inner); 
      angle += part_angle; 
     } 
    glEnd(); 
    glBegin(GL_TRIANGLE_STRIP); 
     glColor4f(1.0f, 1.0f, 1.0f,0.9f); 
     angle -= part_angle; 
     for(int i = 0; i <= parts_unfilled; ++i) { 
      float cosa = cos(angle); 
      float sina = sin(angle); 
      glVertex2f(center_x + cosa * radius,center_y + sina * radius); 
      glVertex2f(center_x + cosa * radius_inner,center_y + sina * radius_inner); 
      angle += part_angle; 
     } 
    glEnd(); 

    if(perc >= 1) { 
     printf("should fire"); 
     fireEvent(); 
     reset(); 
    } 
} 



void PhotoBoothCountdown::start() { 
    start_time = ofGetElapsedTimeMillis(); 
    end_time = start_time + duration; 
} 

void PhotoBoothCountdown::reset() { 
    start_time = 0; 
    end_time = 0; 
    perc = 0; 
} 

답변

1

그것은 당신에 대해 물어 보는 것을 추측하기 어렵다 Double buffering

+0

OpenGL은 기본적으로 더블 버퍼링됩니다. – doc

+0

@doc : OpenGL은 단일 vs 이중 버퍼에 대해 잘 모릅니다. 이는 wgl 또는 glx와 같은 윈도우 시스템 인터페이스의 작업입니다.이것이 전형적으로'glutSwapBuffers'를 호출하는 이유입니다. 예를 들어, 신화적인'glSwapBuffers'가 아닌 –

+0

@doc : 그렇지 않습니다. 당신이 그것을 초기화하는 방식에 달려 있습니다. @ 에릭 : +1 – Calvin1602

0

에서 살펴 보자. 코드보고 후 무료 생각은

  • 당신은 가정 float part_angle = TWO_PI/resolution; 다음 (angle += part_angle) resolution 시간을 합산하여 당신이 TWO_PI를 얻을 수 있습니다 경우 그. 불행히도 이것은 부동 소수점 연산에서는 사실이 아닙니다. 또한 sin (TWO_PI) cos (TWO_PI)는 정확한 0.01.0 값을 반드시 반환하지 않습니다.

  • 그리기 전조를 개선하기 위해 필자는 전체 회색 원과 그 위에 흰색 원을 필요한만큼 그립니다. 이것은 100 %에서 완전한 회색 원을 가져올 것입니다.

  • 수레 작업은 실수를 줄 수 있으며이 오류는 변환 후 정수 값에 영향을 줄 수 있습니다. 아마도 당신은이 표현식으로부터 그것들을 계산함으로써 모든 채워진 부분을 결코 얻을 수 없을 것입니다. int parts_filled = resolution * perc;. 당신은 백분율 카운트 다운을 변환하여 정수형을 사용하거나 적어도 백분율 값을 출력하고 100 %에 도달했는지 체크함으로써 백분율 카운트 다운을 테스트 할 수 있습니다. 부드러운
  • Additionaly 당신이
    • 를 사용하여 안티 앨리어싱을 만들 수 가장자리
    • 증가 프레임 속도가 찢어 페이지를 제거하는 수직 동기에
    • 의 전원을 켭니다 (당신이 당신의 그림을 업데이트하는 방법에 따라 다름)
+0

안녕하세요. doc, 답장을 보내 주셔서 감사합니다. 어쩌면 내가 보여준 예제는 좋은 선택이 아니었을 것입니다. 텍스처가있는 GL_QUAD 만 있고 각도를 늘리더라도 각 업데이트가 매끄러운 선/이미지를 제공하지 않을 때도 원활하게 회전하려고한다고 가정합니다. vsync/증가 프레임 속도는 아마도 중요 할 것입니다. vsync를 true로 설정할 때 프레임 레이트가 어떤 일을하는지 확신 할 수 없지만 ... – pollux

+1

@pollux 엄격해야합니다. 너무 매끄러운 (도약) 애니메이션이나 부드럽지 않은 모양 (톱니 모양, 왜곡)이 문제입니까? – doc

+0

애니메이션이 부드럽 지 않습니다. – pollux

0

내가하는 첫 번째 작업은 단순히 하나의 원을 그려 디스플레이 목록에 저장하는 것입니다 (버퍼 객체로 이동할 수는 있지만이 조언의 나머지 부분은 생략하지 마십시오). nds, 즉각적인 모드이므로 가장 간단한 개선을 계속 할 것입니다.) 분할 된 원을 그려 백분율 완성에 해당하는 각각에 텍스처 좌표를 배치하십시오. 지루한 쉐이더를 적용하되 완전성을 위해 균일 한 쉐이더를 적용하십시오. 텍스쳐 좌표가있는 삼각형들 < = 완전성이 밝아집니다. 나머지는 회색으로 유지됩니다. 그런 다음 그림은 유니폼을 설정하고 표시 목록을 호출하는 것으로 구성됩니다. 훨씬 더 빨리.

관련 문제