Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenGL ES 2.0-Android上的多路径/后处理_Android_Opengl Es 2.0_Post Processing - Fatal编程技术网

OpenGL ES 2.0-Android上的多路径/后处理

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

我是新来的,也是android版OpenGL ES 2.0的新手。我正试图做一些非常简单的事情,但由于某些原因,我无法让它工作。 基本上,我尝试使用帧缓冲区在片段着色器中执行一些后处理工作,然后将其显示在屏幕上。下面是我的片段着色器的简化版本:

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
    ,以确保它能在所有设备上工作


您确定复制的代码正确吗?该着色器无法按原样编译。谢谢Reto Koradi,对不起,我的错!第一个过程应该调用mytexture2D,而第二个过程应该调用texture2D。。。两次通过后的最终结果应该与第一次通过后的结果相同(或者至少我想这样做),即:我的照片是蓝色的。我已经修正了着色器,这样对所有愿意帮助我的人来说都更清晰。谢谢雷托·科拉迪。我已经按照建议改变了一切,当我做两次传球时,一切似乎都起了作用。但是现在我试着做n次传球,但似乎不起作用???我已经在线程顶部相应地更新了初始代码。如果有任何帮助,我将不胜感激,因为我还不知道这里可能有什么错误?请不要编辑问题以包含答案。这不是这个网站的工作方式。Stack Overflow不是一个论坛,它是一个问题和答案的存储库。如果您对问题进行了重大更改,则答案将无效,这与目的背道而驰。抱歉,感谢您为我回滚此内容。我想我必须提出另一个问题来揭露我现在的问题。。。