2016-07-16 16 views
-1

我一直在遵循www.learnopengl.com教程,并尝试使用所述的方法加载模型。它一直工作到它要求你用2点灯加载纳米服装的那一端。我已经从教程中复制了精确的代码:camera,mesh,model和shader classes,但问题出在片段着色器上。如果我尝试一个简单的如:learnopengl教程片段着色器2点灯

#version 330 core 

in vec2 TexCoords; 

out vec4 color; 

uniform sampler2D texture_diffuse1; 

void main() 
{  
    color = vec4(texture(texture_diffuse1, TexCoords)); 
} 

,模型加载和纹理也。但是,如果试图进行2点照明纹理给出的解决方案是黑色:

#version 330 core 
struct Material { 
    sampler2D texture_diffuse1; 
    sampler2D texture_specular1; 
    float shininess; 
}; 
/* Note: because we now use a material struct again you want to change your 
mesh class to bind all the textures using material.texture_diffuseN instead of 
texture_diffuseN. */ 

struct PointLight { 
    vec3 position; 

    float constant; 
    float linear; 
    float quadratic; 

    vec3 ambient; 
    vec3 diffuse; 
    vec3 specular; 
}; 

#define NR_POINT_LIGHTS 2 

in vec3 fragPosition; 
in vec3 Normal; 
in vec2 TexCoords; 

out vec4 color; 

uniform vec3 viewPos; 
uniform PointLight pointLights[NR_POINT_LIGHTS]; 
uniform Material material; 

// Function prototypes 
vec3 CalcPointLight(PointLight light, Material mat, vec3 normal, vec3 fragPos, vec3 viewDir); 

void main() 
{  
    vec3 result; 
    vec3 viewDir = normalize(viewPos - fragPosition); 
    vec3 norm = normalize(Normal); 

    for(int i = 0; i < NR_POINT_LIGHTS; i++) 
     result += CalcPointLight(pointLights[i], material, norm, fragPosition, viewDir); 

    color = vec4(result, 1.0f); 
} 


// Calculates the color when using a point light. 
vec3 CalcPointLight(PointLight light, Material mat, vec3 normal, vec3 fragPos, vec3 viewDir) 
{ 
    vec3 lightDir = normalize(light.position - fragPos); 
    // Diffuse shading 
    float diff = max(dot(normal, lightDir), 0.0); 
    // Specular shading 
    vec3 reflectDir = reflect(-lightDir, normal); 
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), mat.shininess); 
    // Attenuation 
    float distance = length(light.position - fragPos); 
    float attenuation = 1.0f/(light.constant + light.linear * distance + light.quadratic * (distance * distance));  
    // Combine results 
    vec3 ambient = light.ambient * vec3(texture(mat.texture_diffuse1, TexCoords)); 
    vec3 diffuse = light.diffuse * diff * vec3(texture(mat.texture_diffuse1, TexCoords)); 
    vec3 specular = light.specular * spec * vec3(texture(mat.texture_specular1, TexCoords)); 
    ambient *= attenuation; 
    diffuse *= attenuation; 
    specular *= attenuation; 
    return (ambient + diffuse + specular); 
} 

我还修改了网格类作为从在片段着色器描述:

glUniform1i(glGetUniformLocation(shader.Program, (name + number).c_str()), i); 

到:

glUniform1i(glGetUniformLocation(shader.Program, ("material." + name + number).c_str()), i); 

是否有人有同样的问题?

+0

为什么downvote?解释会很有用。 –

+0

你看着你的着色器编译错误吗? –

+0

我没有。它编译得很好,但运行它显示黑色纹理。这些制服是否不能通过主要的其他功能进入? –

回答

0

看来GLSL不喜欢功能。如果我将CalcPointLight()代码放在main()中,它就可以工作!

#version 330 core 
struct Material { 
    sampler2D texture_diffuse1; 
    sampler2D texture_specular1; 
    float shininess; 
}; 
/* Note: because we now use a material struct again you want to change your 
mesh class to bind all the textures using material.texture_diffuseN instead of 
texture_diffuseN. */ 

struct PointLight { 
    vec3 position; 

    float constant; 
    float linear; 
    float quadratic; 

