OpenGL 3.3着色器统一变量不起作用

时间:2014-04-03 09:11:11

标签: c++ opengl glsl

我有两个着色器程序(因为我使用的是延迟着色),每个程序都带有Vertex和Fragment着色器。 我的问题是我可以成功地编译和链接它们(glGetProgramiv与GL_LINK_STATUS为每一个返回GL_TRUE)但是当我尝试获取我的第二个着色器程序的制服的地址时我只能得到其中的3个,而不是27个是目前宣布。

我已经检查了glGetProgramiv和GL_ACTIVE_UNIFORMS以检查每个着色器程序的制服数量,并检查第一个是正确的,但是对于第二个它是错误的。

我注意到我可以从secondo程序获得的唯一制服是它的顶点着色器的前3个,即使我在该顶点着色器中添加了一个制服,可读制服的数量也总是3。

(我只添加了我的制服声明,因为着色器太长了。)

这是第一个程序顶点着色器(正常工作)的代码

uniform struct Matrices
{
    mat4 projectionMatrix;
    mat4 modelMatrix;
    mat4 viewMatrix;
    mat4 normalMatrix;
} matrices;

layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec2 inCoord;
layout (location = 2) in vec3 inNormal;
layout (location = 3) in vec3 inTangent;

这是第一个程序片段着色器(正常工作)的代码

uniform sampler2D gSampler;
uniform sampler2D gSamplerBump;
uniform vec4 vColor;

uniform float       gMatSpecularIntensity;
uniform float       gSpecularPower;
uniform float       gRetroilluminato;

uniform int useTexture;
uniform int useTextureBump;
uniform int fondiTextureColore;

这些是顶点和片段着色器无法正常工作。

顶点:

uniform struct Matrici
{
    mat4 projectionMatrix;
    mat4 modelMatrix;
    mat4 viewMatrix;
} matrici;

片段:

uniform struct MDLight
{
    vec3 vColor;
    vec3 vPosition;
    vec3 vDirection;  

    float fAmbientIntensity;
    float fStrength;

    int bOn;

    float fConeAngle;
    float fConeCosine;

    float fConstantAtt;
    float fLinearAtt;
    float fExpAtt;

    float fAltezza;
    float fLarghezza;

    vec3 vUp;
    vec3 vRight;
} gLuce;

uniform float gSpecularIntensity;
uniform float gSpecularPower;

uniform sampler2D gPositionMap;
uniform sampler2D gColorMap;
uniform sampler2D gNormalMap;
uniform vec3 gCameraPos;

uniform vec2 gScreenSize;
uniform int gLightType;

uniform int gUsaLuci;

基本上我只能在我的第二个程序顶点着色器的统一结构“Matrici”中获得projectionMatrix,modelMatrix和viewMatrix的广告。 我已经尝试在结构体内部和外部添加一个值,但它不会读它。

有想法的人吗?


正如@ rems4e所说,这些是完整的着色器。

工作程序的顶点着色器。

#version 330

uniform struct Matrices
{
    mat4 projectionMatrix;
    mat4 modelMatrix;
    mat4 viewMatrix;
    mat4 normalMatrix;
} matrices;

layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec2 inCoord;
layout (location = 2) in vec3 inNormal;
layout (location = 3) in vec3 inTangent;

smooth out vec2 texCoord;
smooth out vec3 vNormal;
smooth out vec3 vTangent;
smooth out vec3 vEyeSpacePos;
smooth out vec3 vWorldPos;

void main()
{
    vec4 vEyeSpacePosVertex = matrices.viewMatrix*matrices.modelMatrix*vec4(inPosition, 1.0);
    gl_Position = matrices.projectionMatrix*vEyeSpacePosVertex;

    texCoord = inCoord;

    vec4 vRes = matrices.normalMatrix*vec4(inNormal, 0.0);
    vNormal = vRes.xyz;

    vec4 vResTang = matrices.normalMatrix*vec4(inTangent, 0.0);
    vTangent = vResTang.xyz;

    vEyeSpacePos = vEyeSpacePosVertex.xyz;

    vec4 vWorldPosVertex = matrices.modelMatrix*vec4(inPosition, 1.0);
    vWorldPos = vWorldPosVertex.xyz;
}

