2014-11-13 6 views
0

쉐이더의 서브 루틴을 Phong에서 Diffuse 조명으로 "전환"하는 데 어려움을 겪고 있습니다. 그러나 모든 기능이 항상 내 쉐이더에서 항상 호출되도록 선언되었습니다.LWJGL GLSL 서브 루틴이 변경되지 않습니다

는 여기에 내가

sub1 = GL40.glGetSubroutineIndex(programID, GL20.GL_VERTEX_SHADER, "diffuseOnly"); 
sub2 = GL40.glGetSubroutineIndex(programID, GL20.GL_VERTEX_SHADER, "phongModel"); 

는 각각 0과 1의 위치를 ​​생산하는이 단지 GLdrawelements 전에 내 렌더링 방법에 내 쉐이더

#version 430 
subroutine vec3 shadeModelType(vec4 position, vec3 normal); 
subroutine uniform shadeModelType shadeModel; 
layout (location = 0) in vec3 VertexPosition; 
layout (location = 1) in vec3 VertexNormal; 


out vec3 LightIntensity; 
struct LightInfo { 
vec4 Position; // Light position in eye coords. 
vec3 La;  // Ambient light intensity 
vec3 Ld;  // Diffuse light intensity 
vec3 Ls;  // Specular light intensity 
}; 
uniform LightInfo Light; 

struct MaterialInfo { 
vec3 Ka;   // Ambient reflectivity 
vec3 Kd;   // Diffuse reflectivity 
vec3 Ks;   // Specular reflectivity 
float Shininess; // Specular shininess factor 
}; 
uniform MaterialInfo Material; 

uniform mat4 viewMatrix; 
uniform mat4 transformationMatrix; 

uniform mat3 normalMatrix; 
uniform mat4 ProjectionMatrix; 


void getEyeSpace(out vec3 norm, out vec4 position) 
{ 
norm = normalize( mat3(transpose(inverse(viewMatrix *transformationMatrix))) *  

VertexNormal); 

position = viewMatrix * transformationMatrix * vec4(VertexPosition,1.0); 
} 

subroutine(shadeModelType) 
vec3 phongModel(vec4 position, vec3 norm) 
{ 
vec3 s = normalize(vec3(Light.Position - position)); 
vec3 v = normalize(-position.xyz); 
vec3 r = reflect(-s, norm); 
vec3 ambient = Light.La * Material.Ka; 
float sDotN = max(dot(s,norm), 0.0); 
vec3 diffuse = Light.Ld * Material.Kd * sDotN; 
vec3 spec = vec3(0.0); 
if(sDotN > 0.0) 
    spec = Light.Ls * Material.Ks * 
      pow(max(dot(r,v), 0.0), Material.Shininess); 

return ambient + diffuse + spec; 
} 

subroutine(shadeModelType) 
vec3 diffuseOnly(vec4 position, vec3 norm) 
{ 
    vec3 s = normalize(vec3(Light.Position - position)); 
    return 
    Light.Ld * Material.Kd * max(dot(s, norm), 0.0); 
} 


void main() 
{ 
    mat4 modelViewProject = ProjectionMatrix * viewMatrix *transformationMatrix ; 
    mat4 normalMatrix = transpose(inverse(viewMatrix *transformationMatrix)); 

    vec3 eyeNorm; 
    vec4 eyePosition; 

    // Get the position and normal in eye space 
    getEyeSpace(eyeNorm, eyePosition); 

    // Evaluate the shading equation. This will call one of 
    // the functions: diffuseOnly or phongModel. 
    LightIntensity = shadeModel(eyePosition, eyeNorm); 

    gl_Position = modelViewProject * vec4(VertexPosition,1.0); 
} 

입니다.

int routineUniform = GL40.glGetSubroutineUniformLocation(programID, 
GL20.GL_VERTEX_SHADER, "shadeModel"); 
IntBuffer subroutineBuffer = BufferUtils.createIntBuffer(1).put(sub1); 
System.out.println(routineUniform); //produces a 0; 
System.out.println(GL40.glGetProgramStagei(programID, 
GL20.GL_VERTEX_SHADER, GL40.GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS)); 
//prints 1; 

GL40.glUniformSubroutinesu(GL20.GL_VERTEX_SHADER, subroutineBuffer); 

버퍼 utils.createIntBuffer (2)를 시도하고 두 가지를 모두 넣었으므로 2 개의 별도의 int 버퍼를 만들었습니다. 사실 sub1과 sub2 위치를 완전히 제거했으며 기본값은 선언 된 첫 번째 함수로 돌아갑니다.

답변

0

put() 후에 glUniformSubroutinesu를 호출하기 전에 IntBuffer에서 flip()을 호출해야하는 것처럼 보입니다. 그렇지 않으면 버퍼가 처음으로 되 감겨지지 않고 효과적으로 아무것도 보내지 않습니다.

+0

와우가 완전히 옳습니다. 매력처럼 작동합니다. 문제를 단순히 subroutineBuffer.flip(); 당신이 원하는 루틴을 넣은 후 그것을 전환합니다!. 감사 Brian 좋은 추수 감사절!. –