纯虚函数叫!使用GLES20.glLinkProgram时

时间:2015-03-29 17:37:47

标签: java android opengl-es glsl opengl-es-2.0

我在链接程序时遇到此错误。我不知道这意味着什么。它无法链接我的adreno moto g,但在genymotion上模拟的nexus 6上工作正常。

您认为可能出错?两个着色器编译都很好。

这是我得到的确切错误:

03-29 19:16:22.203  17087-17087/com.manu.juegos.half_hero E/libc++abi﹕ Pure virtual function called!
03-29 19:16:22.203  17087-17087/com.manu.juegos.half_hero A/libc﹕ Fatal signal 6 (SIGABRT), code -6 in tid 17087 (uegos.half_hero)

这是调用链接例程的函数:

public static int createProgram(String vertexSource, String fragmentSource) {
    int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
    if (vertexShader == 0) {
        return 0;
    }

    int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
    if (pixelShader == 0) {
        return 0;
    }

    int program = GLES20.glCreateProgram();
    if (program != 0) {
        GLES20.glAttachShader(program, vertexShader);
        GlProgram.checkGLError("glAttachShader");
        GLES20.glAttachShader(program, pixelShader);
        GlProgram.checkGLError("glAttachShader");
        GLES20.glLinkProgram(program);
        int[] linkStatus = new int[1];
        GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
        if (linkStatus[0] != GLES20.GL_TRUE) {
            Log.e(TAG, "Could not link program: ");
            Log.e(TAG, GLES20.glGetProgramInfoLog(program));
            GLES20.glDeleteProgram(program);
            program = 0;
        }
    }

    GlProgram.checkGLError(" - post ShaderManager.createProgram - ");

    return program;
}

glLinkProgram调用后程序流程中断,我甚至无法验证链接过程的结果

这是我的顶点着色器代码:

#define numLights x // x is replaced by the number of lights in compile time
#pragma glsl

attribute vec3 position;
attribute vec3 normal;
attribute vec2 texCoord;

// matrices we'll need
uniform mat4 inversedTrasposedModelViewMatrix; 
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;

// other uniforms, constant or data we are going to use

struct LightSourceParameters {
    mediump vec3 ambient; 
    mediump vec3 lightColor;
    mediump vec4 position;  
    mediump float spotExponent; 
    mediump float spotCutoff; // (range: [0.0,90.0], 180.0)
    mediump vec3 spotDirection;
    mediump float constantAttenuation; 
    mediump float linearAttenuation; 
    mediump float quadraticAttenuation; 
};
uniform LightSourceParameters LightSource[numLights];

// out parameters to fragment shader: varyings      
varying vec3 outNormal;
varying vec2 outTextCoord;
varying vec3 outViewVector;
varying vec3 outLightVector[numLights];

void calculateLightVectors(in vec4 in_position);

void main(){

    // Calculate view-space position coordinate
    vec4 P = modelViewMatrix * vec4(position,1.0);

    // Calculate the normal in view-space
    outNormal = vec3(inversedTrasposedModelViewMatrix * vec4(normal ,0.0));

    // Calculate the view vector in view-space space coordinate
    outViewVector = -P.xyz;

    // Assign the texture coordinate
    outTextCoord = texCoord;

    // Calculate clip-space position of each vertex

    gl_Position = projectionMatrix * P;
    //gl_Position = P;
    // gl_Position = vec4(position,1.0);
    calculateLightVectors(P);
    gl_PointSize = 50.0f;
    //gl_Position = projectionMatrix * modelViewMatrix * vec4(1.0);
} 

void calculateLightVectors(vec4 P){
    // Calculate light vector for all light source
    for (int indexLightVector = 0; indexLightVector < numLights; indexLightVector++){
        /* Si no es ambiental: la unica luz que no lleva asociada vector */
        if ((length(LightSource[indexLightVector].ambient) == 0.0) /* no ambiental */
            && (LightSource[indexLightVector].position.w != 0.0)){ /* no directional */

            /* La luz es o point o spotLight */
            vec4 lightPosition = LightSource[indexLightVector].position;
            outLightVector[indexLightVector] = (vec3(modelViewMatrix * lightPosition) - P.xyz);

        }
        else if (length(LightSource[indexLightVector].ambient) == 0.0) { /* no ambiental */
            /* La luz es directional: position es un vector,
             * lo transformamos con inversedTransposedModelViewMatrix
             * y lo negamos para que vaya desde el punto a la luz y no al rev�s
             */
            outLightVector[indexLightVector] = - vec3(inversedTrasposedModelViewMatrix*LightSource[indexLightVector].position);

        }

    }
}

