我使用 Android Open GL ES2.0 Java API 编写了一个 3D 渲染程序。它在我运行 Android 3.1 的 Xoom 上运行良好。
我正在尝试在 Android 版本分别为 4.0.3 和 4.2 的 HTC Evo 3D 和三星 Galaxy S4 上运行它。没有显示渲染。GLSurface View 上的黑色窗口。Logcat 显示错误消息“无法编译着色器 35633(35632):”和“E/Adreno200-ES20(15586): <__load_uniform_int:258>: GL_INVALID_OPERATION”
从 3.1 到 4.0 的哪些变化导致着色器无法编译?
该程序显示月球绕地球运行。它实现了由类似于太阳的光引起的动态阴影。它还实现了由地球海洋表面上的光引起的镜面反射光。
地球顶点着色器:
attribute vec4 aPosition;
attribute vec3 aNormal;
attribute vec2 aTextureCoord;
varying mediump vec2 vTextureCoord;
varying lowp vec4 colorVarying1;
varying lowp vec4 colorVarying2;
varying vec4 vPosition;
varying vec3 nPos;
varying vec3 vNormal;
uniform vec3 uLight1Position;
uniform vec4 uLight1Color;
uniform vec3 uLight2Position;
uniform vec4 uLight2Color;
uniform mat4 uMVPMatrix;
uniform vec4 uAmbientLight;
void main() {
vTextureCoord.x = aTextureCoord.x;
vTextureCoord.y = aTextureCoord.y;
vNormal = normalize(aNormal);
vPosition = aPosition;
nPos = aPosition.xyz / aPosition.w;
float nDotVP1 = max(0.0, dot(vNormal, normalize(uLight1Position - nPos)));
float nDotVP2 = max(0.0, dot(vNormal, normalize(uLight2Position - nPos)));
vec4 diffuse1 = uLight1Color * nDotVP1;
colorVarying1 = diffuse1;
colorVarying2 = uLight2Color * nDotVP2;
gl_Position = uMVPMatrix * aPosition;
};
以下是地球片段着色器。
precision highp float;
const vec4 bitShifts = vec4(1.0 / (256.0 * 256.0 * 256.0),
1.0 / (256.0 * 256.0),
1.0 / 256.0,
1.0);
varying lowp vec4 colorVarying1;
varying lowp vec4 colorVarying2;
varying mediump vec2 vTextureCoord;
varying vec4 vPosition;
varying vec3 vNormal;
varying vec3 nPos;
uniform sampler2D sTexture;
uniform sampler2D sCloudTexture;
uniform sampler2D sDepthMapLight1;
uniform sampler2D sDepthMapLight2;
uniform float uHeightOfLight1Frustum;
uniform float uHeightOfLight2Frustum;
uniform vec3 uLight1Position;
uniform vec4 uLight1Color;
uniform vec3 uLight2Position;
uniform vec4 uLight2Color;
uniform mat4 uLight1MVPMatrix;
uniform mat4 uLight2MVPMatrix;
uniform vec4 uAmbientLight;
uniform vec3 uEyePosition;
uniform vec4 uCenterOfSphere;
float unpack(vec4 rgba){
return dot(rgba, bitShifts);
};
void main() {
vec4 surfaceColor;
vec4 cloudColor;
vec3 incoming1 = nPos - uLight1Position;
vec3 reflected1 = normalize(reflect(incoming1, vNormal));
vec3 incoming2 = nPos - uLight2Position;
vec3 reflected2 = normalize(reflect(incoming2, vNormal));
vec3 posToEye = normalize(uEyePosition - nPos);
float shininess = 60.0;
vec4 specular1 = uLight1Color * 5.0 * pow(max(0.0, dot(reflected1,posToEye)), shininess);
vec4 specular2 = uLight2Color * 5.0 * pow(max(0.0, dot(reflected2,posToEye)), shininess);
surfaceColor=texture2D(sTexture, vTextureCoord);
if(surfaceColor.x > surfaceColor.z || surfaceColor.y > surfaceColor.z)
specular1 = vec4(0.0, 0.0, 0.0, 0.0);
cloudColor=texture2D(sCloudTexture, vTextureCoord);
vec4 depth1Un = uLight1MVPMatrix * vPosition;
vec3 depth1 = depth1Un.xyz / depth1Un.w;
vec4 depth2Un = uLight2MVPMatrix * vPosition;
vec3 depth2 = depth2Un.xyz / depth2Un.w;
depth1.z = length(vPosition.xyz - uLight1Position) / uHeightOfLight1Frustum;
depth2.z = length(vPosition.xyz - uLight2Position) / uHeightOfLight2Frustum;
vec2 coord1 = vec2((depth1.x+1.0)/2.0, (depth1.y+1.0)/2.0);
vec2 coord2 = vec2((depth2.x+1.0)/2.0, (depth2.y+1.0)/2.0);
vec4 moveToCenter = uCenterOfSphere * 0.01 + vPosition * 0.99;
vec4 depthShifted1Un = uLight1MVPMatrix * moveToCenter;
vec3 depthShifted1 = depthShifted1Un.xyz / depthShifted1Un.w;
vec4 depthShifted2Un = uLight2MVPMatrix * moveToCenter;
vec3 depthShifted2 = depthShifted2Un.xyz / depthShifted2Un.w;
vec2 coordShifted1 = vec2((depthShifted1.x+1.0)/2.0, (depthShifted1.y+1.0)/2.0);
vec2 coordShifted2 = vec2((depthShifted2.x+1.0)/2.0, (depthShifted2.y+1.0)/2.0);
float shadow1 = 1.0;
float shadowDepth1 = unpack(texture2D(sDepthMapLight1, coord1));
float shadowDepthShifted1 = unpack(texture2D(sDepthMapLight1, coordShifted1));
if ( depth1.z >= shadowDepthShifted1 * 1.02 ){
shadow1 = 0.0;
}
float shadow2 = 1.0;
float shadowDepth2 = unpack(texture2D(sDepthMapLight2, coord2));
float shadowDepthShifted2 = unpack(texture2D(sDepthMapLight2, coordShifted2));
if ( depth2.z >= shadowDepthShifted2 * 1.02 ){
shadow2 = 0.0;
}
vec4 totalLight4 = (colorVarying1 + specular1) * shadow1 + uAmbientLight;
if(cloudColor[0]>0.3) {
cloudColor[3]=0.5;
gl_FragColor=(cloudColor*1.3 + surfaceColor*.4) * totalLight4;
} else {
gl_FragColor = surfaceColor * totalLight4;
}
};