2D 게임 및 현대 OpenGL


10

선입견

좋아, 그래서 지금까지 모은 것은 이것입니다.

  • 고정 파이프 라인을 사용하지 마십시오 (더 이상 사용되지 않거나 더 이상 사용되지 않을 예정 임)
  • vbos는 "개체 모델"(주로 n 개의 정점 데이터)을 저장합니다.
  • vaos는 그리기 호출이 각 vbo의 어떤 부분이 어떤 종류의 정점 정보인지 알 수 있도록 데이터가 배치되는 방법을 설명합니다.
  • 각 그리기 호출은 또한 정점 데이터를 셰이더에 보냅니다.

3D를 보는 방법 (선택 사항)

이러한 정보를 통해 현대 OpenGL에서 3D 복잡한 객체를 그리는 것이 얼마나 좋은지 알 수 있습니다. 기본적으로 로컬 좌표를 사용하여 여러 객체 모델 (아마도 Blender 또는 기타 유사한 소프트웨어의)을 VBO에로드 한 다음 객체의 각 인스턴스에 다른 셰이더 매개 변수 (오프셋)를 제공하여 월드 공간에 그립니다.

문제 / 질문

그러나 2D 문제와 우선 순위는 완전히 다릅니다. 복잡한 객체를 그리거나 복잡한 투영 행렬이 필요하지 않으며 셰이더가 무엇보다 훨씬 간단합니다.

현대 OpenGL을 사용하여 지오메트리를 자주 변경하는 (실제로 기본적으로 모든 프레임) 가장 좋은 방법은 무엇입니까?

다음 단락에서는 관심있는 변경 종류를 더 잘 식별하는 몇 가지 문제 (원 및 사각형 문제)를 볼 수 있습니다.

내 시도 (선택 사항)

그래서 화면에 기본 2D 지오메트리를 그리는 방법을 생각하기 시작했습니다.

  • 정사각형 : [(1, 0), (1, 1), (0, 1), (0, 0)]로컬 공간에서 정사각형의 지오메트리에 대한 VBO를 로드 한 다음 정사각형의 실제 너비와 월드 좌표 및 색상 정보를 쉐이더에 제공합니다.

시원하고 쉽게 보입니다. 원으로 이동합시다 :

  • 원 : 삼각형 팬 ... eh. 정밀도 (정점 수)는 얼마입니까? 작은 원의 정밀도는 작아야하고 버그의 원의 정밀도는 높아야합니다. 1 VBO를 확실하게로드하는 것이 모든 경우에 적합한 것은 아닙니다. 원의 크기가 더 커져서 정밀도를 추가해야하는 경우 어떻게해야합니까?

덜 시원합니다. 조금 더 쉬운 직사각형으로 이동합시다.

  • 사각형 : eh. "일반 사각형 지오메트리"는 없습니다. 너비 / 높이 비율 만 있으면되지만 크기가 변경되면 각 사각형이 다를 수 있습니다.

보시다시피, 거기에서 내리막 길이 시작됩니다. 특히 복잡한 다각형과 그 밖의 것들이 있습니다.

코드 정책 없음 : P

아이디어에 대한 개요가 필요합니다. 특히 C 또는 C ++ 코드와 같은 코드가 필요하지 않습니다. "이 꼭짓점 데이터로 VBO를 만든 다음 바인딩하십시오 ..."와 같이 말하십시오.


나는 당신이 요구하는 것을 이해한다고 생각하지만, 당신은이 질문에 조금 더 많은 방향을 제시하고 싶을 것입니다. 무엇을 요청하고 있는지는 불분명합니다. 이것은 실제로 가까운 이유입니다.
Lysol

@AidanMueller 나는 당신이 무슨 뜻인지 잘 모르겠지만, 필요하다고 느낀다면 더 많은 지시를 주시기 바랍니다.
구두

최고 답변은 현재 "주요 질문 인 것 같습니다"라고 말하면서 시작됩니다. 그것은 당신이 무엇을 요구하는지 명확하지 않다는 것을 나타냅니다. 질문 끝에서 알 필요가없는 것에 대한 요약을 제공해야 할 수도 있습니다. 이것은 결국 Q / A이며 토론이 아닙니다.
Lysol

