2015-01-01 11 views
2

와 함께 사용 변수, 지옥에 대해 좀 uniform 변수가 적극적으로 파이프 라인의 출력에 기여하지 않는 경우,이 최적화되어 있음을 이해하고는 -1에 돌아옵니다. 아래의 조각 셰이더를 고려하십시오.glGetUniformLocation 반환 -1 최적화

const char fShader[] = "precision mediump float;            \n" 

    "uniform float uGlobalTime;           \n" 

    "const int iMaxIterations = 6;           \n" 
    "float fCircleSize = 1.0/(3.0 * pow(2.0, float(iMaxIterations)));  \n" 

    "vec2 Rotate(vec2 uv, float a)           \n" 
    "{                  \n" 
     "return vec2(uv.x * cos(a) - uv.y * sin(a), uv.y * cos(a) + uv.x * sin(a)); \n" 
    "}                  \n"; 


    "void main()             \n" 
    "{                \n" 
     "vec2 uv = vec2(1280.0, 720.0);            \n" 
     "uv = -0.5 * (uv - 2.0 * gl_FragCoord.xy)/uv.x;   \n" 

     "uv = Rotate(uv, uGlobalTime);       \n" 
     "uv *= sin(uGlobalTime) * 0.5 + 1.5;      \n" 

     "float s = 0.3;            \n" 
     "for(int i = 0 ; i < iMaxIterations; ++i)     \n" 
     "{               \n" 
      "uv = abs(uv) - s;          \n" 
      "uv = Rotate(uv, uGlobalTime);      \n" 
      "s = s/2.0;           \n" 
     "}               \n" 

     "float c = length(uv) > fCircleSize ? 0.0:1.0;    \n" 

     "gl_FragColor = vec4(c * uGlobalTime, c * uGlobalTime, c * uGlobalTime, 1.0);       \n" 

    "}                \n"; 

이것은 여러 위치에서 전달 된 유니폼을 사용하려고 시도하며 최종 출력 색상에서도 마찬가지입니다. 하지만 여전히 반환 값으로 -1을 얻고 있습니다. 그래도 오류는 없습니다. 나는 내 편이 좋다고 생각하지 않는다.

최적화가 완료되었습니다. 나는 활동적인 유니폼을 체크하지 않았고, 오직 2 가지만있다. 나는 3을 사용하고있다. 그러나 왜 지구상에 ..., 컴파일러 블라인드인지 .. ?? 속성을 사용하여 해결할 수 있지만 그 이유는 무엇입니까?

"attribute float vGlobalTime         \n" 
"varying float globalTime;          \n" 
"globalTime = vGlobalTime;          \n" 
: 적절한 위치에서 버텍스 쉐이더 3 줄을 추가

:

편집

난 내 자신의 해결 방법을 나열하고 내 버텍스 쉐이더뿐만 아니라

const char vShader[] = "attribute vec3 vPosition;          \n" 

"uniform mat4 uMVMatrix;          \n" 
"uniform mat4 uPMatrix;           \n" 

"void main(void)            \n" 
"{                \n" 
    "gl_Position = uPMatrix * uMVMatrix * vec4(vPosition, 1.0);      \n" 
"}                \n"; 

를 참조하십시오

및 1 개의 새 문자 프레 그먼트 쉐이더에서 오프라인 : 지금

"varying float globalTime;          \n" 

그리고 앞서 uGlobalTime

PS를 사용했던 모든 장소에서 globalTime를 사용 :이 테스트하지 않았습니다; 그러나 그것이 작동해서는 안되는 어떤 이유도 보이지 않습니다.

+0

? 무슨 속성? 속성은 정점 당이며, 이것은 프래그먼트 셰이더입니다. 나는 또한 오직 당신의 쉐이더에서 1 유니폼 만 볼 수 있습니다. 균일 한 위치는 _linker_의 함수이기 때문에 올바른 컨텍스트에 대한 질문에 정점 셰이더를 포함시켜야합니다. –

+0

@ AndonM.Coleman, 제복을 입은 것은 time_per_frame입니다. 따라서 버텍스 쉐이더와 파이프 라인에서 시간을 보내면 프래그먼트 쉐이더에 입력으로 제공 할 수 있습니다. 그렇다면 윤리학이 그것을 부인하지 않는 한 왜 내가 할 수 없는가? 나머지 두 유니폼은'mat4 Mprojection'과'mat4 MMview'입니다. 그것을 언급하는 것에 대해 유감스럽게 생각합니다. 그러나 여기에 버텍스 쉐이더에 대해 말했습니다. 이 두 행렬의 곱셈과'attibute vec3 aVer' – Adorn

+0

당신이 속성을 사용하지 않는다면 (나는'aVer'라고 가정합니다)이 문제가 발생한다고 말했습니까? 그 속성을 사용하지 않으면'gl_Vertex'의 소리에서 정의 된 값이 없으므로 조각 쉐이더의 결과는 정의되지 않습니다.이것은 모든 버텍스 쉐이더를 보지 않고 추측 한 것입니다.하지만 이것이 바로 이런 종류의 일입니다. 연결된 버텍스 쉐이더에서 정의되지 않은 출력은 비어있을 수도있는 프래그먼트 쉐이더로 연결됩니다. –

답변

5

당신의 조각 쉐이더 C++ 소스 문자열 정의의 7 행의 끝에 야생 세미콜론이 있습니다.

const char* source = 
    "line 1" 
    "line 2"; // <- semicolon intended? 
    "line 3+ ignored"; // <- lose string constant which is never assigned to anything 

이렇게하면 조각 쉐이더의 주요 기능을 건너 뛰고 전혀 링크하지 않아야합니다. Did you check for errors after linking your program?


이 같은 오타를 방지하는 외부 파일로 셰이더 코드를 아웃소싱에 대해 생각하고 또한 당신의 응용 프로그램이 셰이더를 변경할 때마다 재 컴파일에 대한 필요성을 제거합니다. 속성을 사용하여

bool Shader::compileFromFile(const std::string& filename) 
{ 
    std::ifstream stream(filename, std::ios_base::in); 
    if (!stream.is_open()) 
     return false; 
    std::string source{std::istreambuf_iterator<char>(stream), 
         std::istreambuf_iterator<char>()}; 
    return compile(source); 
} 
+0

눈이 좋긴하지만, 0에서 세는 것을 시작하지 않는다면 8 번째 줄을 의미한다고 생각하십니까? ;) –

+0

buhh ... 네 말이 맞아, 나는 게으름을 극복하고 쉐이더를 다른 파일에 두어야한다. 정말 고맙습니다. 완전을 기하기 위해서, 제안 된 방법은 안드로이드에서 file'd 쉐이더에 대해 작동하지 않을 것입니다. 압축 된 apk 파일이 될 것입니다. 자산 관리자가 필요합니다. – Adorn