这是我的片段着色器代码:

#define numLights x
#pragma glsl

precision mediump float;

struct LightSourceParameters {
    vec3 ambient;
    vec3 lightColor;
    vec4 position;
    float spotExponent;
    float spotCutoff; // (range: [0.0,90.0], 180.0)
    vec3 spotDirection;
    float constantAttenuation;
    float linearAttenuation;
    float quadraticAttenuation;
};
uniform LightSourceParameters LightSource[numLights];

struct MaterialParameters {
    vec4 emission;
    vec4 ambient;
    vec4 diffuse;
    vec4 specular;
    float shininess;
    bool hasDiffuseTexture;
    bool hasSpecularTexture;
    bool hasEmissionTexture;
    bool hasAmbientTexture;
    bool hasNormalTexture;

    sampler2D emissionTexture;

    sampler2D diffuseTexture;
    sampler2D specularTexture;

    sampler2D ambientTexture;
    sampler2D normalTexture;
};
uniform MaterialParameters Material;

varying vec2 outTextCoord;
varying vec3 outNormal;
varying vec3 outViewVector;
varying vec3 outLightVector[numLights];


/* Declaramos cabecera de funcion, necesaria para que GLSL no diga que la funcion no existe, al definirse despues de main */

vec4 computeLight(in LightSourceParameters lightSource, in vec3 normal, in vec3 lightVector, in vec3 halfVector);
vec4 computeEmissionLight();


void main(){

    // Normalize the incoming vectors
    highp vec3 normal = normalize(outNormal);
    highp vec3 viewVector = normalize(outViewVector);

    // BACKFACE CULLING:
    //if (length(normal) == 0.0) discard;


    float NdotVV = dot(normal,viewVector);


    //if (NdotVV <= 0.0) discard;


    // normalize lightvector, compute half vectors and lights
    highp vec4 totalColorLighting = vec4(0.0);


    for (int indexComputeLights = 0; indexComputeLights <  numLights; indexComputeLights++){

        LightSourceParameters light = LightSource[indexComputeLights];

        highp vec3 currentLightVector = vec3(0.0);
        highp vec3 currentHalfVector = vec3(0.0);


        if (length(light.ambient) == 0.0 ){ /* no es ambiental, que no tienen vector ni half vector */

            currentLightVector = outLightVector[indexComputeLights]; // normalizamos posteriormente, para poder obtener la distancia a la luz del m�dulo de este vector
            currentHalfVector = normalize(outLightVector[indexComputeLights] + outViewVector);
        }
        else {
            // nothing
        }



    /* Si la luz es ambiental, halfVector y lightVector son
     * indefinidos para esa luz, pero da igual porque no son
     * utilizados en el algoritmo que calcula las luces
     */


        totalColorLighting = totalColorLighting + computeLight(light, normal, currentLightVector, currentHalfVector);
        totalColorLighting = clamp(totalColorLighting,vec4(0.0),vec4(1.0));

    }


    totalColorLighting = totalColorLighting + computeEmissionLight();
    totalColorLighting = clamp(totalColorLighting, 0.0, 1.0);

    /* Devolvemos el color de fragmento calculado para almacenarlo en el framebuffer */
 gl_FragColor = totalColorLighting;

}

vec4 computeEmissionLight(){

    vec4 totalEmissionColorLighting = vec4(0.0);
    if ((length(vec3(Material.emission)) != 0.0) || (Material.hasEmissionTexture)) {
        /* El material tiene un termino emisivo, es decir, emite luz. Lo andimos al total de color calculado */
        if (!Material.hasEmissionTexture) {
            totalEmissionColorLighting = Material.emission;

        }
        else {
            totalEmissionColorLighting = texture2D(Material.emissionTexture, outTextCoord);
            totalEmissionColorLighting.rgb *= totalEmissionColorLighting.a;

        }

    }

    return totalEmissionColorLighting;
}

