일단 경험상 뼈저리게 느낀 것들만 간추려서 씀...
1. 전역 상태 (glEnable, glDisable, glViewport, glBlend) API 등으로 바로 상태 조절하지 말 것.
프레임버퍼, 쉐이더 스토리지 버퍼, VAO, VBO, EBO 및 텍스쳐들이 갖가지로 교차하는 상태에서 전역 상태 API 을 쓰는 건 구조가 조금만이라도 복잡해지면 엄청 힘들어짐. 개인적으로는 각 상태마다 코드로 스택을 만들어서, 랩핑된 API 로 넣고 뺄 때마다 스택의 Top 값에 따라 코드 내부에서 자동으로 glAPI 을 호출하는 것이 좋은 것 같음.
물론 컨텍스트가 하나가 아니라, 렌더 파이프라인 과정마다 복수개 있으면 그 컨텍스트들 마다 상태가 다 다를테니까 상태 관리는 좀 더 편해질 것 같음. 근데 이렇게 되면 컨텍스트 간의 리소스 공유가 되고 안되는 리미트가 있어서 X빠질 수도 있고... ㅇㅇ
2. GL 컨텍스트 만들 때, 어느 것이 컨텍스트 간 공유가 되고, 안되고를 사전에 알아서 랩핑해야 함.
대표적인 예로 VBO, EBO 는 일반 버퍼라서 컨텍스트 간 공유가 되는데, VAO 는 VBO, EBO 의 포인터를 지정해서 어떻게 쓰겠다고 포맷만 저장한거라 컨텍스트 간 공유가 안됨. 그 외에도 텍스쳐랑 렌더버퍼는 되지만 프레임버퍼 오브젝트는 안됨. 쉐이더 역시 공유가 안됨. 이외에도 여러가지 있을 듯.
https://www.khronos.org/opengl/wiki/OpenGL_Context
3. OpenGL 은 멀티스레드에 완전 고자라서 (어토믹 변수가 있긴 하지만 글쎄다) 멀티스레드로 OpenGL 로 여러가지 작업을 시키게 할 때는 상태 관리 등등이 꼬이는 걸 방지하게 해야함. 가장 편한 솔루션으로는 각 스레드마다 컨텍스트를 하나씩 할당하게 해서 각 스레드에서는 그 컨텍스트로만 쓰게 하기. 저어는 IO 잡 워커 스레드에 2개, 메인 업데이트&렌더 스레드에 1개 만들어서 쓰게끔 하고 있음요.
4. 그냥 Vulkan 쓰세요
Vulkan 넘 코드 길게 나온다던데 더 극혐 아님?? - dc App
그건 애초에 상태변수 같은거 내부에 다 두지않고 프로그래머가 치는 코드에 다 명확하게 나타내야 하기 때문에 길어지는 거임여 이 말인 즉슨 프로그래머가 모든걸 다 알 수 있고 관리할 수 있으니까 장기적인 측면으로는 랩핑만 잘 해주면 관리하기 더 편하다고 봐요
자스로 트랜스 컴파일하는거보다 llvm으로 컴파일해서 웹어셈 만드는게 나은거랑 비슷한가
4번이 본문의핵심 맞지?
내
근데 vulkan은 지원하는 기기가 얼마나 많은가 확신이 없어서 말이죠. 특히 안드로이드에서. ㅜㅜ