2014-10-24 2 views
3

라이트 데이터를 유지하기위한 구조체 배열을 사용하여 GLSL로 작성된 셰이더가 있습니다. 나는 좋은 연습처럼 배열 크기를 선언하기 위해 상수를 사용한다. 이제이 변수가GLSL 셰이더에서 상수 가져 오기

const int NUM_POINT_LIGHTS = 100; 

어떻게 C 내 C++ 프로그램이 그것을 사용할 수 있습니다 정확히 얼마나 많은 조명을 알 수 있도록, 쉐이더에서이 데이터를 끌어 ++ 사용할 수 있습니다로 선언한다고 가정 해 봅시다? 균일 한 사양은 단순히 CONST 사양을 오버라이드 것처럼 OpenGL을 내가 배열을 초기화하는 것을 불평으로 나는 이상하게도하지만, 그것은 나타납니다 (이 작동하지 않았다 예상대로

const uniform int NUM_POINT_LIGHTS = 100; 

로 선언 시도했습니다 비 const 값). 또한이 나는 데이터의 보류를 얻을 수 있도록하기 위해 어떻게 든 사용되는 균일 한 생각으로 GLSL을 추적 할 수 있도록 GLSL 사용하지 않는 유니폼을 멀리 최적화는 사실을 제외하고, 일하는 것이

const int NUM_POINT_LIGHTS = 100; 
uniform numPointLights = NUM_POINT_LIGHTS; 

을 시도했다. 다른 값을 얻기 위해 프로그램을 쿼리하는 다른 방법을 찾을 수 없었습니다. 아무도 셰이더에서 상수를 가져올 수있는 방법에 대한 아이디어가 있습니까? 내 프로그램이 셰이더에서 기능적으로 인코딩 된 정보를 얻으려고 사용합니까?

+1

일반적으로 말하면, 쉐이더 컴파일 후에 그런 식으로 쓰여진 상수는 유니폼이됩니다. NV GLSL 구현에서'_main_NUM_POINT_LIGHTS'와 같은 것으로 불릴 것 같습니다. 나는 그것이 일어 났는지보기 위해 당신이 당신의 프로그램에있는 모든 유니폼을 열거하는 것이 좋습니다.나는 당신이 결국 무엇을 성취하려고하는지 잘 모르겠다. 만약 당신이 데이터의 배열을 원한다면, UBO를 사용하는 것이 더 좋을 것이다. 왜냐하면 그것은 같은 제약 조건 (예를 들어, 컴포넌트)를 유니폼으로 사용합니다. –

+0

UBO의 구성 요소는 최대 유니폼 구성 요소 수를 기준으로 계산 한 것으로 가정했는데, 460m의 2048 개 유니폼 구성 요소 위에 여러 요소가 포함 된 배열을 추가하지 않은 것이 비교적 쉽습니다. 프래그먼트 쉐이더. 사실 UBO를 사용하고 있지만 UBO를 사용할 때도 C++ 프로그램에서 사용할 수있는 광원 수를 동적으로 결정할 수 있다는 것이 좋습니다. 유니폼이 만들어지는 모습을 살펴보고 다른 하드웨어로 포팅 할 수없는 솔루션처럼 들리 겠지만. – Darinth

+0

그런 행운, 내 상수에 대한 제복. – Darinth

답변

8

저는 상수 값을 직접 얻을 수 있다고 생각하지 않습니다. 그러나, 당신은 상수의 값을 사용해야한다고 생각합니다. 가장 큰 것은 일정한 배열의 크기입니다. 이 경우 일정한 배열의 크기를 얻을 수 있습니다.이 배열은 간접적으로 상수 값을 가져옵니다. 당신이 다음이 균일의 속성을 검색 할 수 있습니다이 인덱스를 사용

const GLchar* uniformName = "LightPositions"; 
GLuint uniformIdx = 0; 
glGetUniformIndices(program, 1, &uniformName, &uniformIdx); 

:

const int NUM_POINT_LIGHTS = 100; 
uniform vec3 LightPositions[NUM_POINT_LIGHTS]; 

그럼 먼저이 균일의 인덱스를 얻을 수 있습니다 :

은 쉐이더가 같은 것을 포함 말 :

const int nameLen = strlen("LightPositions") + 1; 
const GLchar name[nameLen]; 
GLint uniformSize = 0; 
GLenum uniformType = GL_NONE; 
glGetActiveUniform(program, uniformIdx, nameLen, NULL, 
        &uniformSize, &uniformType, name); 

uniformSizeNUM_POINT_LIGHTS 상수. 이것을 시도하지는 않았지만 문서를 기반으로 논쟁의 여지가 있기를 바랍니다.

다소 못 생기는하지만 아주 실제적인 해결책은 물론 쉐이더 소스 코드의 값을 파싱하는 것입니다. 어쨌든 glShaderSource()으로 전달하기 전에 읽어야하므로 상수 값을 선택하는 것이 충분히 쉬워야합니다.

또 다른 옵션은 여러 위치에서 상수를 사용하지 않으려면 C++ 코드에서 정의하고 셰이더 코드를 읽은 후 동적으로 셰이더 코드에 상수 정의를 추가하는 것입니다 그것을 지나치면 glShaderSource() 가라.

+2

쉐이더 소스에'#define NUM_POINT_LIGHTS'를 동적으로 주입하기 위해 +1 – jozxyqk

+0

불행하게도 구조체의 배열에 glGetUniformIndices를 사용할 수 없습니다. 개별 요소마다 자체 인덱스가 아니라 배열에 배열이 하나 있습니다. 그러나 소스에서 값을 파싱하거나 소스에 동적으로 추가하면이 함수를 만드는 데 정말 좋은 방법으로 작동합니다. 동적으로 추가하면 실제로 최상의 옵션이 될 수 있습니다. 여러 쉐이더는 변수로 쓰여지고 progra와 지속적으로 동기화됩니다. m 기능을 제공합니다. – Darinth

0

GLSL 프로그램에서 상수를 쿼리 할 수는 없습니다. 그런 것은 GLSL 스펙에 정의되어 있지 않습니다.

균일 버퍼 객체는 최적화 된 유니폼 문제를 해결할 수있는 방법 일 수 있습니다. https://www.opengl.org/wiki/Uniform_Buffer_Object

+0

불행히도 UBO 회원은 초기화 프로그램을 사용할 수 없습니다. : – Darinth

+0

나는 모든 것을 동적으로 만들려고 열심히 노력하고 있다고 생각한다. 당신은 벤더 종속적 인 해결책을 완전히 취할 수도 있고, 쉐이더 자체의 소스 코드를 볼 수도있다. – BlamKiwi

관련 문제