2014-07-07 4 views
2

저는 GLSL 프로그램에 값을 전달하는 방법에 대해 여러 가지 예제를 검색하고 읽고 시도했습니다. 하지만 슬프게도 모든 시도는 실패했습니다. (이 예에서 glUniform1f를 사용하는 방법은 무엇입니까?

내가 계획하고있는 것은 매우 간단합니다 : 안드로이드 애플 리케이션 내에서 약간 열린 gl 3d 애니메이션. 내 GUI 디자인으로 인해 OpenGl Surface로 TextureView를 사용하는 것을 선호합니다. 내 프로젝트에 완벽하게 맞는 몇 가지 코드를 발견했다.

하지만 내 문제가 this example 내부에 완전히 것 같다.

을 내가 컴파일하고 실행하면 어떻게해야 정확히 않습니다. 하나 하나 개의 삼각형을 그리기 화면.

그런 다음 Vertex Shader를 다음과 같이 수정했습니다.

final String vertexShaderSource = 
    "attribute vec4 position;\n" + 
    "attribute float myValue;\n" + 
    "void main() {\n" + 
     "vec4 oo;\n"+ 
     "oo[0] = position[0];\n"+ 
     "oo[1] = position[1] * myValue;\n"+ 
     "oo[2] = position[2];\n"+ 
     "oo[3] = position[3];\n"+ 
     "gl_Position = oo;\n" + 
    "}"; 

이제 값 myValue에 값을 전달하고 싶습니다.

그래서 여기에 run 메소드를 수정했습니다.

public void run() { 
    initGL(); 

    int attribPosition = GLES20.glGetAttribLocation(mProgram, 
      "position"); 
    checkGlError(); 

    int valuePosition = GLES20.glGetAttribLocation(mProgram, 
      "myValue"); 
    checkGlError(); 

    System.out.println("att id:"+ attribPosition 
      + " val id:" + valuePosition); 

//[...] 

    while (true) { 
     checkCurrent(); 

     mVertices.position(0); 
     GLES20.glVertexAttribPointer(attribPosition, 3, 
       GLES20.GL_FLOAT, false, 0, mVertices); 
     checkGlError(); 

     GLES20.glUniform1f(valuePosition, 1.5f); 
     checkGlError(); 
    //[...]   
    } 
} 

제 생각에 y 축의 삼각형이 1.5f로 확대되어야합니다. 하지만 작동하지 않습니다. 내 디버그 라인의 OUPUT은 다음과 같습니다 그들 중 누구도이 없기 때문에 -1 컨텐츠를

I/System.out(22427): att id:1 val id:0 

그래서 이들은 올바른 위치해야한다. 1.5f 값을 myValueglUniform1f으로 전달하면 내가 얻을 수있는 유일한 결과는 연속 OpenGL Error 0x502 출력입니다. 셰이더 스크립트가 1.5f을받지 못하고 값 0을 사용하여 확장하기 때문에 더 이상 삼각형이 없습니다.

정말 누군가가 나를 설명 할 수 있기를 바랍니다. 어떻게해야할까요? 그게 근본적인 무언가이기 때문에 나는 여기서 아주 명백한 것을 놓치고 있다고 생각합니다.

다음
+0

쉐이더 실행 중에 OpenGL 오류가 발생하는지 확인하고 문제를 업데이트하십시오. –

+0

다른 OpenGL 오류가 없습니다. 그리고이 예제는 오류를 많이 점검합니다. – ArcticLord

답변

5

당신은 attributeuniform 변수의 개념을 혼합하고 있습니다.,

glVertexAttrib1f(valuePosition, 1.5f); 

당신이 그것을이 uniform 싶은 경우에 버텍스 쉐이더에서 선언을 변경 : 당신이 쉐이더의 attributemyValue 변수를 선언 한 이후

, 당신은 glVertexAttrib()으로 값을 설정해야 :

int valuePosition = GLES20.glGetUniformLocation(mProgram, "myValue"); 
:

uniform float myValue; 

및 호출에 위치를 얻을 수

두 가지 모두 유효합니다. 이름에서 알 수 있듯이 uniform 변수는 많이 변하지 않는 값, 즉 이상적으로 전체 프레임에서 동일하게 유지되는 값에 이상적입니다. attribute 변수는 프레임을 렌더링하는 동안 자주 변경되는 값에 대해 더 효율적입니다.

0

시도의 수정 :

"attribute float myValue;\n" -> "uniform float myValue;\n"

int valuePosition = GLES20.glGetAttribLocation(mProgram, "myValue"); - 또한>int valuePosition = GLES20.glGetUniformLocation(mProgram, "myValue");

을, 더 깨끗한 방법을 보여줍니다 다음 설명서 페이지를 참조,이 버텍스 번역 및 스케일링

http://developer.android.com/reference/android/opengl/Matrix.html

0

유니폼을 신고하기 전에 glUniform1f을 설정해야합니다. 따라서 myValue을 동일하게 만드십시오.

uniform float myValue; 

다음으로 값을 바인딩 할 위치가 필요합니다. 당신은 glGetUniformLocation 기능을 사용하여 그렇게 할 수 있습니다.

int valuePosition = GLES20.glGetUniformLocation(mProgram, "myValue"); 

마지막으로 glUniform 기능을 사용하여 해당 위치에 유니폼을 설정했습니다.

GLES20.glUniform1f(valuePosition, 0.5f); 

그리고 속성을 사용해도 동일한 결과를 얻을 수 있습니다. 속성은 값을 지속적으로 변경하는 데는 효율적이지만 유니폼은 값을 변경하지 않아도 효율적입니다.