vertex shader doesn't run on galaxy tab10 (tegra 2)
Asked Answered
T

2

2

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
 );
Toddtoddie answered 9/7, 2012 at 15:22 Comment(3)
Have you checked the program infolog (see glGetProgramiv) for the reason it can't be linked? Have you checked the shader compile status? Which line specifically is generating the OpenGL error?Schifra
Thanks for the hint! The shader infolog reads: "error C3004: function "vec4 texture"D(sampler2D, vec2);" not supported in this profile"Toddtoddie
If the compiler says it's not supported and you get 0 sampler2D's supported on compile, then I believe the phone GPU will not support vertex sampler2D, so a solution would be to use a try/catch and revert to a per-vertex shader for phones that don't play ball.Eckhart
C
2

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).

Chronological answered 10/7, 2012 at 8:48 Comment(5)
I'm new to opengl and copied most of this code from a tutorial. What are the work around possibilites here? Or do I have to apply the z coordinates in the java code? I thankful for every opinion/suggestionToddtoddie
I am not aware of a workaround that lets you read textures in the vertex shader. How do you get the data into the texture? I guess you have to modify your code so that the input is sent to the shader per vertex (as you suggested). Maybe you can give a little more detail about what you want to do (is this some sort of height field rendering?).Chronological
I followed this Tutorial to plot a 3d graph. The z values are calculated with the function to plot and stored in an array that is then used as texture to get the z coordinate for each vortex)Toddtoddie
I think in this case you should really store the z-values for your graph in the vertex array. I don't think that there is a real (speed-wise) benefit of writing the values on the CPU and sending it to the GPU as a texture compared to updating your vertex positions. As an alternative, you could also consider evaluating your function on the GPU (in the vertex shader).Chronological
I think the basic idea in the tutorial is that one can have a vertex at a point where the z value has not been evaluated in the java code. But I don't need this very much, so I'll do as you suggested. Thank you again!Toddtoddie
P
-1

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

Profligate answered 24/1, 2013 at 13:55 Comment(2)
Can't downvote yet but the specs do NOT state that! What it says is that the texture2DLodX functions are only allowed in the vertex shader, there is nothing in there that says you have to use it!Eastnortheast
I've tried texture2DLod and it doesn't work either. I think this is a red herring too.Gulf

© 2022 - 2024 — McMap. All rights reserved.