我在链接程序时遇到此错误。我不知道这意味着什么。它无法链接我的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;
}