2014-01-23 4 views
0

개체에 다른 색상으로 간단한 Gouraud 쉐이딩을하고 싶습니다. 근본적으로 제 문제는 셰이더에 색상 값을 가져올 수 없다는 것입니다. 그냥 검정색으로 렌더링됩니다. 셰이더의 벡터를 전체 객체의 색상으로 정의하면 잘 동작합니다.GLSL 1.5에서 색상 입력을 얻을 수 없습니다.

메인 프로그램 :

protected void initOpenGL() { 
    glEnable(GL_DEPTH_TEST); 
    glEnable(GL_CULL_FACE); 
    startTime = Sys.getTime(); 

    m = new Matrix4f(); 
    m.m00 = 1; 
    m.m11 = 1; 
    m.m22 = -(101.0f/99); 
    m.m32 = -(200.0f/99); 
    m.m23 = -1; 
    m.m33 = 0; 

    makeCube(); 

    sp = new ShaderProgram("gouraud"); 
    glBindAttribLocation(sp.getId(), 0, "corners"); 
    glBindAttribLocation(sp.getId(), 1, "colors"); 

} 

@Override 
protected void render() { 

    gamma = gamma + 1; 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    Matrix4f newMat = new Matrix4f(m); 
    Matrix4f.translate(new Vector3f(0, 0, -5), newMat, newMat); 
    newMat.rotate(gamma/100, new Vector3f(0, 1, 0)); 
    newMat.rotate(gamma/200, new Vector3f(1, 0, 0)); 

    FloatBuffer fb = BufferUtils.createFloatBuffer(16); 
    newMat.store(fb); 
    fb.flip(); 
    GL20.glUniformMatrix4(GL20.glGetUniformLocation(sp.getId(), "matrix"), 
      false, fb); 

    GL20.glUseProgram(sp.getId()); 


    glBindVertexArray(vaoId); 
    glEnableVertexAttribArray(0); 
    glEnableVertexAttribArray(1); 
    glDrawArrays(GL_QUADS, 0, corners.length/3); 
    glDisableVertexAttribArray(1); 
    glDisableVertexAttribArray(0); 
    glBindVertexArray(0); 

} 

private void makeCube(){ 
    corners = new float[] { 
      // cube 
      // front 
      -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 
      // left 
      -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 
      // bottom 
      -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 
      // right 
      1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 
      // top 
      -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 
      // back 
      -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 

    }; 

    FloatBuffer eckenBuffer = BufferUtils.createFloatBuffer(corners.length); 
    eckenBuffer.put(corners); 
    eckenBuffer.flip(); 

    vaoId = glGenVertexArrays(); 
    glBindVertexArray(vaoId); 
    int vboId = glGenBuffers(); 
    glBindBuffer(GL_ARRAY_BUFFER, vboId); 
    glBufferData(GL_ARRAY_BUFFER, eckenBuffer, GL_STATIC_DRAW); 
    glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 


    colors = new float[] { 
      // front 
      1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 

      // right 
      1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 

      // back 
      1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 

      // left 
      0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 

      // top 
      0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 

      // bottom 
      1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f }; 

    FloatBuffer colorBuffer = BufferUtils.createFloatBuffer(colors.length); 
    colorBuffer.put(colors); 
    colorBuffer.flip(); 

    int vboIdB = glGenBuffers(); 
    glBindBuffer(GL_ARRAY_BUFFER, vboIdB); 
    glBufferData(GL_ARRAY_BUFFER, colorBuffer, GL_STATIC_DRAW); 
    glVertexAttribPointer(1, 3, GL_FLOAT, false, 0, 0); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
} 

쉐이더 :

정점

#version 150 
in vec4 corners; 
in vec4 colors; 

vec4 colorTest = vec4(1.0,0.0,0.0,1.0); 

out vec4 colorToFrag; 

uniform mat4 matrix; 

void main(void) { 
colorToFrag = colors ; 
gl_Position = matrix * corners; 

} 

조각

#version 150 
in vec4 colorToFrag; 

out vec4 colorOut; 

void main(void) { 
colorOut = colorToFrag; 
} 
+0

VAO를 사용하여 그리기 전후에 속성 배열을 활성화/비활성화하지 마십시오. 이것이 사실 VAO의 전체 요점입니다. 처음에는 VAO를 만들 때 모든 배열이 비활성화 된 채로 시작됩니다. VAO를 만들 때 필요한 배열을 활성화 할 수 있습니다. 그리기 전에 바운드 VAO를 변경하기 만하면됩니다. 활성화 된 어레이 세트는 사용자가 그릴 때 VAO가 바인딩 된 것과 직접 연결됩니다. * 이것으로 문제를 해결할 수는 없지만 알아 두어야 할 사항입니다. * –

+0

또한 GL20.glUniformMatrix4 (GL20.glGetUniformLocation (sp.getId(), "matrix")를 너무 일찍 호출합니다. *** 후에 *** glUseProgram (...)을 호출해야합니다. 그리고'glGetUniformLocation (...)'은 모든 프레임을 처리해야하는 것이 아니며 프로그램을 링크 한 후에이 색인을 계산해야합니다 클래스로 값을 저장하십시오. 이름으로 균일 한 위치를 검색하는 것은 매우 비효율적이므로 변경되지 않습니다. –

답변

1

당신은, 연결/셰이더 컴파일에 대한 코드를 게시하지 않았다 하지만 0으로 전화 했으니 까.하지만 나머지 코드에서는 glLinkProgram을 호출하지 않기 때문에 나는 해당 연결이 ShaderProgram 생성자에서만 발생한다는 교양있는 추측을합니다.

glBindAttribLocation 호출은 그 이후의 연결 작업에만 영향을 미칩니다. 그래서 귀하의 위치 바인딩은 전혀 효과가 없습니다 - GL은 그것들을 할당합니다.

셰이더에서 colors 특성을 사용하지 않으면 해당 셰이더는 특성이 최적화되고 특성이 활성화되지 않으므로 전혀 위치를 얻지 못하며 corners은 인덱스 0을 얻을 가능성이 높습니다. 너는 그것을 기대한다. GL은 속성 위치를 0부터 시작하여 순차적으로 처리 할 필요는 없지만 대부분은 수행합니다. '색'을 실제로 사용하면 위치가 0으로 끝나고 렌더링이 완전히 중단 될 수 있습니다.

다른 쪽 메모 : nvidia에서 GL로 할당 된 속성 위치가 실제로 셰이더의 변수 이름에 의해 사전 식으로 정렬 된 것처럼 보입니다. 따라서 '색상'이 '모서리'앞에옵니다. 우연의 일치인지, 아니면 다른 구현이 그것을 어떻게 처리하는지는 확실하지 않습니다.