@AidanMueller 그런 맥락이 아니라고 생각합니다. "주요 질문은 ... 인 것 같습니다"라고 표시 한 다음 내가 게시 한 질문을 인용합니다. 실제로 인용하기에 충분하다는 것을 나타냅니다. 또한 문구는 내 질문이 명확하지 않다는 것이 아니라 주요 질문과 또 다른 보조 질문이 있음을 나타냅니다 (즉, 내가 제시 한 특정 사례에 대한 해결책은 무엇입니까). 나는 현재의 질문에 대한 문제를 실제로 보지 못하며 대답이 매우 유용하고 요점을 알았을 때 응답자조차도 보이지 않았습니다.
구두

조각 쉐이더로 정확한 원을 그릴 수 있습니다.
user253751

답변:


5

주요 질문 은 다음과 같습니다.

현대 OpenGL을 사용하여 지오메트리를 자주 변경하는 (실제로 기본적으로 모든 프레임) 가장 좋은 방법은 무엇입니까?

대부분의 경우 2d와 3d OpenGL 사이에는 큰 차이가 없습니다. 그래픽스 파이프 라인에는 2 차원으로 많이 사용되지 않는 Z라는 하나의 추가 좌표가 있지만 그 정도입니다.

각 그리기에서 지오메트리를 변경하는 몇 가지 방법이 있습니다.

  • 매 프레임마다 새로운 CPU 제공 버텍스를 푸시 할 수 있습니다. ( 버퍼 재사용에 대한 참고 사항 은 /programming/14155615/opengl-updating-vertex-buffer-with-glbufferdata 를 참조 하십시오 .)

  • 을 사용하여 기존 버퍼의 다른 부분을 그릴 수 있습니다 glDrawArrays(mode, first, count). 애니메이션이 반복되는 경우 다른 버텍스 목록이있는 미리 계산 된 프레임을 하나의 큰 버퍼에 넣고 각 프레임마다 버퍼의 적절한 부분을 그릴 수 있습니다.

  • 균일 한 배열 또는 텍스처와 같은 다른 데이터로 정점 목록에 영향을 줄 수 있습니다. 정점 셰이더에서이 데이터를 읽고 적절히 적용하십시오. 이들은 GPU에 데이터를 표시하는 다른 관용구이며 성능에 큰 차이가 없을 것입니다.

  • 동일한 지오메트리의 많은 인스턴스가있는 경우 (속성에 영향을 받음) glDrawElementsInstanced()유용 할 수 있습니다.

  • 정점, 지오메트리 또는 테셀레이션 셰이더에서 알고리즘 적으로 정점 목록에 영향을 줄 수 있습니다. 애니메이션을 수학적으로 설명 할 수 있으면 동일한 정점 목록을 유지하고 각 프레임마다 몇 가지 쉐이더 유니폼 만 변경할 수 있습니다.

또한 애니메이션은 순수한 텍스처로 표현 될 수 있으며 모든 애니메이션은 CPU에 의해 픽셀 단위로 수행되거나 디스크에서 사전 렌더링됩니다.

"컴퓨터가 빠르기 때문에 매 프레임마다 신선한 CPU로 만든 꼭지점을 설정하는 것이 가장 쉬운 방법입니다. 그런 다음, 그것이 충분한 지 확인하십시오. 배터리 / CPU 사용량을 프로파일 링하십시오. 첫 번째는 메모리 풋 프린트입니다. "

다른 질문 은 "원과 사각형을 그리는 좋은 방법은 무엇입니까?"

