2014-09-26 2 views
2

Android에서 OpenGL ES 2.0 엔진을 구현하고 있습니다. 나는 여러 개의 쉐이더를 가지고 있으며, 오브젝트는 여러 텍스처를 가질 수 있습니다.glUseProgram 간의 OpenGL 텍스처 바인딩

목표는 OpenGL에 대한 텍스처 바인딩 호출을 최소화하는 것이므로 각 셰이더에 현재 바인딩 된 텍스처 목록을 유지하고 텍스처가 변경된 경우 glBindTexture() 만 호출하면됩니다.

예를 들어 스카이 박스 쉐이더가 있고, 하나의 오브젝트 (스카이 박스 큐브) 만 그릴 수 있습니다. 그러면이 쉐이더는 그 수명 기간 동안 하나의 텍스처 바인딩 만 필요합니다.

그리고 동일한 텍스처로 여러 오브젝트를 그릴 때도 이익이있을 수 있습니다.

필자가 스카이 박스 텍스처를 그리기 전에 리 바인드하지 않으면 스카이 박스에서 다른 (이전에 그려진) 오브젝트 텍스처가 사용된다는 것입니다. 이 이전에 그려진 개체는 다른 셰이더를 사용합니다.

그래서 셰이더 프로그램을 다시 사용할 때 텍스처 바인딩이 복원된다고 가정하는 것은 잘못입니까?

ps : 나는 cubemap이 아닌 skybox에 대해 단일 2d 텍스처를 사용합니다.

답변

6

예, 지정된 셰이더 프로그램을 사용할 때 텍스처 바인딩이 복원되었다고 가정하면 문제가 발생합니다.

텍스처 바인딩 상태는 현재 셰이더 프로그램과 완전히 독립적입니다. 현재 텍스처 유닛타겟마다 텍스처가 바인드되어 있습니다.

glActiveTexture(GL_TEXTURE7); 
glBindTexture(GL_TEXTURE_2D, myTexId); 

당신이 텍스처 유닛 (7)의 2D 대상으로 ID를 myTexId과 질감을 결합하고 당신이 장치의 2D 대상에 다른 질감을 결합 할 때까지이 상태가 유지됩니다 : 다음 코드 시퀀스를 실행하면 말 7 (또는 텍스처 삭제). 셰이더 프로그램이 활성화되어 있는지와 완전히 독립적입니다.

텍스처와 쉐이더 프로그램 사이의 관계는 프로그램의 샘플러 균일 변수 값을 텍스처 단위로 설정함으로써 설정됩니다. 위의 예를 계속, 주어진 프로그램에 의해이 텍스처를 사용하도록 지정 : 당신이 바인딩 텍스처에 대한 중복 호출을 피하려면,이를 바탕으로

// needed only once after linking the program 
GLint texLoc = glGetUniformLocation(myProgId, "MySampler"); 

// use the texture bound to unit 7 
glUseProgram(myProgId); 
glUniform1i(texLoc, 7); 

, 당신은 무엇 질감을 추적 할 것 어느 단위에 속해 있는가? 이 정보는 "전역 적"으로, 즉 특정 셰이더 프로그램과 독립적으로 유지되어야합니다.

균등 값 은 프로그램 당입니다. 따라서 다른 프로그램에 바인딩 된 텍스처에서 샘플링하지 않으려면 특정 프로그램을 바인딩 한 후에 값을 다시 설정할 필요가 없습니다.

서로 다른 텍스처를 바인딩해야하는 횟수를 줄이기 위해 할 수있는 한 가지 방법은 각 셰이더에 대해 서로 다른 텍스처 단위를 사용하는 것입니다. 단순화 된 예로서, 각 프로그램이 하나의 텍스처를 사용하고 프로그램이 사용될 때마다 동일한 텍스처를 사용하는 상황을 그림으로 그려보십시오. 그런 다음 각 프로그램의 샘플러 유니폼에 대해 다른 값을 설정하고 각 프로그램에서 사용하는 텍스처를 해당 텍스처 단위에 바인딩 할 수 있습니다. 각 프로그램은 glBindTexture()을 호출하지 않고 glUseProgram()에 전화 할 때마다 해당 텍스처를 사용합니다.

물론 프로그램이 여러 텍스처를 사용할 때 좀 더 복잡해지고 특정 프로그램의 텍스처를 전환하고 싶습니다. 그러나 텍스처 유닛을 영리하게 관리한다면 여전히 텍스처 바인딩 작업의 수를 크게 줄일 수 있습니다. 이를 수행하면서 텍스처 유닛의 수가 제한된다는 것을 명심하십시오. 한계는 다음과 같이 질의 될 수 있습니다 :

glGetIntegerv(MAX_TEXTURE_IMAGE_UNITS, ...); 

한계는 ES 2.0의 경우 8로 낮을 수 있습니다.

다른 각도에서 같은 것을 보는 것 : 사용 가능한 텍스처 단위 수보다 적은 텍스처를 사용하는 경우 각 텍스처를 다른 텍스처 단위에 한 번 바인드하고 텍스처 바인딩을 사용하여 완료 할 수 있습니다. 그런 다음 샘플러 유니폼을 원하는 텍스처가 바인딩 된 텍스처 단위로 설정하여 주어진 시간에 각 셰이더가 사용하는 텍스처를 제어합니다.

실제로 앱이 다소 복잡한 경우 이러한 접근 방식을 혼용 할 가능성이 큽니다. 예를 들어 자주 사용되는 텍스처 몇 개를 고정 된 텍스처 단위에 계속 바인딩 할 수 있으며 필요한 경우 다른 텍스처를 리바 인딩 할 수 있습니다.

이 모두가 정말, 내가 관계를 요약 할 것보다 더 복잡하게 들릴 수도 있기 때문에 :

  • 각 프로그램은 균일 한 값 세트를 갖습니다. 특정 프로그램이 활성화되어있는 동안 호출
  • glUniform1i()
  • 는 상기 셰이더 프로그램 와 질감 부 사이의 관계를 수립한다.
  • glBindTexture()텍스쳐 유닛텍스쳐 오브젝트 사이의 관계를 설정합니다.

따라서 텍스처 단위는 프로그램과 텍스처 개체 사이에 간접적 인 수준을 제공하여 텍스처 바인딩 상태가 특정 프로그램의 일부가 아닌 이유를 설명합니다.

+0

훌륭한 답변을 보내 주셔서 감사합니다. 바인딩에 대해 혼란 스러웠습니다. – agnu17