OpenGL ES 2.0-Android上的多路径/后处理
我是新来的,也是android版OpenGL ES 2.0的新手。我正试图做一些非常简单的事情,但由于某些原因,我无法让它工作。 基本上,我尝试使用帧缓冲区在片段着色器中执行一些后处理工作,然后将其显示在屏幕上。下面是我的片段着色器的简化版本:OpenGL ES 2.0-Android上的多路径/后处理,android,opengl-es-2.0,post-processing,Android,Opengl Es 2.0,Post Processing,我是新来的,也是android版OpenGL ES 2.0的新手。我正试图做一些非常简单的事情,但由于某些原因,我无法让它工作。 基本上,我尝试使用帧缓冲区在片段着色器中执行一些后处理工作,然后将其显示在屏幕上。下面是我的片段着色器的简化版本: precision mediump float; uniform sampler2D u_Texture0; uniform sampler2D u_Texture1; uniform float u_FirstPass; varying vec3 v
precision mediump float;
uniform sampler2D u_Texture0;
uniform sampler2D u_Texture1;
uniform float u_FirstPass;
varying vec3 v_texCoord;
float mytexture2D(sampler2D text0, vec2 coord)
{
vec4 pixelColor=texture2D(text0, coord.xy);
return pixelColor.r * 0.299 + pixelColor.g * 0.587 + pixelColor.b * 0.114;
}
void main()
{
if(u_FirstPass==1.0)
{
gl_FragColor = vec4(0.0,0.0,mytexture2D(u_Texture0, v_texCoord.st),1.0);
}
else
{
gl_FragColor = texture2D(u_Texture1, v_texCoord.st);
}
}
我使用的FrameBufferObject类是:
package com.my.cameratesting;
import android.opengl.GLES20;
public class FrameBufferObject {
public int colorTexture;
private int frameBuffer;
private int depthRenderBuffer;
public FrameBufferObject(){
}
public void generate(int w, int h){
//Generate color texture
//-------------------------
int [] id = new int[1];
GLES20.glGenTextures(1, id, 0);
colorTexture = id[0];
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, colorTexture);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
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.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, w, h, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
//-------------------------
// Generate frame buffer;
//-------------------------
GLES20.glGenFramebuffers(1, id, 0);
frameBuffer = id[0];
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBuffer);
//Attach 2D texture to this FBO
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, colorTexture, 0);
//-------------------------
// Generate depth render buffer
//-------------------------
GLES20.glGenRenderbuffers(1, id, 0);
depthRenderBuffer = id[0];
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depthRenderBuffer);
GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, w, h);
//-------------------------
//Attach depth buffer to FBO
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, depthRenderBuffer);
//-------------------------
//and now you can render to GL_TEXTURE_2D
//GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBuffer);
//GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
}
public void unbind(){
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
}
public void bind(){
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBuffer);
}
public int getTextureId(){
return colorTexture;
}
}
最后:
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1f);
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT );
GLES20.glUseProgram(mProgramHandle);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
//fbo0 is properly instanciated in my onSurfaceCreated function
fbo0.generate(mWidth, mHeight);
fbo0.bind();
GLES20.glUniform1i(mTextureUniformHandle0, 0);
GLES20.glUniform1f(mFirstPassUniformHandle,1);
checkFBOError();
objects[0].draw(mProgramShader,mMVPMatrix);
fbo0.unbind();
//***** THIS IS THE BIT THAT DOESNT WORK AS I WOULD LIKE IT TO*******/
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,fbo0.colorTexture);
GLES20.glUniform1i(mTextureUniformHandle1, 0);
GLES20.glUniform1f(mFirstPassUniformHandle,0);
objects[0].draw(mProgramShader,mMVPMatrix);
}
因此,我希望我的图片在第一次传递后显示为蓝色-这在我不使用任何帧缓冲区并且不打算运行第二次传递时效果很好。现在,当我运行第二个过程时,我期望得到相同的输出,因为我没有对我的u_纹理1进行任何修改。。。相反,我得到了一个黑屏。
我显然在绑定纹理时做了一些错误的事情,但我不清楚纹理之间的乒乓应该如何工作。我在谷歌上搜索了很多,但在任何地方都找不到任何明确的例子。所以,如果有人能在这里帮助我,那就太好了,因为我已经用这个敲我的头很久了。thks
顺便说一句,如果您需要其他详细信息,请务必告诉我。在渲染第二遍时,您似乎没有使用第一遍生成的纹理:
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,fbo0.colorTexture);
GLES20.glUniform1i(mTextureUniformHandle1, 0);
GLES20.glUniform1f(mFirstPassUniformHandle,0);
这会将纹理绑定到纹理单元1,但随后会设置统一,以便着色器从纹理单元0采样。如果要使用纹理单元1,则设置制服的调用需要为:
GLES20.glUniform1i(mTextureUniformHandle1, 1);
还有一些事情可能会引起关注:
- 至少在这里显示的代码中,你永远不会清除FBO。您需要确保在绑定FBO后有一个
调用glClear()
- 我认为这个调用首先需要一个纹理绑定。另外,请确保具有正确的活动纹理单元:
您可能不希望在每次重画时从位图加载纹理。您应该能够在安装过程中加载一次GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
- 在每次重画时调用
方法。其中的大部分内容在安装过程中只需执行一次generate()
- ES 2.0中两种纹理的非增强功能不保证支持“GL_REPEAT”(GL_REPEAT)包裹模式。除非您的宽度和高度是二的幂,否则您可能需要使用
,以确保它能在所有设备上工作GL\u-CLAMP\u-to\u-EDGE