2010-01-28 3 views
4

저는 C++과 DirectX를 처음 접했고 XNA에서 왔습니다. Fly The Copter과 같은 게임을 개발했습니다. 내가 한 것은 Wall이라는 클래스를 만듭니다. 게임을 실행하는 동안 모든 벽을 그립니다. XNA에서는 ArrayList에 벽을 저장했으며 C++에서는 vector를 사용했습니다. XNA에서 게임은 빠르게 실행되고 C++에서는 느리게 실행됩니다.느린 C++ DirectX 2D 게임

void GameScreen::Update() 
{ 
    //Update Walls 
    int len = walls.size(); 
    for(int i = wallsPassed; i < len; i++) 
    { 
     walls.at(i).Update(); 
     if (walls.at(i).pos.x <= -40) 
      wallsPassed += 2; 
    } 
} 

void GameScreen::Draw() 
{ 
    //Draw Walls 
    int len = walls.size(); 
    for(int i = wallsPassed; i < len; i++) 
    { 
     if (walls.at(i).pos.x < 1280) 
      walls.at(i).Draw(); 
     else 
      break; 
    } 
} 

업데이트 방법은 내가 sprite- 전화 그리기 방법> 그리기 (Direct3DXSprite)에서 4 하여 X 값을 감소 : 다음은 C++ 코드입니다. 게임 루프에서 실행되는 유일한 코드입니다. 이 코드가 좋지 않다는 것을 알고 있습니다. 개선 할 생각이 있다면 도움을주십시오. 제 영어에 대해 고마워하고 죄송합니다.

+0

여기 코드는 상당히 똑똑해 보입니다. 문제는 렌더링 파이프 라인 및 최적화 플래그에 가장 많이 놓이게됩니다. – aramadia

+1

나는 당신이 최적화 플래그를 켜지 않았다고 말할 것이다. – AraK

+0

얼마나 느린 지 아는 것이 유용 할 수 있습니다. 우리는 반 속도 또는 규모의 명령을 말하는거야? –

답변

8

at()의 모든 항목을 [] 연산자로 바꾸어보십시오. 예 :

walls[i].Draw(); 

다음에 모든 최적화를 설정하십시오. []와 at()는 모두 함수 호출입니다. 즉, 최적화 된 수준을 향상시키는 것이 무엇인지 인라인되도록하는 데 필요한 최대 성능을 얻기 위해서입니다.

당신은 또한 벽 객체의 최소한의 캐싱을 수행 할 수 있습니다 - 예를 들면 : 성능 문제의 원인을 좁힐 수

for(int i = wallsPassed; i < len; i++) 
{ 
    Wall & w = walls[i]; 
    w.Update(); 
    if (w.pos.x <= -40) 
     wallsPassed += 2; 
} 
+0

'[]'과'at() '의 주된 차이점은 무엇입니까? 편집 : 오, 그냥 대답을 발견 :'at()'경계를 확인합니다. – dreamlax

+1

실제 차이점이 없습니다. []이 (가) 과부하되므로 너무 짧습니다. 또한 이런 종류의 최적화() 대 []가 사소하기 때문에 나는 downvoted. – aramadia

+8

차이점은 -() 범위 검사가 필요하지 않으면 시간이 걸리고 무의미합니다. 그리고 연산자 [] (또는에서)를 인라이닝 (inlining) 한 결과는 매우 명확하게 나타납니다. –

2

시도를 (또한 프로파일 링을 지칭). 모든 개체를 계속 업데이트하면서 하나의 개체 만 그리기를 시도합니다. 갑자기 더 빠르면 DirectX 그리기 문제입니다.

그렇지 않으면 모든 개체를 그리지 만 한 벽만 업데이트 해보십시오. 그것보다 빨리 update() 함수가 너무 비싸면.

0

비트 맵에 여러 개의 버퍼 (더블 버퍼링 )를 시도 했습니까?

일반적인 시나리오는 하나의 버퍼에 그리는 것이고 첫 번째 버퍼가 화면에 복사되는 동안 두 번째 버퍼에 그립니다.

또 다른 기술은 메모리에 거대한 "논리적"화면을 갖는 것입니다. 물리적 디스플레이에서 그려지는 부분은 뷰포트 또는 입니다. 논리적 인 화면의 작은 영역으로보기입니다. 배경 (또는 화면)을 이동하면 그래픽 프로세서 부분에 사본이 필요합니다.

0

스프라이트 그리기 호출의 일괄 처리를 지원할 수 있습니다. 아마도 귀하의 draw 호출은 관련 매개 변수를 사용하여 ID3DXSprite :: Draw의 유일한 인스턴스를 호출합니다.

모든 렌더링을 완료하면 ID3DXSprite :: Begin (D3DXSPRITE_SORT_TEXTURE 플래그가 설정된)을 호출하고 ID3DXSprite :: End를 호출하면 훨씬 향상된 성능을 얻을 수 있습니다. 그런 다음 ID3DXSprite는 모든 스프라이트 호출을 텍스처별로 정렬하여 텍스처 스위치 수를 줄이고 관련 호출을 함께 배치합니다. 이렇게하면 성능이 크게 향상됩니다.

그러나 업데이트 및 그리기 호출의 내부를 보지 않고는 말하기가 어렵습니다. 위의 것은 단지 추측 일뿐입니다 ...

0

다른 모든 그리기 호출로 모든 단일 벽을 그리는 것은 좋지 않습니다.데이터를 단일 버텍스 버퍼/인덱스 버퍼로 일괄 처리하여 단일 끌기로 전송하십시오. 그게 더 온화한 생각입니다.

어쨌든 천천히 CPU와 GPU (PerfHud, Intel GPA 등 ...)에서 병목 현상 (CPU 또는 GPU 인 경우)을 알아 내려고 시도하는 이유에 대한 아이디어를 얻으 려합니다. 그리고 나서 문제를 해결하기 위해 싸울 수 있습니다.

1
  • '빠름'속도는 얼마나 빠릅니까?
  • 얼마나 천천히 '천천히'입니까?
  • 몇 개의 스프라이트를 그리나요?
  • 각 이미지 파일과 화면에 그려지는 픽셀의 크기는 어느 정도입니까?
  • 그려지는 스프라이트 수를 변경하면 성능은 어떻게 조정됩니까 (XNA/C++에서)? 당신은 당신이 업데이트하지 않고 그릴 경우 얻을, 또는 무슨 차이
  • 그 반대의 경우도 마찬가지
1

어쩌면 당신은 그냥 과거에 몇 가지 문제가 있었다 : 릴리스 모드를 켭 잊어 버린 - 나는 내 코드라고 생각 디버그 모드 때문에 매우 느립니다. 그렇지 않은 경우 파트 렌더링 또는 개체 수가 매우 많아 문제가 발생할 수 있습니다. 당신이 제공 한 코드가 잘 어울립니다 ...

0

벽 목록에 조회가 귀하의 감속의 원천이 될 가능성은 희박합니다. 3D로 객체를 그리는 비용은 일반적으로 제한 요소가됩니다.

중요한 부분은 드로 코드, DirectX 장치를 만드는 데 사용한 플래그 및 텍스처를 만드는 데 사용하는 플래그입니다. 어둠 속의 찌르다 ... REF (소프트웨어 3D)가 아닌 HAL (하드웨어 3D)으로 장치를 초기화했는지 확인하십시오.

또한 몇 개의 스프라이트를 그리나요? 각 그리기 호출에는 상당한 양의 오버 헤드가 있습니다. 프레임 당 2 백 개 이상 만들면 그것은 제한 요소가됩니다.