首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >glReadPixels + FBO不工作

glReadPixels + FBO不工作
EN

Stack Overflow用户
提问于 2014-07-10 16:34:23
回答 1查看 1.6K关注 0票数 0

在Android 2.通过调用glReadPixels + FBO从帧缓冲区读取。但是,字节数组是0。有趣的是,当我删除绑定代码(保留glReadPixels)时,它可以工作。

这让我怀疑我是否没有正确绑定缓冲区,尽管当我检查框架缓冲区状态(glCheckFramebufferStatus)时,我得到了GLES20.GL_FRAMEBUFFER_COMPLETE。知道我做错了什么吗?

代码语言:javascript
运行
复制
    int frameIdIndex=0,renderIdIndex=1,textureIdIndex=2;
    int[] bufferId=new int[3];

    Bitmap takeOne(Context cntxt) {

            DisplayMetrics dm = cntxt.getResources().getDisplayMetrics();
            int width = dm.widthPixels;
            int height = dm.heightPixels;

            //id  index  0 frameId, 1 renderId 2 textureId;

            GLES20.glGenFramebuffers(1,bufferId,frameIdIndex);
            GLES20.glGenRenderbuffers(1, bufferId, renderIdIndex);
            GLES20.glGenTextures(1, bufferId, textureIdIndex);

            // bind texture and load the texture mip-level 0
            // texels are RGB565
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,bufferId[textureIdIndex]);
            GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D,0,GLES20.GL_RGBA,width,height,0,GLES20.GL_RGBA,GLES20.GL_UNSIGNED_SHORT_5_6_5,null);

            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_MAG_FILTER, GLES20.GL_LINEAR);
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);


            // bind renderbuffer and create a 16-bit depth buffer
            // width and height of renderbuffer = width and height of
            // the texture
            GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, bufferId[renderIdIndex]);
            GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER,GLES20.GL_DEPTH_COMPONENT16,width,height);

            //bind the frameBuffer;
            GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER,bufferId[frameIdIndex]);

            //specify texture as color attachment
            GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,GLES20.GL_COLOR_ATTACHMENT0,GLES20.GL_TEXTURE_2D,bufferId[textureIdIndex],0);


            //specify renderbuffer as depth_attachment
            GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER,GLES20.GL_DEPTH_ATTACHMENT,GLES20.GL_RENDERBUFFER,bufferId[renderIdIndex]);


            //check for framebuffer complete
            int status= GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
            if(status !=GLES20.GL_FRAMEBUFFER_COMPLETE) {
                throw new RuntimeException("status:"+status+", hex:"+Integer.toHexString(status));
            }


            int screenshotSize = width * height;
            ByteBuffer bb = ByteBuffer.allocateDirect(screenshotSize * 4);
            bb.order(ByteOrder.nativeOrder());
            GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA,
                    GL10.GL_UNSIGNED_BYTE, bb);

            int pixelsBuffer[] = new int[screenshotSize];
            bb.asIntBuffer().get(pixelsBuffer);
            final Bitmap bitmap = Bitmap.createBitmap(width, height,
                    Bitmap.Config.RGB_565);
            bitmap.setPixels(pixelsBuffer, screenshotSize - width, -width,
                    0, 0, width, height);
            pixelsBuffer = null;

            short sBuffer[] = new short[screenshotSize];
            ShortBuffer sb = ShortBuffer.wrap(sBuffer);
            bitmap.copyPixelsToBuffer(sb);

            // Making created bitmap (from OpenGL points) compatible with
            // Android
            // bitmap
            for (int i = 0; i < screenshotSize; ++i) {
                short v = sBuffer[i];
                sBuffer[i] = (short) (((v & 0x1f) << 11) | (v & 0x7e0) | ((v & 0xf800) >> 11));
            }
            sb.rewind();
            bitmap.copyPixelsFromBuffer(sb);

            // cleanup
            GLES20.glDeleteRenderbuffers(1, bufferId,renderIdIndex);
            GLES20.glDeleteFramebuffers(1, bufferId ,frameIdIndex);
            GLES20.glDeleteTextures(1, bufferId,textureIdIndex);

            return bitmap;
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-07-10 17:28:32

您的格式和类型有些混淆。这个glTexImage2D()应该已经给你打了一个GL_INVALID_OPERATION电话,如果你检查了glGetError()

代码语言:javascript
运行
复制
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0,
    GLES20.GL_RGBA, width, height, 0,
    GLES20.GL_RGBA, GLES20.GL_UNSIGNED_SHORT_5_6_5, null);

GL_UNSIGNED_SHORT_5_6_5只能与GL_RGB格式一起使用。来自文档

如果类型为GL_UNSIGNED_SHORT_5_6_5而格式不是GL_RGB,则生成GL_RGB。

为了避免这种错误情况,调用需要如下:

代码语言:javascript
运行
复制
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0,
    GLES20.GL_RGB, width, height, 0,
    GLES20.GL_RGB, GLES20.GL_UNSIGNED_SHORT_5_6_5, null);

在我看来,glReadPixels()调用本身是很好的,所以我相信一旦你有了一个有效的纹理就可以使用它了。

bitmap.setPixels()调用可能有问题。文档说,它需要ARGB颜色,您将在这里使用RGBA。但这超出了你问题的主要范围。

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

https://stackoverflow.com/questions/24681908

复制
相关文章

相似问题

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