    vec3 ambient; 
    vec3 diffuse; 
    vec3 specular; 
}; 

#define NR_POINT_LIGHTS 2 

in vec3 fragPosition; 
in vec3 Normal; 
in vec2 TexCoords; 

out vec4 color; 

uniform vec3 viewPos; 
uniform PointLight pointLights[NR_POINT_LIGHTS]; 
uniform Material material; 

void main() 
{ 
    vec3 result; 
    vec3 viewDir = normalize(viewPos - fragPosition); 
    vec3 norm = normalize(Normal); 

    vec3 lightDir = normalize(pointLights[0].position - fragPosition); 

    // Diffuse shading 
    float diff = max(dot(norm, lightDir), 0.0); 

    // Specular shading 
    vec3 reflectDir = reflect(-lightDir, norm); 
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 

    // Attenuation 
    float distance = length(pointLights[0].position - fragPosition); 
    float attenuation = 1.0f/(pointLights[0].constant + pointLights[0].linear * distance + pointLights[0].quadratic * (distance * distance)); 

    // Combine results 
    vec3 ambient = pointLights[0].ambient * vec3(texture(material.texture_diffuse1, TexCoords)); 
    vec3 diffuse = pointLights[0].diffuse * diff * vec3(texture(material.texture_diffuse1, TexCoords)); 
    vec3 specular = pointLights[0].specular * spec * vec3(texture(material.texture_specular1, TexCoords)); 
    ambient *= attenuation; 
    diffuse *= attenuation; 
    specular *= attenuation; 
    result = ambient+diffuse+specular; 

    color = vec4(result, 1.0f); 
} 

编辑:在那里发现了答案:GLSL sampler2D in struct。您不能实例化包含诸如sampler2D之类的不透明类型的结构。

EDIT1:您实际上可以使用这些变量到一个函数,而不将它们作为参数,因为它们是全局定义:

#version 330 core 
struct Material { 
    sampler2D texture_diffuse1; 
    sampler2D texture_specular1; 
    float shininess; 
}; 
/* Note: because we now use a material struct again you want to change your 
mesh class to bind all the textures using material.texture_diffuseN instead of 
texture_diffuseN. */ 

struct PointLight { 
    vec3 position; 

    float constant; 
    float linear; 
    float quadratic; 

    vec3 ambient; 
    vec3 diffuse; 
    vec3 specular; 
}; 

#define NR_POINT_LIGHTS 2 

in vec3 fragPosition; 
in vec3 Normal; 
in vec2 TexCoords; 

out vec4 color; 

uniform vec3 viewPos; 
uniform PointLight pointLights[NR_POINT_LIGHTS]; 
uniform Material material; 

vec3 CalcLights(int i); 

void main() 
{ 
    vec3 result; 
    for(int i=0; i<NR_POINT_LIGHTS; i++) 
     result += CalcLights(i); 
    color = vec4(result, 1.0f); 
} 

vec3 CalcLights(int i) //viewPos fragPosition pointLights[] Normal material TexCoords 
{ 
    vec3 viewDir = normalize(viewPos - fragPosition); 
    vec3 norm = normalize(Normal); 

    vec3 lightDir = normalize(pointLights[i].position - fragPosition); 

    // Diffuse shading 
    float diff = max(dot(norm, lightDir), 0.0); 

    // Specular shading 
    vec3 reflectDir = reflect(-lightDir, norm); 
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 

    // Attenuation 
    float distance = length(pointLights[i].position - fragPosition); 
    float attenuation = 1.0f/(pointLights[i].constant + pointLights[i].linear * distance + pointLights[i].quadratic * (distance * distance)); 

    // Combine results 
    vec3 ambient = pointLights[0].ambient * vec3(texture(material.texture_diffuse1, TexCoords)); 
    vec3 diffuse = pointLights[0].diffuse * diff * vec3(texture(material.texture_diffuse1, TexCoords)); 
    vec3 specular = pointLights[0].specular * spec * vec3(texture(material.texture_specular1, TexCoords)); 
    ambient *= attenuation; 
    diffuse *= attenuation; 
    specular *= attenuation; 

    return (ambient+diffuse+specular); 
}