13

I have an android application that uses GLES for rendering. Currently using Java to render stuff, and rendering is fine. Due to limitation in Android Java application memory I plan to integrate native rendering to my Java rendering code.

To do this I followed basic native GLES tutorials. After integrating, Java rendering was not visible, only the things I render in C++ was seen.

The simplest version of the code is at: https://github.com/khedd/JavaCppGLES Java code renders a Triangle, C++ renders a Quad. If both are called only Quad is renderer.

How can I solve this issue? Should I port everything to C++?

Code in a nutshell.

MyGLRenderer(){
    mTriangle = new Triangle();
    mCppRenderer = new MyCppRenderer();
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    gl.glClearColor(1.0f, 0.0f, 1.0f, 1.0f);

    //init java triangle
    mTriangle.init();
    //init c quad
    mCppRenderer.init(); //comment this line to make java triangle appear
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    gl.glViewport(0, 0, width, height);
}

@Override
public void onDrawFrame(GL10 gl) {
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    mTriangle.draw();
    mCppRenderer.draw ();
}
2
  • You did this for "memory reasons"? Why do you expect this will use less memory? Also, likely your C++ and Java OpenGL calls are happening on different threads, but, without any code or idea of the iterop between Java and C++, it's going to be pretty hard to give advice. Commented Jul 19, 2017 at 19:26
  • it will not use less memory but in native i can use more space. Also you are right i will try to provide a sample code tomorrow. I am quite sure that they are on the same thread within the drawFrame call of java. Commented Jul 19, 2017 at 19:34

2 Answers 2

12

The problem was caused because of not unbinding the buffers.

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

Adding these two lines to init and render fixes the problem.

Sign up to request clarification or add additional context in comments.

Comments

3

The easiest way to do this is to directly call your C++ code from your surface renderer.

private class PlayerRenderer implements GLSurfaceView.Renderer {

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        surface_created(); // native c++
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int wid, int hgt) {
        surface_changed(wid, hgt); // native c++
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        surface_draw(); // native c++
    }
}

private native void surface_created();
private native void surface_changed(int w, int h);
private native void surface_draw();

No need for context switching.

6 Comments

I am trying to do the same however I have a legacy code in Java so my first option is to use these together, by the way in my code i did not call native surface_created and surface changed only surface draw is used. I will look into this, thanks.
I moved my initialization to cpp, but nothing has changed the java triangle is still not being rendered.
If you show your initialisation and drawing code, I should be able to understand better then.
Git project uses java init version, for cpp init i only moved viewport and glclearcolor to corresponding parts on cpp that all. What should i add more?
The project you've linked to in your OP use precision highp in the shaders. Android GLES usually always uses mediump. I'm packing up and heading home and will look further into it later on.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.