我在使用着色器中的子程序从Phong“切换”到漫反射光照时遇到了麻烦,但我尝试过的所有内容都会导致在我的着色器中首先声明的任何函数始终被调用。
这是我的着色器
#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);
}
在我的GLdrawelements之前的渲染方法中
sub1 = GL40.glGetSubroutineIndex(programID, GL20.GL_VERTEX_SHADER, "diffuseOnly");
sub2 = GL40.glGetSubroutineIndex(programID, GL20.GL_VERTEX_SHADER, "phongModel");
分别产生0和1的位置。
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 :(得分:0)
看起来你需要在put()之后但在调用glUniformSubroutinesu之前调用IntBuffer上的flip()。否则,缓冲区不会重绕到开头,而您实际上没有发送任何内容。