Praveena
Praveena

Reputation: 6941

Android OpenGL: How to change bitmap attached to texture?

I have created a texture like this

public int createTexture(Bitmap bitmap){
 final int[] textureHandle = new int[1];
 GLES20.glGenTextures(1, textureHandle, 0);
 glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);       
 glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
 glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
 // Load the bitmap into the bound texture.
 GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 
 return textureHandle[0];
}

Now based on the user input I want to update my Texture with the new Bitmap. I tried recalling same function with different Bitmap but its not getting updated. Am I doing something wrong here?

EDIT

I tried as Tommy said in his answer but no use. Let me elaborate how I am using textures.

public void changeFilter(){
  //create required bitmap here
  if(mTextureDataHandle1==0) 
    mTextureDataHandle1 =loadTexture(bitmap); 
  else 
      updateTexture(mTextureDataHandle1);
}

In onDrawFrame

 glActiveTexture(GL_TEXTURE1);
 glBindTexture(GL_TEXTURE_2D, mTextureDataHandle1);
 glUniform1i(mTextureUniformHandle1, 1);

Upvotes: 4

Views: 3485

Answers (3)

Victor O
Victor O

Reputation: 21

I tried the techniques in the above responses I got horrible performance. If what you want is to update the texture live as in 60 fps there is a better way. BTW I didn't find documentation on it, I had to pull and pieces together from different sources.

(1) you have to tell OpenGL extensions to use external textures. That is when defining your texture instead of using GLES20.GL_TEXTURE0 you use GLES11Ext.GL_TEXTURE_EXTERNAL_OES

(2) you have to use the classes Surface and SurfaceTexture. (look into consumers and producers for more into. They work like a server/client but instead the architecture is called consumer/producer)

(3) You have to enable an extension on your fragment shader. You can't use sampler2D you have to use samplerExternalOES. To enable the extension you put the following line at the top of your shader code:

#extension GL_OES_EGL_image_external: require

Code snapshot

The above is a snapshot of my code, below is the fragment shader

Fragment shader

Upvotes: 2

user1712200
user1712200

Reputation: 349

You may simply be not on the OpenGL rendering thread when changing the Bitmap. When you change the Bitmap, save in a boolean that you did so, and then only in the rendering thread call texImage2D.

Upvotes: 3

Tommy
Tommy

Reputation: 100632

That method both creates a new texture and uploads a Bitmap to it. It sounds like you want to do the second thing but not the first? If so then provide the int texture name as a parameter rather than receiving it as a result, and skip straight to the glBindTexure (i.e. omit the glGenTextures, which is what creates the new texture).

E.g.

public int createTexture(Bitmap bitmap){
 final int[] textureHandle = new int[1];
 GLES20.glGenTextures(1, textureHandle, 0);
 glBindTexture(GLES20.GL_TEXTURE_2D, textureName);       
 glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
 glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
 updateTexture(textureHandle[0], bitmap);
 return textureHandle[0];
}

public void updateTexture(int textureName, Bitmap bitmap) {
 glBindTexture(GLES20.GL_TEXTURE_2D, textureName);       
 // Load the bitmap into the bound texture.
 GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 
}

So the bit where you upload a Bitmap is factored out from the bit where you create a texture and set its filtering type; to update an existing texture use the int you got earlier and call directly into updateTexture.

Upvotes: 4

Related Questions