首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AIDE-ide - render to texture中的opengl es 3.0返回空白纹理

AIDE-ide - render to texture中的opengl es 3.0返回空白纹理
EN

Stack Overflow用户
提问于 2016-05-31 04:42:38
回答 1查看 327关注 0票数 0

最终目标是GPU图像处理(颜色量化,像素排序,连通分量分析)使用乒乓方法,将两个纹理附加到同一帧缓冲区。

我已经查看了其他线程,完成了我的纹理,检查了错误,遵循了this教程和that教程,查看了文档,但似乎什么都不起作用。我可以很好地渲染到屏幕上,但我可以渲染到附加到帧缓冲区的纹理。

我知道绘制到四边形作品的代码,因为我对两种类型的渲染都使用相同的代码。我没有收到glCheckFramebufferStatus或glGetErrors的错误,一切看起来就像教程中的一样,希望我已经创建或附加了一个渲染缓冲区,因为我不需要深度或模板数据。所以我有点不知所措。任何帮助都将不胜感激,因此我可以继续解决困难的问题。

用于创建帧缓冲区和纹理以及检查错误的代码,在ImageRenderer类中:

代码语言:javascript
复制
public static int createFBO()
{
    int[] fbo = new int[1];
    GLES30.glGenFramebuffers(1,fbo,0);
    GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, fbo[0]);
        
    int error = GLES30.glGetError();
    if(error != GLES30.GL_NO_ERROR)
    {
        while (error !=GLES30.GL_NO_ERROR )
        {
            System.out.println(error);
            error = GLES30.glGetError();
        }
        GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, 0);
        return 0;
    }
    else
    {
        GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, 0);
        return fbo[0];
    }
}
    
public static int[] createFBOTextures(int framebuffer, int width, int height)
{
    //bind the framebuffer
    GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, framebuffer);
        
    int[] rt = new int[2];
    GLES30.glGenTextures(2, rt, 0);
    int[] DrawBuffers = {GLES30.GL_COLOR_ATTACHMENT0,GLES30.GL_COLOR_ATTACHMENT1};

    for (int i=0; i<2; i++)
    {
        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, rt[i]);
        GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D,0,GLES30.GL_RGBA32F, width, height,0,GLES30.GL_RGBA, GLES30.GL_FLOAT, null);
        GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);
        GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR_MIPMAP_LINEAR);
        GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE);
        GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE);
            // Attach each texture to colour attachement #i
        GLES30.glFramebufferTexture2D (GLES30.GL_FRAMEBUFFER, DrawBuffers[i], GLES30.GL_TEXTURE_2D, rt[i], 0);
    }
        
    if(check_framebuffer_errors())
        return null;
    else
        return rt;
    }
    
public static boolean check_framebuffer_errors()
{
    if(GLES30.glCheckFramebufferStatus(GLES30.GL_FRAMEBUFFER) != GLES30.GL_FRAMEBUFFER_COMPLETE)
    {
            System.out.println(GLES30.glCheckFramebufferStatus(GLES30.GL_FRAMEBUFFER));
        return true;
    }
    else
    {
        int error = GLES30.glGetError();
        if(error !=GLES30.GL_NO_ERROR )
        {
            while (error != GLES30.GL_NO_ERROR)
            {
                System.out.println(error);
                error = GLES30.glGetError();
            }
            return true;
        }
        else
            return false;
    }
}

所有由PixelCounter对象生成的绘制命令,初始化方式如下:

代码语言:javascript
复制
public PixelCounter(Bitmap b)
{
    mWidth = b.getWidth();
    mHeight = b.getHeight();
            
    defineShape();
    ConversionData = ImageRenderer.createUBO(16+3);
    ImageRenderer.updateBuffer(toXYZ,0,ConversionData);
    ImageRenderer.updateBuffer(new float[]{0.95047f, 1.0f, 1.08883f},15,ConversionData);
    FBOHandle = ImageRenderer.createFBO();
    //create temporary texture to pass bitmap to float texture
    temptex = ImageRenderer.loadTexturefromBitmap(b);
    //create ping-pong textures
    FBOTextureHandles = ImageRenderer.createFBOTextures(FBOHandle, mWidth,mHeight);
            
    to_LAB = compile_shader(new String[]{default_vertex,to_lab});
    to_screen = compile_shader(new String[]{default_vertex, render_to_screen});
    to_texture = compile_shader(new String[]{default_vertex, render_to_texture});
}

绘制为四边形的代码

代码语言:javascript
复制
//draw temptex to initial src texture
GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER,FBOHandle);
GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT | GLES30.GL_DEPTH_BUFFER_BIT);
//GLES30.glViewport(0,0,mWidth,mHeight);
bindTexture(temptex, to_texture, "src");
GLES30.glDrawBuffers(1, new int[]{GLES30.GL_COLOR_ATTACHMENT0}, 0);    
simple_draw(to_texture);
        
//draw to screen
GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER,0);
bindTexture(FBOTextureHandles[dest],to_screen, "src");
simple_draw(to_screen);

simple_draw函数

代码语言:javascript
复制
private void simple_draw(int program)
{
    GLES30.glUseProgram(program);

    //get handle to vertex shader's position member
    mPositionHandle = GLES30.glGetAttribLocation(program, "position");

    //Add attribute array of vertices
        GLES30.glEnableVertexAttribArray(mPositionHandle);
        GLES30.glVertexAttribPointer(
            mPositionHandle, mPositionDataSize,
        GLES30.GL_FLOAT, false,
            mStrideBytes, vertexBuffer);

        GLES30.glDrawElements(
                GLES30.GL_TRIANGLES, drawOrder.length,
                GLES30.GL_UNSIGNED_SHORT, drawListBuffer);
    }

代码语言:javascript
复制
private String render_to_texture =
"#version 300 es \n" +
"uniform sampler2D src;\n"+
"in vec4 coord;\n"+
"layout(location = 0) out vec4 dest;\n" +

"void main()\n"+
"{\n"+
    "vec2 size = vec2(textureSize(src,0));\n"+
    "ivec2 uv_coord = ivec2((coord.xy+vec2(1.0,1.0))/2.0*size);\n"+ 
    "dest = texelFetch(src,uv_coord,0);\n"+
"}";
EN

回答 1

Stack Overflow用户

发布于 2016-06-15 15:07:23

解决了。渲染前添加glViewport(0,0,width,height)。虽然我很好奇宽度/高度的默认值是什么,因为宽度/高度是从手机运行助手的相机拍摄的照片中检索出来的(所以尺寸应该与GLSurfaceView相同)。

编辑:当绘制到第二个纹理作为目标时,还需要将新的参数更改为(2,glDrawBuffers int[]{GL_NONE,COLOR_ATTACHMENT1},0)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37533427

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档