서클.

  • 테셀레이션 쉐이더 (또는 지오메트리 쉐이더)를 사용하면 지오메트리의 동적합니다.

  • 정사각형을 그릴 수 있으며 프래그먼트 셰이더에서는 반경 내에서만 불투명 (알파 = 1.0)하고 반경 밖에서는 투명 (알파 = 0.0) 할 수 있습니다. 그러면 매번 완벽한 픽셀입니다. (정사각형 꼭지점을 -1에서 +1로 만들고 조각 쉐이더에서 다음과 같이 만드십시오 outColor.a = dot(coord.xy, coord.xy) < 1.0 ? 1.0 : 0.0;. 가장자리를 약간 부드럽게 할 수 있습니다.

  • 예를 들어 항상 120- 삼각형 팬을 사용할 수 있습니다. 아마 충분할 것입니다.

사각형.

  • 나는 당신이 그 질문에 대해 당신 자신의 질문에 대답했다고 생각합니다. 당신이 제안하는 것은 잘 작동합니다!

조각 쉐이더 / 반경은 매우 깔끔합니다. 내 자신의 질문에 대답하는 것과 관련하여, 나는 당신이 무엇을 의미하는지 이해하지 못한다고 생각합니다.
구두

아, 정사각형과 마찬가지로 너비를 조절한다고 언급하고 (제복을 가정) 너비, 높이 비율 만 있으면되지만 크기가 바뀌면 각 사각형이 다를 수 있습니다. . 따라서 사각형의 경우 사각형과 동일하게 수행하지만 3 (x, y, w) 대신 4 개의 값 (x, y, w, h)이 필요합니다. 또는 (xlow, xhigh, ylow, yhigh)를 네 개의 유니폼으로 전달하십시오. (0,0) ~ (1,1) 입력으로, 정점 쉐이더가 필요한 것을 수행하기에 충분합니다.
david van brink

오, 알겠습니다.
구두

고정 기능 파이프 라인의 GL_TRIANGLE_FAN과 같은 최신 GL에 자동 팬이 있습니까?
John P

5

나는이 주제에 대해 전문가라고 말할 수 없으며, 내 게임 프로젝트에서 3D 측면에 더 집중했습니다. 따라서 2D 측면은 일반적으로 3D 측면을 위해 만든 것들을 사용하여 매우 간단합니다. 분명히 내 관점은 게임 측면이므로 2D 그래픽은 지오메트리보다 스프라이트를 블리 팅하는 것에 관한 것입니다. 그런 관점에서

1) 사각형과 사각형은 매우 쉽습니다. VBO에는 모든 것을 블리 팅하는 데 사용하는 단일 1x1 상자가 있습니다. 이 "단위 상자"를 사용하여 MVP 행렬을 셰이더에 전달하고 추가 크기 조정과 결합하여 상자의 크기를 올바른 크기로 조정했습니다.

내 목적을 위해, 나는 "유닛 박스"를 사용하는 것에서 2D 스프라이트를 블리 팅하기 위해 일종의 파티클 엔진으로 옮기려고 생각했지만, 그것은 또 다른 이야기입니다.

2) 나는 원으로 많은 일을하지 않았으며 특정 수의 정점이있는 고정 VBO를 사용합니다. 그러나 원에 그려진 정점 수에 영향을 미치기 위해 약간의 조정을 할 수 있다고 상상할 수 있습니다.

VBO 데이터를 셰이더 속성에 연결할 때 glVertexAttribPointer를 사용합니다. 인터리브 된 데이터 (내가 사용하는)에 사용되는 보폭 매개 변수가 있습니다. 그러나 다음과 같이 사용할 수 있습니다.

glVertexAttribPointer(..., n * sizeof(VERTEX_DATA), ...);

... 버퍼에서 모든 n 번째 정점을 선택하여 원에 그려진 정점의 수에 영향을 미칩니다. 원에 그려지는 꼭지점의 수에 영향을 미치는 보폭이 다른 VBO가 동일한 여러 VAO를 만들 수 있습니다. 나는 그것을 시도하지 않았다.

일반적으로 그렇습니다 .VBO와 함께 작업하면 CPU 측 조정이 좀 더 복잡해집니다. 왜 GPU 측 (쉐이더)에서 조정하기 위해 다른 것들을 연구하고 있습니까? 그러나이 기사에 따르면 많은 CPU 측 "중재"가 필요한 경우에도 최신 하드웨어에서 VBO를 사용하는 것이 더 효율적입니다.

http://www.quelsolaar.com/opengl_performance.txt

이것이 방향을 디자인하고 결정하는 데 도움이되기를 바랍니다.


2
"원에 대해 그린 정점 수에 영향을 미치는 보폭 조정"매우 멋지다!
david van brink
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.