title: OpenGL texture ID generated more than once
body: <p>I have texture loading routine in C that calls Java part of my game to do the job. It can load .png as well as .jpg files and create textures from them. It returns back to C the generated textureID (generated with glGenTextures). It worked perfectly until I started to use frontbuffer.</p>
  <p>As the texture for frontbuffer is empty one I am creating it directly in C. It works ok when I run the game for the first time - the texture ID generated for front buffer is different from all other texture IDs. But when I press HOME key, then jump back into game again and I reload all textures and recreate front buffer again (to recover from context loss) the texture ID generated for frontbuffer collides with one of texture IDs generated for textures - like if there were two ID lines. The screen using the framebuffer is corrupted - displaying the texture with ID that equals to the newly assigned ID of the framebuffer.</p>
  <p>This all happens only on real device (Samsung Galaxy Tablet in my case), not in emulator.</p>
  <p>The C loading routine:</p>
  <pre class="lang-cpp prettyprint-override"><code>void Texture::construct(AssetLoader* aLoader, s32 aIdx)
  {
      const c8* fileName = aLoader-&gt;getFileName();
      
      // load texture
      SBC::System::Application* app = &amp;Game::getGame().getApplication();
     
      JNIEnv *env;
      
      bool shouldDetach = false;
      JavaVM* vm = gJavaVM;
      jint rc = vm-&gt;GetEnv((void **)&amp;env, JNI_VERSION_1_6);
      if (rc != JNI_OK)
      {
          shouldDetach = true;
          vm-&gt;AttachCurrentThread(&amp;env, NULL);
      }
      jclass&amp; activityClass = gJavaActivityClass;
      
      jmethodID mid = env-&gt;GetStaticMethodID(activityClass, &quot;loadTexture&quot;, &quot;(Ljava/lang/String;I)I&quot;);
      jstring mystr = env-&gt;NewStringUTF(fileName);
      jint ret = env-&gt;CallStaticIntMethod(activityClass, mid, mystr, aIdx);
      env-&gt;DeleteLocalRef(mystr);
      
      // store information on ID, width and height of texture
      mTextureID = ret;
      
      LOGE(&quot;textureID = %i&quot;, mTextureID);
      
      mid = env-&gt;GetStaticMethodID(activityClass, &quot;getTextureWidth&quot;, &quot;()I&quot;);
      mWidth = env-&gt;CallStaticIntMethod(activityClass, mid);
      mid = env-&gt;GetStaticMethodID(activityClass, &quot;getTextureHeight&quot;, &quot;()I&quot;);
      mHeight = env-&gt;CallStaticIntMethod(activityClass, mid);
      
      if (shouldDetach)
          vm-&gt;DetachCurrentThread();
      
      LOGI(&quot;texture ID %i, width %i, height %i&quot;, mTextureID, mWidth, mHeight);
  }
  </code></pre>
  <p>Java methods</p>
  <pre class="lang-java prettyprint-override"><code>//-----------------------------------------------------
  /* fname = asset file name
   * id &gt;= 0 ... position in compound file
   * id &lt; 0 ... single file (no compound)
   */
  public static int loadTexture(String fname, int id)
  {
      // clear last texture parameters
      txtID = width = height = -1;
          
      Log.d(&quot;Helper&quot;, &quot;Loading texture from asset file &quot; + fname + &quot; with id &quot; + id);
      
      final BitmapFactory.Options options = new BitmapFactory.Options();
      options.inScaled = false;       // No pre-scaling
      AssetManager am = SBCEngine.getSBCEngine().getAssets();
      Bitmap bitmap = null;
      
      try
      {
          InputStream stream = am.open(fname);
              
          // loading from compound file?
          if (id &gt;= 0)
          {
              DataInputStream input = new DataInputStream(stream);
                  
              // skip header
              input.skip(3);
              // skip to entry offset
              input.skip(id * 4);
              // read entry beginning
              int dataStart = input.readInt();
              // read data length
              int dataLen = input.readInt() - dataStart;
              // skip to start of subfile
              // offsets are without header (3) bytes
              // we already skipped id * 4 bytes
              // we already have read 2 offset by 4 bytes = 8 in total
              input.skip(dataStart - (id * 4) - 8);
      
              // get data from correct position
              byte[] data = new byte[dataLen];
              input.read(data);
      
              bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
          }
          else    // no compound
          {
              Log.d(&quot;Helper&quot;, &quot;Loading from stream&quot;);
              bitmap = BitmapFactory.decodeStream(stream, null, options);
          }
              
              
          // test returned bitmap for success
          if (bitmap == null)
          {
              Log.e(&quot;Helper&quot;, &quot;Failed to load texture &quot; + fname + &quot; with id &quot; + id);
          }
      
          // check whether the loaded bitmap has width and height equal to power of 2
          int w = bitmap.getWidth();
          int h = bitmap.getHeight();
          if (getNearestPOT(w) != w || getNearestPOT(h) != h)
          {
              Log.w(&quot;Helper&quot;, &quot;Texture &quot; + fname + &quot; with id &quot; + id +
                          &quot; has not either width or height power of 2&quot;);
                  
              // new dimensions
              w = getNearestPOT(w);
              h = getNearestPOT(h);
      
              // get actual bitmap config
              Bitmap.Config bitmapConfig = bitmap.getConfig();
              // check for null
              if (bitmapConfig == null)
              {
                  bitmapConfig = Bitmap.Config.ARGB_8888;
                  Log.w(&quot;Helper&quot;, &quot;Unknown bitmap config. Setting to ARGB_8888&quot;);
              }
              // redraw bitmap into POT bitmap
              Bitmap newBitmap = Bitmap.createBitmap(w, h, bitmapConfig);
              Canvas canvas = new Canvas(newBitmap);
              canvas.drawBitmap(bitmap, 0.0f, 0.0f, null);
              bitmap.recycle();
              canvas = null;
              bitmap = newBitmap;
                  
              Log.w(&quot;Helper&quot;, &quot;Texture &quot; + fname + &quot; rebuilded into texture with POT&quot;);
          }
              
          // generate textureID
          int[] textures = new int[1];
          GLES20.glGenTextures(1, textures, 0);
          int textureID = textures[0];
              
          // create texture
          GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureID);
          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_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
          GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
          GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
              
          // destroy bitmap
          bitmap.recycle();
              
          txtID = textureID;
          width = w;
          height = h;
              
          Log.d(&quot;Helper&quot;, &quot;Loaded texture ID:&quot; + textureID + &quot;, width:&quot; + w + &quot;, height:&quot; + h);
          return textureID;
      }
      catch (IOException e)
      {
          Log.e(&quot;Helper&quot;, &quot;Failed to load texture &quot; + fname + &quot; with id &quot; + id);
          return 0;
      }
  }
      
      //------------------------------------------------------------------------
  public static int getTextureWidth()
  {
      return width;
  }
      
      //------------------------------------------------------------------------
  public static int getTextureHeight()
  {
      return height;
  }
      
      //------------------------------------------------------------------------
  private static int getNearestPOT(int val)
  {
      int newDim = 1;
      while(val &gt; newDim) newDim *= 2;
      return newDim;
  }
  </code></pre>
  <p>and finally the C routine to create texture for frontbuffer</p>
  <pre class="lang-cpp prettyprint-override"><code>// create empty texture
  void Texture::construct(u32 aTextureWidth, u32 aTextureHeight)
  {
      // get power of 2 dimensions
      mWidth = getNearestPOT(aTextureWidth);
      mHeight = getNearestPOT(aTextureHeight);
      
      glGenTextures(1, &amp;mTextureID);
      glBindTexture(GL_TEXTURE_2D, mTextureID);
      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, mWidth, mHeight, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, null);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      
      LOGE(&quot;textureID = %i&quot;, mTextureID);
  }
  </code></pre>
  <p>Anyone encoutered the same problem?</p>