vec4 computeLight(in LightSourceParameters lightSource,
                in vec3 normal, in vec3 lightVector, in vec3 halfVector){

    vec3 normalizedLightVector = normalize(lightVector);

    float attenuation = 1.0; // no attenuation
    highp vec4 totalLightingColor = vec4(0.0); // no color

    if (length(lightSource.ambient) > 0.0) { // es luz ambiente
        vec4 ambientalTerm = vec4(0.0,0.0,0.0,1.0);
        if (!Material.hasAmbientTexture){
            ambientalTerm =  Material.ambient;

        }
        else {
            ambientalTerm = texture2D(Material.ambientTexture, outTextCoord);
            ambientalTerm.rgb *= ambientalTerm.a;
        }
        totalLightingColor = vec4(lightSource.ambient, 1.0) * ambientalTerm;
//totalLightingColor = vec4(0.0);

    }
    else { // Is not ambiental light


        // BACKLIGHT CULLING:

        float NdotLV = dot(normal, normalizedLightVector);
        if (NdotLV < 0.0 ) { // light source in the wrong side
            return vec4(0.0,0.0,0.0,1.0);
        }



        if (lightSource.position.w == 0.0) { // es un vector, por lo tanto es una luz direccional
            attenuation = 1.0; // no attenuation

        }
        else { // Is a point light or a spot light (LIGHTVECTOR EXPRESA UN VECTOR DESDE GL_FRAGCOORD HASTA LA LUZ, NO LA DIRECCION DE LA LUZ A SECAS): SACAMOS DISTANCIAS
            float distanceToLight = length(lightVector);

            attenuation = lightSource.constantAttenuation / ((1.0+lightSource.linearAttenuation*distanceToLight)*(1.0+lightSource.quadraticAttenuation*distanceToLight*distanceToLight));


            if (lightSource.spotCutoff <= 90.0){ /* Is a spot light */


                vec3 spotDirection = normalize(lightSource.spotDirection);
                float clampedCosine = max(0.0, dot(-normalizedLightVector, spotDirection));

                if (clampedCosine < cos(radians(lightSource.spotCutoff))){ /* outside the spotlight cone */
                    attenuation = 0.0; /* full attenuation */
                }
                else { /* inside the spotlight cone */
                    attenuation = attenuation * pow(clampedCosine, lightSource.spotExponent);
                }
            }
        }

        // Calculo de los terminos de color: diffuso y especular
        vec4 diffuseReflection = vec4(0.0);
        vec4 diffuseMaterialTerm = vec4(0.0, 0.0, 0.0, 0.0); /* El canal difuso será NO opaco y negro hasta que se sobreescriban sus datos */
        if (!Material.hasDiffuseTexture) { /* El canal difuso no tiene textura */
            diffuseMaterialTerm =  Material.diffuse;
        }
        else {
            diffuseMaterialTerm = texture2D(Material.diffuseTexture, outTextCoord);
        }



        diffuseReflection = attenuation * vec4(lightSource.lightColor, 1.0) * diffuseMaterialTerm * max(0.0, NdotLV);
        if (Material.hasDiffuseTexture){ // premultiplicado por alpha en bitmapfactory de android
            diffuseReflection.rgb *= diffuseMaterialTerm.a;
        }
        vec4 specularReflection = vec4(0.0);


        // LIGHT SOURCE IS ALWAYS IN THE RIGHT SIDE DUE TO BACKLIGHT CULLING

            highp float NdotHV = max(dot(normal, halfVector), 0.0); /* Normal-dot-halfvector */

            vec4 specularMaterialTerm = vec4 (0.0, 0.0, 0.0, 0.0); /* El canal especular será NO opaco y negro hasta que se sobreescriban sus datos */
            if (!Material.hasSpecularTexture){
                specularMaterialTerm = Material.specular;
            }
            else {
                specularMaterialTerm = texture2D(Material.specularTexture, outTextCoord);
            }

            specularReflection = attenuation * pow(NdotHV, (Material.shininess)) * vec4(lightSource.lightColor, 1.0) * specularMaterialTerm;
            if (Material.hasSpecularTexture){ // premultiplicado por alpha en bitmapfactory de android
                specularReflection.rgb *= specularMaterialTerm.a;
            }

        totalLightingColor = diffuseReflection + specularReflection;

    }
    return totalLightingColor;
    //return clamp(totalLightingColor,vec4(0.0),vec4(1.0));
}

我不知道我做了什么。我刚刚删除了computeEmisionLight中的一些coments(在片段着色器中),现在链接正常。请告诉我你是否知道有什么区别。这是新的computeEmisionLight代码:

vec4 computeEmissionLight(){

    vec4 totalEmissionColorLighting = vec4(0.0);
    if ((length(vec3(Material.emission)) != 0.0) || (Material.hasEmissionTexture)) {
        /* El material tiene un termino emisivo, es decir, emite luz. Lo andimos al total de color calculado */
        if (!Material.hasEmissionTexture) {
            totalEmissionColorLighting = Material.emission;
        }
        else {
            totalEmissionColorLighting = texture2D(Material.emissionTexture, outTextCoord);
            totalEmissionColorLighting.rgb *= totalEmissionColorLighting.a;

            // discard;
            // texture2D(material.diffuseTexture, outTextCoord);
        }
    }
    return totalEmissionColorLighting;
}

0 个答案:

没有答案