简体   繁体   English

Android OpenGL:如何更改贴在纹理上的位图?

[英]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 . 现在,根据用户输入,我想用新的Bitmap更新我的Texture I tried recalling same function with different Bitmap but its not getting updated. 我尝试使用不同的Bitmap调用相同的功能,但未更新。 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 onDrawFrame

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

That method both creates a new texture and uploads a Bitmap to it. 该方法既创建了新纹理,又向其上载了Bitmap 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 (ie omit the glGenTextures , which is what creates the new texture). 如果是这样,则提供int纹理名称作为参数,而不是作为结果接收它,然后直接跳到glBindTexure (即,省略创建新纹理的glGenTextures )。

Eg 例如

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; 因此,从创建纹理并设置其过滤类型的位中会排除上传Bitmap的位。 to update an existing texture use the int you got earlier and call directly into updateTexture . 要更新现有纹理,请使用您之前获得的int并直接调用updateTexture

You may simply be not on the OpenGL rendering thread when changing the Bitmap. 更改位图时,您可能根本不在OpenGL渲染线程上。 When you change the Bitmap, save in a boolean that you did so, and then only in the rendering thread call texImage2D. 更改位图时,请保存为布尔值,然后仅在渲染线程中调用texImage2D。

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. 如果要以60 fps 实时更新纹理 ,则有更好的方法。 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. (1)您必须告诉OpenGL扩展使用外部纹理。 That is when defining your texture instead of using GLES20.GL_TEXTURE0 you use GLES11Ext.GL_TEXTURE_EXTERNAL_OES 那就是在定义纹理而不是使用GLES20.GL_TEXTURE0时,您使用GLES11Ext.GL_TEXTURE_EXTERNAL_OES

(2) you have to use the classes Surface and SurfaceTexture. (2)您必须使用Surface和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. (3)您必须在片段着色器上启用扩展。 You can't use sampler2D you have to use samplerExternalOES . 您不能使用sampler2D,而必须使用samplerExternalOES To enable the extension you put the following line at the top of your shader code: 要启用扩展,请将以下行放在着色器代码的顶部:

#extension GL_OES_EGL_image_external: require #extension GL_OES_EGL_image_external:要求

Code snapshot 代码快照

The above is a snapshot of my code, below is the fragment shader 上面是我的代码的快照,下面是片段着色器

Fragment shader 片段着色器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM