Question

I'm starting out with the Android NDK and OpenGL. I know I'm doing something (probably a few) things wrong here and since I keep getting a black screen when I test I know the rendering isn't being sent to the screen.

In the Java I have a GLSurfaceView.Renderer that calls these two native methods. They are being called correctly but not drawing to the device screen.

Could someone point me in the right direction with this?

Here are the native method implementations:

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);
}

The log output is:

init() draw() draw() draw() etc..

Was it helpful?

Solution 2

I finally found the problem after MUCH tinkering.

Turns out that because I was calling the code from a GLSurfaceView.Renderer in Java the frame buffer already existed and so by calling:

glGenFramebuffersOES(1, &framebuffer);

I was unintentionally allocating a NEW buffer that was not attached to the target display. By removing this line and replacing it with:

framebuffer = (GLuint) 0;

It now renders to the correct buffer and displays properly on the screen. Note that even though I don't really use the buffer in this snippet, changing it is what messed up the proper display.

OTHER TIPS

I don't think that this is a real solution at all.

I'm having the same problem here, using framebuffer objects inside native code, and by doing

framebuffer = (GLuint) 0;

you're only using the default frame buffer, which always exist and is reserved to 0. Technically, you could erase all your code related to framebuffers and your app should be working properly as framebuffer 0 is always generated and is the one binded by defaut.

But, you should be able to generate multiple frame buffers and swap between them using the binding function (glBindFramebuffer) as you please. But that doesn't seems to be working on my end and I haven't found the real solution yet. There's not much documentation on the android part, and I'm starting to wonder if fbo are really supported in native code. They do work properly inside the java code though, I've tested it with succes !

Oh ! And I just noticed that your buffer dimensions are not power of 2...that usually should be the case for all textures/buffers like structure in Opengl.


UPDATE :

Now I'm fairly sure you cannot use FBOs with android (2.2 or lower) and ndk (version r5b or lower). It is a whole different game if you use the new 3.1 release though, where you can code all of your app with native code (no more jni wrapper necessary), but I haven't tested it yet !

On the other hand, I've manage to make Stencil buffers and textures work flawlessly ! So the workaround will be to use those for my rendering logic, and just forget about FBO offscreen rendering.

I had similar issues when moving form iOS to Android NDK here is my complete solution too.

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top