Android opengl 1.1 渲染到纹理 1286 错误(无效的帧缓冲区操作)

发布于 2025-01-02 08:12:02 字数 3341 浏览 0 评论 0原文

我正在尝试在我的 Android 游戏中实现运动模糊效果。

经过大量研究后,我发现最好的方法是使用帧缓冲区对象将前一帧保存为纹理,并将其渲染在当前帧的顶部。所以看到一些不错的教程< /a> 关于如何做类似的事情,我最终得到了这段代码,它基本上**在纹理上渲染我的场景,然后将纹理绘制到默认的帧缓冲区。

它只绘制白色纹理**,并在 gl.glGetError() 中出现 1286(无效帧缓冲区操作)错误

已解决:问题似乎是两个纹理尺寸的非幂,正如 Jean 所说

int[] fb, depthRb, renderTex; 
int texW = 480 * 2; 
int texH = 800 * 2; 
IntBuffer texBuffer;
int[] buf = new int[texW * texH];
GL11ExtensionPack gl11ep ;
void setup(GL10 gl)
{
    gl11ep=(GL11ExtensionPack)gl;           

    fb = new int[1];
    depthRb = new int[1];
    renderTex = new int[1];

    gl11ep.glGenFramebuffersOES(1, fb, 0);
    gl11ep.glGenRenderbuffersOES(1, depthRb, 0); // the depth buffer

    gl.glGenTextures(1, renderTex, 0);// generate texture
    gl.glBindTexture(GL10.GL_TEXTURE_2D, renderTex[0]);

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);

    texBuffer = ByteBuffer.allocateDirect(buf.length*4).order(ByteOrder.nativeOrder()).asIntBuffer();

    gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGB, texW, texH, 0, GL10.GL_RGB, GL10.GL_UNSIGNED_SHORT_5_6_5, texBuffer);


    gl11ep.glBindRenderbufferOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, depthRb[0]);
    gl11ep.glRenderbufferStorageOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, GL11ExtensionPack.GL_DEPTH_COMPONENT16, texW, texH);

}

boolean RenderStart(GL10 gl)
{
    // Bind the framebuffer
    gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, fb[0]);
    // specify texture as color attachment
    gl11ep.glFramebufferTexture2DOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES, GL10.GL_TEXTURE_2D, renderTex[0], 0);
    // attach render buffer as depth buffer
    gl11ep.glFramebufferRenderbufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, GL11ExtensionPack.GL_DEPTH_ATTACHMENT_OES, GL11ExtensionPack.GL_RENDERBUFFER_OES, depthRb[0]);

    int error = gl.glGetError();
    if (error != GL10.GL_NO_ERROR) {
                  Tools.con("Background Load GLError: " + error) ;//here the 1286 error
    }

    int status = gl11ep.glCheckFramebufferStatusOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES);
    if (status != GL11ExtensionPack.GL_FRAMEBUFFER_COMPLETE_OES)//here always geting true
    {
        return false;
    }

    return true;
}

void RenderEnd(GL10 gl)
{
    gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);
    gl.glClearColor(0f, 0f, 0f, 1.0f);
    gl.glClear( gl.GL_DEPTH_BUFFER_BIT | gl.GL_COLOR_BUFFER_BIT);
    gl.glEnable(GL10.GL_TEXTURE_2D);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, renderTex[0]);
    gl.glColor4f(1,1,1,1);
    ((GL11Ext) gl).glDrawTexfOES(0, 0, 0,800, 480);
    gl.glDisable(GL10.GL_TEXTURE_2D);

}


public void onDrawFrame(GL10 gl)
    {

    this.RenderStart(gl);
    render(gl);//render scene
    this.RenderEnd(gl);
    }

public void onSurfaceCreated(GL10 gl, EGLConfig config)
    {
       ...
       setup(gl);
    }

I am trying to implement a motion blur effect in my android game.

