【问题标题】:Android NDK OpenGL ES 1.0 Simple RenderingAndroid NDK OpenGL ES 1.0 简单渲染
【发布时间】:2011-06-09 19:51:00
【问题描述】:

我开始使用 Android NDK 和 OpenGL。我知道我在这里做错了一些事情(可能是一些),因为我在测试时一直黑屏,所以我知道渲染没有发送到屏幕上。

在 Java 中,我有一个调用这两个本地方法的 GLSurfaceView.Renderer。它们被正确调用,但未绘制到设备屏幕。

有人能指出我正确的方向吗?

这里是本地方法的实现:

int init()
{
    sendMessage("init()");

    glGenFramebuffersOES(1, &framebuffer);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);

    glGenRenderbuffersOES(1, &colorRenderbuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, 854, 480);
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);

    GLuint depthRenderbuffer;
    glGenRenderbuffersOES(1, &depthRenderbuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, 854, 480);
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);

    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
    if(status != GL_FRAMEBUFFER_COMPLETE_OES)
        sendMessage("Failed to make complete framebuffer object");

    return 0;
}

void draw()
{
    sendMessage("draw()");

    GLfloat vertices[] = {1,0,0, 0,1,0, -1,0,0};
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, vertices);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glDisableClientState(GL_VERTEX_ARRAY);

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
}

日志输出为:

初始化() 画() 画() 画() 等等。

【问题讨论】:

    标签: c++ android opengl-es android-ndk-r4


    【解决方案1】:

    经过多次修改,我终于找到了问题。

    事实证明,因为我是从 Java 中的 GLSurfaceView.Renderer 调用代码,所以帧缓冲区已经存在,因此通过调用:

    glGenFramebuffersOES(1, &framebuffer);
    

    我无意中分配了一个未附加到目标显示器的新缓冲区。通过删除此行并将其替换为:

    framebuffer = (GLuint) 0;
    

    它现在渲染到正确的缓冲区并正确显示在屏幕上。请注意,即使我在此 sn-p 中并没有真正使用缓冲区,但更改它会破坏正确的显示。

    【讨论】:

    • 这里,khronos.org/opengles/sdk/docs/man/xhtml/…,如果您设置 framebuffer = 0,您可以看到您正在使用默认帧缓冲区。“默认的窗口系统提供的帧缓冲区始终是帧缓冲区完整的,因此返回 GL_FRAMEBUFFER_COMPLETE当 GL_FRAMEBUFFER_BINDING 为 0 时。”这不是答案,因为您不知道到底是哪个问题。本机代码不支持 Android OpenGL ES 2.0 帧缓冲区。我不知道为什么,但这是你的问题。
    【解决方案2】:

    我认为这根本不是一个真正的解决方案。

    我在这里遇到了同样的问题,在本机代码中使用帧缓冲区对象,并通过做

    framebuffer = (GLuint) 0;
    

    您仅使用默认帧缓冲区,该缓冲区始终存在并保留为 0。 从技术上讲,您可以删除所有与帧缓冲区相关的代码,并且您的应用程序应该可以正常工作,因为始终生成帧缓冲区 0 并且是默认绑定的。

    但是,您应该能够根据需要使用绑定函数 (glBindFramebuffer) 生成多个帧缓冲区并在它们之间进行交换。但这似乎对我不起作用,我还没有找到真正的解决方案。关于 android 部分的文档并不多,我开始怀疑本机代码是否真的支持 fbo。虽然它们在 java 代码中确实可以正常工作,但我已经成功地对其进行了测试!

    哦!而且我刚刚注意到您的缓冲区尺寸不是 2 的幂...通常应该是所有纹理/缓冲区(如 Opengl 中的结构)的情况。


    更新:

    现在我很确定您不能将 FBO 与 android(2.2 或更低版本)和 ndk(r5b 或更低版本)一起使用。如果您使用新的 3.1 版本,这是一个完全不同的游戏,您可以使用本机代码编写所有应用程序(不需要更多的 jni 包装器),但我还没有测试它!

    另一方面,我已经设法使 Stencil 缓冲区和纹理完美地工作! 所以解决方法是将这些用于我的渲染逻辑,而忘记 FBO 屏幕外渲染。

    【讨论】:

    • 我也遇到了同样的问题。您仍然认为 FBO 在 NDK r5b 上无法使用 pre-OS-3.x 吗?
    • 是的,我愿意!我什么都试过了……已经环顾了好几个星期了……我唯一能做的就是模板!所以我只是从等式中删除了 FBO...性能稍差,但工作良好;)
    • 我遇到了同样的问题。但我在删除 FBO 时修复了它。
    【解决方案3】:

    我在从 iOS 迁移到 Android NDK 时遇到了类似的问题,这也是我的完整解决方案。

    OpenGLES 1.1 with FrameBuffer / ColorBuffer / DepthBuffer for Android with NDK r7b

    【讨论】:

      猜你喜欢
      • 2012-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-31
      • 2012-02-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多