Android 索引大于GL#u MAX_VERTEX_ATTRIBS(而实际上它';低于硬件限制)
我在手机上运行应用程序时遇到问题,而它在模拟器上运行正常。我在Android上使用OPENGLES 2.0,问题似乎出在OpenGL上。每次画框时,基本上都会重复以下错误:Android 索引大于GL#u MAX_VERTEX_ATTRIBS(而实际上它';低于硬件限制),android,opengl-es,Android,Opengl Es,我在手机上运行应用程序时遇到问题,而它在模拟器上运行正常。我在Android上使用OPENGLES 2.0,问题似乎出在OpenGL上。每次画框时,基本上都会重复以下错误: gles_state_set_error_internal:63: GLES error info:<program> could not be made part of current state. <program> is not linked GLES a_norm-1 gles_state_s
gles_state_set_error_internal:63: GLES error info:<program> could not be made part of current state. <program> is not linked GLES a_norm-1
gles_state_set_error_internal:62: GLES ctx: 0x7fa2596008, error code:0x502
gles_state_set_error_internal:63: GLES error info:<index> is greater than or equal to GL_MAX_VERTEX_ATTRIBS
对于模拟器,这是29,而对于我的真实手机,这是16。Ok 16较少,但正如您在我的着色器中所看到的,我只使用了3个属性,3问题在于片段着色器。不知怎的,手机中的硬件无法处理除以8的问题,它必须是8.0,这样它才能知道它是一个浮点数
public static final String fragmentLightTexture = "precision mediump float;"+
"uniform vec3 u_LightPos;"+ // The position of the light in eye space.
"uniform sampler2D s_Texture;"+ // The input texture.
"varying vec3 v_Position;"+ // Interpolated position for this fragment
"varying vec3 v_Normal;"+ // Interpolated normal for this fragment
"varying vec2 v_TexCoordinate;"+// Interpolated texture coordinate per fragment.\n" +
"void main()"+
"{"+
"float distance = length(u_LightPos - v_Position);"+ // Will be used for attenuation
"vec3 lightVector = normalize(u_LightPos - v_Position);" +// Get a lighting direction vector from the light to the vertex
"float diffuse = max(dot(v_Normal, lightVector), 0.0);" + // dot product for the illumination angle.
"diffuse = diffuse * (1.5 / (1.0 + (distance/8.0)));\n" + // Attenuation.
"diffuse = diffuse + 0.2;" + // ambient light
"gl_FragColor = (diffuse * texture2D(s_Texture, v_TexCoordinate));" +// Multiply the color by the diffuse illumination level and texture value to get final output color.
"}";
我不得不说GL_MAX_VERTEX_ATTRIBS的错误消息一点帮助都没有,真的让我无法朝错误的方向进行搜索。为什么不从第一条错误消息开始,而不是从第二条错误消息开始,后者说程序链接不正确?总是先调试第一个错误。。。后来的错误通常是早期错误传播的结果。回顾这一点,我明白这更能说明问题。它在仿真器上运行的事实让我认为程序是正确的,并且链接由于MAX_ATTRIBS而失败
public static final String vertexLightTexture = "uniform mat4 u_MVPMatrix;"+ // A constant representing the combined model/view/projection matrix.
"uniform mat4 u_MVMatrix;"+ // A constant representing the combined model/view matrix.
"attribute vec4 a_Position;"+ // Per-vertex position information we will pass in.
"attribute vec3 a_Normal;"+ // Per-vertex normal information we will pass in.
"attribute vec2 a_TexCoordinate;"+ // Per-vertex texture coordinate information we will pass in.
"varying vec3 v_Position;"+ // This will be passed into the fragment shader.
"varying vec3 v_Normal;"+ // This will be passed into the fragment shader.
"varying vec2 v_TexCoordinate;"+ // This will be passed into the fragment shader.
"void main()"+
"{"+
"v_Position = vec3(u_MVMatrix * a_Position);"+ // Transform the vertex into eye space.
"v_TexCoordinate = a_TexCoordinate;"+ // Pass through the texture coordinate.
"v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));"+ // Transform the normal's orientation into eye space.
"gl_Position = u_MVPMatrix * a_Position;"+ // regular position
"}";
public static final String fragmentLightTexture = "precision mediump float;"+
"uniform vec3 u_LightPos;"+ // The position of the light in eye space.
"uniform sampler2D s_Texture;"+ // The input texture.
"varying vec3 v_Position;"+ // Interpolated position for this fragment
"varying vec3 v_Normal;"+ // Interpolated normal for this fragment
"varying vec2 v_TexCoordinate;"+// Interpolated texture coordinate per fragment.\n" +
"void main()"+
"{"+
"float distance = length(u_LightPos - v_Position);"+ // Will be used for attenuation
"vec3 lightVector = normalize(u_LightPos - v_Position);" +// Get a lighting direction vector from the light to the vertex
"float diffuse = max(dot(v_Normal, lightVector), 0.0);" + // dot product for the illumination angle.
"diffuse = diffuse * (1.5 / (1.0 + (distance/8)));\n" + // Attenuation.
"diffuse = diffuse + 0.2;" + // ambient light
"gl_FragColor = (diffuse * texture2D(s_Texture, v_TexCoordinate));" +// Multiply the color by the diffuse illumination level and texture value to get final output color.
"}";
int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER, Shaders.vertexLightTexture);
int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,Shaders.fragmentLightTexture);
// create empty OpenGL ES Program
mProgram = GLES20.glCreateProgram();
// add the vertex shader to program
GLES20.glAttachShader(mProgram, vertexShader);
// add the fragment shader to program
GLES20.glAttachShader(mProgram, fragmentShader);
// creates OpenGL ES program executables
GLES20.glLinkProgram(mProgram);
public void draw(float[] mvpMatrix, float[] mvMatrix, float[] lightPosition){
// group all wall elements at once
// Add program to OpenGL ES environment
GLES20.glUseProgram(mProgram);
// Get handle to shape's transformation matrix]
int mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "u_MVPMatrix");
System.err.println("GLES MVPMatrix" + mMVPMatrixHandle);
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
// Get handle to shape's transformation matrix]
int mMVMatrixHandle = GLES20.glGetUniformLocation(mProgram, "u_MVMatrix");
System.err.println("GLES MVMatrix" + mMVMatrixHandle);
// Apply the view transformation
GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mvMatrix, 0);
// Get handle to textures locations
int mSamplerLoc = GLES20.glGetUniformLocation(mProgram, "s_Texture");
System.err.println("GLES s_tex" + mSamplerLoc);
// Set the active texture unit to texture unit 0.
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
// Bind the texture to this unit.
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
// Set the sampler texture unit to 0, where we have saved the texture.
GLES20.glUniform1i(mSamplerLoc, 0);
// get handle to vertex shader's vPosition member
int mPositionHandle = GLES20.glGetAttribLocation(mProgram, "a_Position");
System.err.println("GLES a_pos" + mPositionHandle);
// Use the buffered data from GPU memory
int vertexStride = COORDINATES_PER_VERTEX * 4;
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, positionBufferIndex);
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, vertexStride, 0);
// get handle to vertex shader's vPosition member
int mNormalHandle = GLES20.glGetAttribLocation(mProgram, "a_Normal");
System.err.println("GLES a_norm" + mNormalHandle);
// Use the buffered data from GPU memory
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, normalBufferIndex);
GLES20.glEnableVertexAttribArray(mNormalHandle);
GLES20.glVertexAttribPointer(mNormalHandle, 3, GLES20.GL_FLOAT, false, vertexStride, 0);
// Get handle to texture coordinates location
int mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate" );
System.err.println("GLES a_tex" + mTextureCoordinateHandle);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, uvBufferIndex);
GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
GLES20.glVertexAttribPointer(mTextureCoordinateHandle, 2, GLES20.GL_FLOAT, false, 0, 0);
// Clear the currently bound buffer (so future OpenGL calls do not use this buffer).
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
// Pass in the light position in eye space.
int mLightPosHandle = GLES20.glGetUniformLocation(mProgram, "u_LightPos");
System.err.println("GLES u_light" + mLightPosHandle);
GLES20.glUniform3f(mLightPosHandle, lightPosition[0], lightPosition[1], lightPosition[2]);
// Draw the Square
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexBufferIndex);
GLES20.glDrawElements(GLES20.GL_TRIANGLES,numberOfIndices,GLES20.GL_UNSIGNED_SHORT,0);
// Clear the currently bound buffer (so future OpenGL calls do not use this buffer).
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mNormalHandle);
GLES20.glDisableVertexAttribArray(mTextureCoordinateHandle);
}
public static final String fragmentLightTexture = "precision mediump float;"+
"uniform vec3 u_LightPos;"+ // The position of the light in eye space.
"uniform sampler2D s_Texture;"+ // The input texture.
"varying vec3 v_Position;"+ // Interpolated position for this fragment
"varying vec3 v_Normal;"+ // Interpolated normal for this fragment
"varying vec2 v_TexCoordinate;"+// Interpolated texture coordinate per fragment.\n" +
"void main()"+
"{"+
"float distance = length(u_LightPos - v_Position);"+ // Will be used for attenuation
"vec3 lightVector = normalize(u_LightPos - v_Position);" +// Get a lighting direction vector from the light to the vertex
"float diffuse = max(dot(v_Normal, lightVector), 0.0);" + // dot product for the illumination angle.
"diffuse = diffuse * (1.5 / (1.0 + (distance/8.0)));\n" + // Attenuation.
"diffuse = diffuse + 0.2;" + // ambient light
"gl_FragColor = (diffuse * texture2D(s_Texture, v_TexCoordinate));" +// Multiply the color by the diffuse illumination level and texture value to get final output color.
"}";