After a lot of research I found that the best way to do that is to save the previous frame as a texture using the Frame Buffer Object and render it on top of the current frame. So seeing some nice tutorials on how to do something like that I ended up with this code which basically **render my scene on the texture and then draws the texture to the default framebuffer.

It only draw's a white texture** with a 1286 (Invalid framebuffer operation) error in gl.glGetError()

SOLVED:The problem seems to be the non power of two texture dimmensions as Jean said

int[] fb, depthRb, renderTex; 
int texW = 480 * 2; 
int texH = 800 * 2; 
IntBuffer texBuffer;
int[] buf = new int[texW * texH];
GL11ExtensionPack gl11ep ;
void setup(GL10 gl)
{
    gl11ep=(GL11ExtensionPack)gl;           

    fb = new int[1];
    depthRb = new int[1];
    renderTex = new int[1];

    gl11ep.glGenFramebuffersOES(1, fb, 0);
    gl11ep.glGenRenderbuffersOES(1, depthRb, 0); // the depth buffer

    gl.glGenTextures(1, renderTex, 0);// generate texture
    gl.glBindTexture(GL10.GL_TEXTURE_2D, renderTex[0]);

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);

    texBuffer = ByteBuffer.allocateDirect(buf.length*4).order(ByteOrder.nativeOrder()).asIntBuffer();

    gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGB, texW, texH, 0, GL10.GL_RGB, GL10.GL_UNSIGNED_SHORT_5_6_5, texBuffer);


    gl11ep.glBindRenderbufferOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, depthRb[0]);
    gl11ep.glRenderbufferStorageOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, GL11ExtensionPack.GL_DEPTH_COMPONENT16, texW, texH);

}

boolean RenderStart(GL10 gl)
{
    // Bind the framebuffer
    gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, fb[0]);
    // specify texture as color attachment
    gl11ep.glFramebufferTexture2DOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES, GL10.GL_TEXTURE_2D, renderTex[0], 0);
    // attach render buffer as depth buffer
    gl11ep.glFramebufferRenderbufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, GL11ExtensionPack.GL_DEPTH_ATTACHMENT_OES, GL11ExtensionPack.GL_RENDERBUFFER_OES, depthRb[0]);

    int error = gl.glGetError();
    if (error != GL10.GL_NO_ERROR) {
                  Tools.con("Background Load GLError: " + error) ;//here the 1286 error
    }

    int status = gl11ep.glCheckFramebufferStatusOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES);
    if (status != GL11ExtensionPack.GL_FRAMEBUFFER_COMPLETE_OES)//here always geting true
    {
        return false;
    }

    return true;
}

void RenderEnd(GL10 gl)
{
    gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);
    gl.glClearColor(0f, 0f, 0f, 1.0f);
    gl.glClear( gl.GL_DEPTH_BUFFER_BIT | gl.GL_COLOR_BUFFER_BIT);
    gl.glEnable(GL10.GL_TEXTURE_2D);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, renderTex[0]);
    gl.glColor4f(1,1,1,1);
    ((GL11Ext) gl).glDrawTexfOES(0, 0, 0,800, 480);
    gl.glDisable(GL10.GL_TEXTURE_2D);

}


public void onDrawFrame(GL10 gl)
    {

    this.RenderStart(gl);
    render(gl);//render scene
    this.RenderEnd(gl);
    }

public void onSurfaceCreated(GL10 gl, EGLConfig config)
    {
       ...
       setup(gl);
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

总攻大人 2025-01-09 08:12:02

也许您应该使纹理的高度和宽度均为 2 的幂(即 512x512,甚至更小,因为它仅用于模糊效果)。几乎所有具有硬件加速功能的设备都需要它。测试此功能的快速方法是将其运行到模拟器中(仅作为软件,如果它支持代码中所需的所有其他功能,则它应该可以工作)

Probably you should make your texture have a power of 2 as height and width (i.e. 512x512, or even less since it's only for a blur effect). Almost every device with hardware acceleration needs that. Quick way to test this is to run it into the emulator (being software only it should work if it supports every other feature you need in your code)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文