Note that there are some explanatory texts on larger screens.

plurals
  1. POCan't see texture on device, but can see it on the emulator. OpenGL Error 0x502
    primarykey
    data
    text
    <p>I'm trying to render a 512x512 texture on a square on Android using OpenGL. My program works fine when I use the emulator, but if I use a Nexus 7 (the old one), glGetError() returns 1282. This happens after I call glUseProgram in my render loop. GLUtils.getEGLErrorString says error 1282 corresponds to error 0x502, which stands for GL_INVALID_OPERATION.</p> <p>I've tried the solutions mentioned in <a href="https://stackoverflow.com/a/2186772/2652189">this</a> answer, <a href="https://stackoverflow.com/a/11872680/2652189">this</a> answer and <a href="http://twigstechtips.blogspot.com.au/2012/07/android-opengl-textures-showing-up-on.html" rel="nofollow noreferrer">this</a> article. I've tried putting my texture in drawable-nodpi and I've also made sure my texture size is a power of two. I also tried putting my texture in res/raw and following the alternate method of loading the texture but that didn't work either.</p> <p>Could someone point me in the right direction? </p> <p>If there is anything I can do to improve my question, please let me know!</p> <p>My shaders:</p> <pre><code> private final String vertexShaderCode = // This matrix member variable provides a hook to manipulate // the coordinates of the objects that use this vertex shader "uniform mat4 uMVPMatrix;" + // Per-vertex texture coordinate info we will pass in "attribute vec2 a_TexCoordinate;" + // This will be passed into the fragment shader "varying vec2 v_TexCoordinate;" + "attribute vec4 vPosition;" + "void main() {" + // the matrix must be included as a modifier of gl_Position " gl_Position = vPosition * uMVPMatrix;" + " v_TexCoordinate = a_TexCoordinate;" + "}"; private final String fragmentShaderCode = // The input texture "uniform sampler2D u_Texture;" + // Interpolated texture coordinate per fragment "varying vec2 v_TexCoordinate;" + "precision mediump float;" + "uniform vec4 vColor;" + "void main() {" + " gl_FragColor = (vColor * texture2D(u_Texture, v_TexCoordinate));" + "}"; </code></pre> <p>My draw call:</p> <pre><code> public void draw(float[] mvpMatrix) { GLES20.glUseProgram(shaderProgramHandle); // POSITION INFO - Get a handle to the position attribute in the shader and // associate the vertices with it int vPositionHandle = GLES20.glGetAttribLocation(shaderProgramHandle, "vPosition"); GLES20.glEnableVertexAttribArray(vPositionHandle); GLES20.glVertexAttribPointer( vPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, COORDS_PER_VERTEX * BYTES_PER_COORD, vertexBuffer); // COLOR INFO - Get a handle to the color attribute in the shader and associate // the color with it int vColorHandle = GLES20.glGetUniformLocation(shaderProgramHandle, "vColor"); GLES20.glUniform4fv(vColorHandle, 1, vertexColor, 0); // TRANSFORM INFO - Get a handle to the MVP matrix uniform in the shader and // associate the MVP matrix with it int uMVPHandle = GLES20.glGetUniformLocation(shaderProgramHandle, "uMVPMatrix"); GLES20.glUniformMatrix4fv(uMVPHandle, 1, false, mvpMatrix, 0); // TEXTURE INFO int texCoordinateHandle = GLES20.glGetAttribLocation(shaderProgramHandle, "a_TexCoordinate"); GLES20.glEnableVertexAttribArray(texCoordinateHandle); GLES20.glVertexAttribPointer( texCoordinateHandle, COORDS_PER_TEX, GLES20.GL_FLOAT, false, 0, textureCoordinatesBuffer); int texUniformHandle = GLES20.glGetUniformLocation(shaderProgramHandle, "u_Texture"); // 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, textureDataHandle); // Tell the texture uniform sampler to use this texture in the shader // by binding to texture unit 0 GLES20.glUniform1i(texUniformHandle, 0); // Draw the square GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, vertices.length / 3); // Cleanup GLES20.glDisableVertexAttribArray(vPositionHandle); GLES20.glDisableVertexAttribArray(texCoordinateHandle); } </code></pre> <p>I'm loading my texture in my implementation of GLSurfaceView.Renderer's onSurfaceCreated. Here is a snippet that shows how I'm loading the texture. </p> <pre><code> int loadTexture(final Context context, final int resourceId) { final int[] textureHandle = new int[1]; GLES20.glGenTextures(1, textureHandle, 0); Utils.checkGLError("glGenTextures"); if (textureHandle[0] != 0) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inScaled = false; // No pre-scalings // Read in the resource final Bitmap bitmap = BitmapFactory.decodeResource( context.getResources(), resourceId, options); // InputStream is = context.getResources().openRawResource(resourceId); // Bitmap bitmap = null; // try { // bitmap = BitmapFactory.decodeStream(is); // } finally { // //Always clear and close // try { // is.close(); // is = null; // } catch (IOException e) { // } // } // Bind to the texture in OpenGL GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]); // Set filtering GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); // GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, // GLES20.GL_NEAREST); // GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, // GLES20.GL_NEAREST); // GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, // GLES20.GL_CLAMP_TO_EDGE); // GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, // GLES20.GL_CLAMP_TO_EDGE); // Load the bitmap into the bound texture. GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); // Recycle the bitmap, since its data has been loaded into OpenGL. bitmap.recycle(); } if (textureHandle[0] == 0) { throw new RuntimeException("Error loading texture."); } return textureHandle[0]; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. COAll OpenGL enumerated constants (e.g. error codes) are base-16, for future reference. You will have great difficulty if you try to look up the decimal representation, but if you use hexadecimal you can find the token name immediately by looking for `0x...` in any text editor in `gl.h`, it will be in the form: `#define GL_... 0x...`. I realize you are using Java, but `gl.h` is easy to find [here](http://www.khronos.org/registry/gles/#specfiles), decimal OpenGL constant values on the other hand are anything but easy to find.
      singulars
    2. CODoes this program actually run fine in the simulator? I ask because `" gl_Position = vPosition * uMVPMatrix;" +` is not valid if you use column-major matrices like you are expected to in OpenGL. You should have the matrix on the l-hand side in this statement.
      singulars
    3. COOnto the actual issue: `glUseProgram (...)` will most often generate `GL_INVALID_OPERATION` when you try to use a program that did not link properly. Look into Shader / Program info logs, they will tell you what is really going on here. See: [`glGetShaderInfoLog`](http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetShaderInfoLog.xml) and [`glGetProgramInfoLog`](http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetProgramInfoLog.xml).
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload