각 glDraw *는 그리기 호출입니다.
1 glDrawArrays는 1 그리기 호출입니다.
1 glDrawElements는 1 그리기 호출입니다.
사용하는 정점 또는 인덱스의 수는 중요하지 않습니다 (드로우 콜 수에 관한 한). 1 glDraw *는 1 드로우 콜입니다.
쿼드를 그리는 간단한 사례 (사용하는 GL 버전이 쿼드를 제거하지 않았다고 가정) 또는 삼각형은 이들을 비교하기에 좋은 예가 아닙니다. 쿼드 목록 또는 삼각형 목록은 glDrawArrays는 인덱싱에 대한 추가 오버 헤드가 없기 때문에 더 효율적으로 나타납니다.
좀 더 복잡한 경우를 보자. 그러나보다 실제적인 시나리오를 나타내는 사례를 보자. 여러 개의 삼각형 스트립과 팬으로 구성된 모델이 있다고 상상해보십시오.
glDrawArrays (GL_TRIANGLE_FAN, .....);
glDrawArrays (GL_TRIANGLE_STRIP, .....);
glDrawArrays (GL_TRIANGLE_STRIP, .....);
glDrawArrays (GL_TRIANGLE_FAN, .....);
glDrawArrays (GL_TRIANGLE_STRIP, .....);
glDrawArrays (GL_TRIANGLE_FAN, .....);
이 예제에서 glDrawArrays를 사용하면 모델에 대해 총 6 개의 그리기 호출이 제공됩니다. 그러나 스트립과 팬 모두 인덱스 된 삼각형으로 쉽게 변환 할 수 있으므로 인덱스를 추가하면 다음과 같이됩니다.
glDrawElements (GL_TRIANGLES, .....);
그것은 전체 모델에 대한 하나의 끌기 호출입니다.
glDrawArray에 비해 glDrawElements의 장점은 단순한 메모리 절약 이상의 것입니다. 이는 메모리를 측정하는 순진한 방법입니다. 인덱스가 일반적으로 정점보다 작기 때문에 정점을 재사용 할 수있는 메모리를 절약 할 수있는 가능성 이 있습니다 (따라서 균형에 대한 인덱스가 많더라도 더 작을 수 있음).
드로우 콜 횟수 감소 각 드로우 콜은 유효성 검사 상태, 설정 등으로 인해 약간의 오버 헤드가 발생 하며이 오버 헤드의 대부분은 CPU 측에서 발생합니다. 드로우 콜 수를 줄임으로써 이러한 오버 헤드를 크게 피할 수 있습니다.
정점 재사용. 이것은 단순한 메모리 절약 이상의 것입니다. GPU에는 하드웨어 정점 캐시가있을 수 있으며, 최근에 변환 된 정점을 저장할 수 있습니다. 동일한 꼭짓점이 다시 들어오고 캐시에 있으면 다시 변환하지 않고 캐시에서 재사용 할 수 있습니다. 하드웨어는 인덱스를 비교하여 캐시를 확인하므로 OpenGL 용어로 캐시를 사용하는 유일한 방법은 glDrawElements를 사용하는 것입니다.
구체적인 질문에 대답하려면 다음을 수행하십시오.
glDrawElements가 그리기 호출을 어떻게 저장할 수 있습니까? 사용하는 예제에서는 그렇지 않습니다. 각각 하나의 드로우 콜이 있습니다. 위에서 논의했듯이이 예제는 두 가지를 비교하기에는 매우 나쁜 예입니다.
glDrawElements를 사용하면 공간이 어떻게 절약됩니까? 인덱스가 꼭짓점보다 작기 때문입니다. 16 비트 인덱스는 2 바이트이고 위치 / 컬러 / 텍스처 정점은 24 바이트입니다. 6 개의 정점은 144 바이트, 4 개의 정점에 6 개의 색인은 108 바이트입니다.
2 개의 삼각형에서 정사각형을 그리는 경우 ...? 하나와 하나. glDraw * 호출은 하나의 드로우 호출이며, 사용 된 정점 또는 인덱스의 수는이 측정과 관련이 없습니다. 그러나 나는 다시 강조해야합니다.이 둘을 비교하기에는 매우 나쁜 예입니다.
마지막으로 문제를 조금 복잡하게 만드는 것은 삼각형이있는 glDrawElements가 데스크탑 GPU에서 최적의 경로이며, 모바일에서는 매우 다를 수 있습니다. 일부 모바일 GPU는 GL_TRIANGLE_STRIP (이 경우 기본 요소를 연결하기 위해 축퇴 삼각형을 추가 할 것)이있는 glDrawArrays를 선호 할 수 있으며 기본 다시 시작 또는 다중 그리기와 같은 고급 주제는 다루지 않았습니다.