android opengl模糊,Android:双重渲染使用OpenGL渲染到SurfaceTexture
时间: 2024-02-06 07:04:44 浏览: 155
Android OpenGL ES从入门到精通
要实现模糊效果,可以使用双重渲染技术,即将OpenGL渲染到SurfaceTexture,再将SurfaceTexture渲染到屏幕上。
下面是一个简单的示例代码:
1. 首先,在XML布局文件中添加一个TextureView:
```
<TextureView
android:id="@+id/textureView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
```
2. 在Activity中获取TextureView并设置监听器:
```
private TextureView textureView;
private SurfaceTexture surfaceTexture;
private int textureId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textureView = findViewById(R.id.textureView);
textureView.setSurfaceTextureListener(surfaceTextureListener);
}
private TextureView.SurfaceTextureListener surfaceTextureListener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
surfaceTexture = surface;
textureId = createTexture();
startRender();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
stopRender();
surfaceTexture = null;
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
};
```
3. 创建OpenGL纹理:
```
private int createTexture() {
int[] textures = new int[1];
GLES20.glGenTextures(1, textures, 0);
int textureId = textures[0];
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);
return textureId;
}
```
4. 开始渲染:
```
private RenderThread renderThread;
private void startRender() {
if (renderThread == null) {
renderThread = new RenderThread();
renderThread.start();
}
}
private void stopRender() {
if (renderThread != null) {
renderThread.stopRender();
renderThread = null;
}
}
private class RenderThread extends Thread {
private volatile boolean isRender = true;
@Override
public void run() {
super.run();
EglCore eglCore = new EglCore();
WindowSurface windowSurface = new WindowSurface(eglCore, surfaceTexture);
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
while (isRender) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
// 在这里进行OpenGL渲染操作
windowSurface.swapBuffers();
}
windowSurface.release();
eglCore.release();
}
public void stopRender() {
isRender = false;
}
}
```
5. 最后,在onDrawFrame方法中进行双重渲染:
```
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
// 在这里进行OpenGL渲染操作
SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
surfaceTexture.updateTexImage();
// 将SurfaceTexture渲染到屏幕上
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
GLES20.glViewport(0, 0, getWidth(), getHeight());
GLES20.glUseProgram(programId);
int uTextureSamplerLocation = GLES20.glGetUniformLocation(programId, "uTextureSampler");
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId);
GLES20.glUniform1i(uTextureSamplerLocation, 0);
GLES20.glEnableVertexAttribArray(aPositionLocation);
GLES20.glVertexAttribPointer(aPositionLocation, 2, GLES20.GL_FLOAT, false, 0, vertexBuffer);
GLES20.glEnableVertexAttribArray(aTextureCoordLocation);
GLES20.glVertexAttribPointer(aTextureCoordLocation, 2, GLES20.GL_FLOAT, false, 0, textureBuffer);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GLES20.glDisableVertexAttribArray(aPositionLocation);
GLES20.glDisableVertexAttribArray(aTextureCoordLocation);
}
```
阅读全文