2017-07-19 2 views
12

Ich habe eine Android-Anwendung, die GLES zum Rendern verwendet. Momentan wird Java zum Rendern verwendet und das Rendern ist in Ordnung. Aufgrund der Einschränkungen im Android-Java-Anwendungsspeicher plane ich, natives Rendering in meinen Java-Rendering-Code zu integrieren.Android OpenGLES Rendering mit C++ und Java

Um dies zu tun, folgte ich grundlegende native GLES Tutorials. Nach der Integration war das Java-Rendering nicht sichtbar, nur die Dinge, die ich in C++ rendere, wurden gesehen.

Die einfachste Version des Codes ist unter: https://github.com/khedd/JavaCppGLES Java-Code macht ein Dreieck, C++ rendert ein Quad. Wenn beide aufgerufen werden, ist nur Quad Renderer.

Wie kann ich dieses Problem lösen? Soll ich alles nach C++ portieren?

Code auf den Punkt gebracht.

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(); 
} 
+0

Sie haben dies aus "Speichergründen" getan? Warum erwarten Sie, dass dies weniger Speicher benötigt? Wahrscheinlich werden Ihre C++ - und Java OpenGL-Aufrufe auch auf verschiedenen Threads ausgeführt, aber ohne Code oder Idee des Iterop zwischen Java und C++ wird es ziemlich schwierig sein, Ratschläge zu geben. – MuertoExcobito

+0

es wird nicht weniger Speicher verwenden, aber in native kann ich mehr Speicherplatz verwenden. Auch Sie haben Recht, ich werde versuchen, morgen einen Mustercode zur Verfügung zu stellen. Ich bin mir ziemlich sicher, dass sie sich im selben Drawframe-Aufruf von Java befinden. – Hakes

Antwort

11

Das Problem wurde verursacht, weil die Puffer nicht gelöst wurden.

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

Hinzufügen dieser beiden Zeilen zu init und render behebt das Problem.

2

Der einfachste Weg, dies zu tun ist, um Ihren C++ - Code direkt von Ihrem Surface-Renderer aufzurufen.

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

Keine Notwendigkeit für Kontextwechsel.

+0

Ich versuche das Gleiche zu tun, aber ich habe einen Legacy-Code in Java, also ist meine erste Option, diese zusammen zu verwenden. Übrigens habe ich in meinem Code nicht native surface_created aufgerufen und nur Oberflächen-Draw verwendet. Ich werde das prüfen, danke. – Hakes

+1

Ich habe meine Initialisierung nach cpp verschoben, aber nichts hat sich geändert. Das Java-Dreieck wird immer noch nicht gerendert. – Hakes

+0

Wenn Sie Ihren Initialisierungs- und Zeichencode zeigen, sollte ich besser verstehen können. – WLGfx