工作程序的片段着色器。

#version 330

smooth in vec2 texCoord;
smooth in vec3 vNormal;
smooth in vec3 vTangent;
smooth in vec3 vEyeSpacePos;
smooth in vec3 vWorldPos;

layout (location = 0) out vec4 WorldPosOut; 
layout (location = 1) out vec4 DiffuseOut; 
layout (location = 2) out vec4 NormalOut; 
layout (location = 3) out vec4 FlagsOut; 

uniform sampler2D gSampler;
uniform sampler2D gSamplerBump;
uniform vec4 vColor;

uniform float       gMatSpecularIntensity;
uniform float       gSpecularPower;
uniform float       gRetroilluminato;

uniform int useTexture;
uniform int useTextureBump;
uniform int fondiTextureColore;

void main()
{
    vec3 vNormalized = normalize(vNormal);
    vec3 vTangente = normalize(vTangent);

    vec4 vTexColor;
    vec4 vMixedColor;

    if(useTexture == 1)
    {
        vTexColor = texture2D(gSampler, texCoord);

        if(fondiTextureColore == 1)
            vMixedColor = vTexColor * vColor;
        else
            vMixedColor = vTexColor;
    }
    else
    {
        vMixedColor = vColor;
    }

    if(useTextureBump == 1)
    {
        vec3 vNormaleBump = texture(gSamplerBump, texCoord).xyz;
        vNormaleBump = 2.0 * vNormaleBump - vec3(1.0, 1.0, 1.0);

        vTangente = normalize(vTangente - dot(vTangente, vNormalized) * vNormalized);

        vec3 vBitangente = cross(vTangente, vNormalized);

        mat3 TBN = mat3(vTangente, vBitangente, vNormalized);

        vec3 vNuovaNormale = TBN * vNormaleBump;
        vNuovaNormale = normalize(vNuovaNormale);

        vNormalized = vNuovaNormale;
    }

    WorldPosOut = vec4(vWorldPos, 1.0);
    DiffuseOut = vMixedColor;
    NormalOut = vec4(vNormalized, 1.0);

    float v1 = 0.0;
    float v2 = gMatSpecularIntensity;
    float v3 = gSpecularPower;
    float v4 = 1.0;

    if(gRetroilluminato == 1)
        v1 = 1.0;

    FlagsOut = vec4(v1, v2, v3, v4);
}

不工作程序的顶点着色器。

#version 330

uniform struct Matrici
{
    mat4 projectionMatrix;
    mat4 modelMatrix;
    mat4 viewMatrix;
} matrici;

layout (location = 0) in vec3 inPosition;

void main()
{
    vec4 vEyeSpacePosVertex = matrici.viewMatrix * matrici.modelMatrix * vec4(inPosition, 1.0);
    gl_Position = matrici.projectionMatrix * vEyeSpacePosVertex;
}

非工作程序的片段着色器。

#version 330

uniform struct MDLight
{
    vec3 vColor;
    vec3 vPosition;
    vec3 vDirection;  

    float fAmbientIntensity;
    float fStrength;

    int bOn;

    float fConeAngle;
    float fConeCosine;

    float fConstantAtt;
    float fLinearAtt;
    float fExpAtt;

    float fAltezza;
    float fLarghezza;

    vec3 vUp;
    vec3 vRight;
} gLuce;

uniform float gSpecularIntensity;
uniform float gSpecularPower;

uniform sampler2D gPositionMap;
uniform sampler2D gColorMap;
uniform sampler2D gNormalMap;
uniform vec3 gCameraPos;

uniform vec2 gScreenSize;
uniform int gLightType;

uniform int gUsaLuci;

vec3 projectOnPlane( vec3 point, vec3 planeCenter, vec3 planeNorm )
{
    return point - dot( point - planeCenter, planeNorm ) * planeNorm;
}

vec3 linePlaneIntersect( vec3 lp, vec3 lv, vec3 pc, vec3 pn ) 
{
    return lp + lv * ( dot( pn, pc - lp ) / dot( pn, lv ) );
}

