2017-07-19 15 views
12

Mam aplikację na Androida, która używa GLES do renderowania. Obecnie używa Java do renderowania rzeczy, a renderowanie jest w porządku. Z powodu ograniczeń w pamięci aplikacji Java w Javie planuję zintegrować natywne renderowanie z moim kodem renderującym Java.Android OpenGLES Renderowanie za pomocą C++ i Java

Aby to zrobić, postępowałem zgodnie z podstawowymi samouczkami podręcznika GLES. Po integracji, renderowanie w Javie nie było widoczne, widoczne były tylko te elementy, które renderuję w C++.

Najprostszą wersją kodu jest: https://github.com/khedd/JavaCppGLES Kod Java renderuje trójkąt, C++ oznacza Quad. Jeśli oba są wywoływane, tylko Quad jest rendererem.

Jak mogę rozwiązać ten problem? Czy powinienem przenieść wszystko na C++?

Kod w pigułce.

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

Zrobiłeś to dla "powodów pamięci"? Dlaczego spodziewasz się, że to będzie zużywać mniej pamięci? Prawdopodobnie twoje wywołania C++ i Java OpenGL dzieją się na różnych wątkach, ale bez żadnego kodu lub idei iteropu między Javą i C++ trudno będzie ci doradzić. – MuertoExcobito

+0

to nie będzie zużywać mniej pamięci, ale w natywnym mogę użyć więcej miejsca. Również masz rację, postaram się dostarczyć jutro przykładowy kod. Jestem całkiem pewien, że są one w tym samym wątku w ramach wywołania drawFrame języka Java. – Hakes

Odpowiedz

11

Problem został spowodowany przez brak rozłączania buforów.

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

Dodanie tych dwóch linii do init i renderowania rozwiązuje problem.

2

Najprostszym sposobem wykonania tej czynności jest bezpośrednie wywołanie kodu C++ z renderera powierzchni.

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

Nie ma potrzeby przełączania kontekstu.

+0

Próbuję zrobić to samo, ale mam starszego kodu w Javie, więc moją pierwszą opcją jest używać tych razem, przy okazji w moim kodzie nie nazwał natywnej surface_created i powierzchni tylko remis powierzchni jest używany. Zajmę się tym, dzięki. – Hakes

+1

Przenieśliłem moją inicjalizację do cpp, ale nic się nie zmieniło, trójkąt java nadal nie jest renderowany. – Hakes

+0

Jeśli pokażesz kod inicjalizacyjny i rysunkowy, powinienem być w stanie lepiej to zrozumieć. – WLGfx

Powiązane problemy