vertex shader doesn't run on galaxy tab10 (tegra 2)
-
19-06-2021 - |
Question
I created an app that uses GLES2.0 on a HTC Desire S. It works on the HTC, but not on an Samung Galaxy tab10.1. The program cannot be linked (GLES20.glGetProgramiv(mProgram, GLES20.GL_LINK_STATUS, linOk,0) gives-1) and glGetError() gives me an error 1282 (Invalid Operation).
When I replace this line (in the shader):
graph_coord.z = (texture2D(mytexture, graph_coord.xy / 2.0 + 0.5).r);
by
graph_coord.z = 0.2;
it works also on the galaxy tab. My shader looks like this:
private final String vertexShaderCode =
"attribute vec2 coord2d;" +
"varying vec4 graph_coord;" +
"uniform mat4 texture_transform;" +
"uniform mat4 vertex_transform;" +
"uniform sampler2D mytexture;" +
"void main(void) {" +
" graph_coord = texture_transform * vec4(coord2d, 0, 1);" +
" graph_coord.z = (texture2D(mytexture, graph_coord.xy / 2.0 + 0.5).r);" +
" gl_Position = vertex_transform * vec4(coord2d, graph_coord.z, 1);" +
"}";
That's where the shaders are attached:
mProgram = GLES20.glCreateProgram(); // create empty OpenGL Program
GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
GLES20.glLinkProgram(mProgram); // create OpenGL program executables
int linOk[] = new int[1];
GLES20.glGetProgramiv(mProgram, GLES20.GL_LINK_STATUS, linOk,0);
And the texture is loaded here:
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture_id[0]);
GLES20.glTexImage2D(
GLES20.GL_TEXTURE_2D, // target
0, // level, 0 = base, no minimap,
GLES20.GL_LUMINANCE, // internalformat
size, // width
size, // height
0, // border, always 0 in OpenGL ES
GLES20.GL_LUMINANCE, // format
GLES20.GL_UNSIGNED_BYTE, // type
values
);
Solution
This seems to be a limitation of the Nvidia Tegra GPU. I was able to reproduce the error on a Tegra 3 GPU. Even though texture lookups in the vertex shader are in theory part of OpenGL ES 2.0, according to Nvidia the number of vertex shader texture units (GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS
) for Tegra is 0 (PDF: OpenGL ES 2.0 Development for the Tegra Platform).
OTHER TIPS
You have to use texture2DLod()
instead of texture2D()
to make texture lookups in vertex shader.
GLSL specs, section 8.7 Texture Lookup Functions: http://www.khronos.org/files/opengles_shading_language.pdf