bool isDavanti(vec3 p1, vec3 p2, vec3 n2)
{
    vec3 p1p2 = normalize(p1 - p2);
    float prod = dot(p1p2, n2);

    if(prod >= 0.0)
        return true;
    else
        return false;
}

vec4 getDirectionalLightColor(const MDLight dirLight, vec3 vNormale, int retroilluminato)
{
    float fDiffuseIntensity = max(0.0, dot(vNormale, -dirLight.vDirection));
    return vec4(dirLight.vColor * (dirLight.fAmbientIntensity + fDiffuseIntensity) * dirLight.fStrength, 1.0);
}

vec4 getPointLightColor(const MDLight ptLight, vec3 vWorldPos, vec3 vNormale, int retroilluminato)
{
    if(ptLight.bOn == 0)
        return vec4(0.0, 0.0, 0.0, 0.0);

    vec3 vPosToLight = vWorldPos - ptLight.vPosition;
    float fDist = length(vPosToLight);
    vPosToLight = normalize(vPosToLight);

    float fDiffuse;

    if(retroilluminato == 1 && isDavanti(vWorldPos, ptLight.vPosition, vPosToLight))
        fDiffuse = abs(dot(vNormale, -vPosToLight));
    else
        fDiffuse = max(0.0, dot(vNormale, -vPosToLight));

    float fAttTotal = (1 + fDist * 0.0001 + 0.0000001 * fDist * fDist);

    return vec4(ptLight.vColor, 1.0)*(ptLight.fAmbientIntensity + fDiffuse) / fAttTotal;
}   

vec4 GetSpotLightColor(const MDLight spotLight, vec3 vWorldPos, vec3 vNormale, int retroilluminato)
{
    if(spotLight.bOn == 0)
        return vec4(0.0, 0.0, 0.0, 0.0);

    vec3 vDir = vWorldPos-spotLight.vPosition;
    vDir = normalize(vDir);

    if(dot(vNormale, -vDir) <= 0.00 && (retroilluminato == 0))
        return vec4(0.0, 0.0, 0.0, 0.0);

    float fDistance = distance(vWorldPos, spotLight.vPosition);

    float fCosine = dot(spotLight.vDirection, vDir);

    float fDif = 1.0-spotLight.fConeCosine;

    float fFactor = clamp((fCosine-spotLight.fConeCosine)/fDif, 0.0, 1.0);

    float fAttTotal = (1 + fDistance * 0.0001 + 0.000001 * fDistance * fDistance);

    if(fCosine > spotLight.fConeCosine)
        return vec4(spotLight.vColor, 1.0)*(fFactor * spotLight.fAmbientIntensity) / fAttTotal;

    return vec4(0.0, 0.0, 0.0, 0.0);
}

vec4 GetRectLightColor(const MDLight luce, vec3 vPosVert, vec3 vNormale, int retroilluminato)
{
    if(luce.bOn == 0)
        return vec4(0.0, 0.0, 0.0, 0.0);

    vec3 direzioneLuce = normalize(luce.vDirection);
    vec3 posizioneLuce = luce.vPosition;
    vec3 normaleVertice = normalize(vNormale);

    float w = luce.fLarghezza;
    float h = luce.fAltezza;

    vec3 proj = projectOnPlane(vPosVert, posizioneLuce, direzioneLuce);
    vec3 dir = proj - posizioneLuce;

    vec2 diagonal = vec2(dot( dir, luce.vRight), dot( dir, luce.vUp));
    vec2 nearest2D = vec2(clamp(diagonal.x, -w, w), clamp(diagonal.y, -h, h));

    vec3 nearestPointInside = posizioneLuce + (luce.vRight * nearest2D.x + luce.vUp * nearest2D.y);

    vec3 lightDir = normalize(nearestPointInside - vPosVert);

    float prodDirLmLD = dot(direzioneLuce, -lightDir);
    float prodNVLD = dot(normaleVertice, lightDir);

    float NdotL = 0.0;
    float NdotL2 = 0.0;

    if(retroilluminato == 1)
    {
        NdotL = abs(prodDirLmLD);
        NdotL2 = abs(prodNVLD);
    }
    else
    {
        NdotL = max(prodDirLmLD, 0.0);
        NdotL2 = max(prodNVLD, 0.0);
    }

    float prodottoDot = NdotL2 * NdotL;

    if ( prodottoDot > 0.0 )
    {
        vec3 diffuse = vec3(sqrt(prodottoDot));
        float dist = distance(vPosVert, nearestPointInside);

        float attenuation = (1 + dist * 0.0001 + 0.000001 * dist * dist);

        vec3 light = luce.fAmbientIntensity * luce.vColor;

        return vec4(light * diffuse, 1.0) / attenuation;
    }
    else
    {
        return vec4(0.0, 0.0, 0.0, 0.0);
    }
}

vec4 GetSpecularColor(vec3 vPosVertice, vec3 vPosCamera, vec3 vNormaleVertice, const MDLight luce)
{
    vec4 vResult = vec4(0.0, 0.0, 0.0, 0.0);

    vec3 direzioneLuce = luce.vDirection;
    vec3 direzioneLuceVertice = vPosVertice - luce.vPosition;

    if(gLightType == 1)
        direzioneLuce = normalize(vPosVertice - luce.vPosition);

    if(dot(-direzioneLuce, vNormaleVertice) <= 0.0 || dot(direzioneLuce, direzioneLuceVertice) <= 0.0)
        return vResult;

    vec3 vReflectedVector = normalize(reflect(direzioneLuce, vNormaleVertice));
    vec3 vVertexToEyeVector = normalize(vPosCamera - vPosVertice);
    float fSpecularFactor = dot(vVertexToEyeVector, vReflectedVector);

    fSpecularFactor = pow(fSpecularFactor, gSpecularPower);

    if (fSpecularFactor > 0)
        vResult = vec4(luce.vColor, 1.0) * gSpecularIntensity * fSpecularFactor * luce.fAmbientIntensity;

    return vResult; 
}

vec4 GetMDLightColor(const MDLight ptLight, vec3 vWorldPos, vec3 vNormale, int retroilluminato)
{
    if(gLightType == 0)
        return getDirectionalLightColor(ptLight, vNormale, retroilluminato);
    else if(gLightType == 1)
        return getPointLightColor(ptLight, vWorldPos, vNormale, retroilluminato);
    else if(gLightType == 2)
        return GetSpotLightColor(ptLight, vWorldPos, vNormale, retroilluminato);
    else if(gLightType == 3)
        return GetRectLightColor(ptLight, vWorldPos, vNormale, retroilluminato);
}

vec2 CalcTexCoord()
{
    return gl_FragCoord.xy / gScreenSize;
}

out vec4 FragColor; 

void main()
{
    vec2 TexCoord = CalcTexCoord();
    vec4 Color = texture(gColorMap, TexCoord);

    if(gUsaLuci == 1)
    {
        vec3 WorldPos = texture(gPositionMap, TexCoord).xyz;
        vec3 Normal = texture(gNormalMap, TexCoord).xyz;
        Normal = normalize(Normal);

            int retroilluminato = 0;

        vec4 coloreLuce = GetMDLightColor(gLuce, WorldPos, Normal, retroilluminato);
        vec4 coloreRiflesso = GetSpecularColor(WorldPos, gCameraPos, Normal, gLuce);
    }
    else
    {
        FragColor = Color;
    }
}

2 个答案:

答案 0 :(得分:1)

GL_ACTIVE_UNIFORMS被映射为其名称指示活动的制服,即实际上未被着色器编译器/链接器优化掉的制服。如果程序未使用制服,或以不影响最终渲染的方式使用制服,则会发生这种情况。 需要使用着色器代码来查看是否使用了无法获得索引的制服,但我认为它们不是。

答案 1 :(得分:0)

我在@ rems4e提示后解决了我的问题。

事实上,我认为我在理论上使用了所有制服,但在实践中我并非如此。在我的所有函数中,我传递了MDLight作为参数,实际上是gLuce,我试图得到制服的制服。似乎将gLuce作为其他函数的参数传递,OpenGL认为我实际上并没有使用gLuce,而是从我的活动统一列表中删除它。

所以基本上我只是在任何地方使用gLuce代替我传递给函数的参数,它现在正在工作。

对于我无法获得的所有其他制服也一样。