2015-04-28 13 views
18

Mam kod jest wykonywana przy użyciu glMapBufferRange() z OpenGL ES 3.0 na Androida, które wygląda następująco:Bezpieczne korzystanie z glMapBufferRange() na Android/Java

glBindBuffer(GL_ARRAY_BUFFER, myVertexBufferName); 
    glBufferData(GL_ARRAY_BUFFER, myVertexBufferSize, null, GL_STATIC_DRAW); 
    ByteBuffer mappedBuffer = (ByteBuffer)glMapBufferRange(
    GL_ARRAY_BUFFER, 
    0, myVertexBufferSize, 
    GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); 

    // [fill buffer...] 

    glUnmapBuffer(GL_ARRAY_BUFFER); 

Moje pytanie jest o rzutowanie w dół wynik glMapBufferRange() do ByteBuffer na trzecia linia. glMapBufferRange() jest declared to return a Buffer:

public static Buffer glMapBufferRange (int target, int offset, int length, int access)

Na moim platformy testowej funkcja zwraca podklasę ByteBuffer tak pracach odkrywkowych, ale czyni to założenie dla wszystkich platform lub wersji Android wspiera OpenGL ES 3+ nie robi wydaje się bardzo bezpieczny. Chociaż wydaje się to uzasadnione, nie znalazłem żadnej dokumentacji, która by to zagwarantowała, a gdyby było zagwarantowane, wydaje się, że funkcja powinna zostać zadeklarowana jako zwracająca ByteBuffer.

Jaki jest poprawny sposób (najlepiej obsługiwany przez dokumentację) korzystania z Buffer zwrócony przez glMapBufferRange()?

Odpowiedz

6

Jak już stwierdzono, brakuje dokumentacji. Ale nadal istnieje dość rozstrzygające odniesienie: Implementacja wiązań Java OpenGL jest częścią publicznego kodu źródłowego Androida.

Jeśli spojrzeć na realizację otoki JNI dla glMapBufferRange(), który jest w pliku glMapBufferRange.cpp, można zobaczyć, że bufor jest przydzielany przez wywołanie funkcji o nazwie NewDirectByteBuffer(). Na tej podstawie można bezpiecznie założyć, że bufor rzeczywiście jest ByteBuffer.

Podczas gdy sprzedawcy mogą zmieniać kod Androida, wydaje się mało prawdopodobne, aby ktokolwiek zmienił zachowanie powiązań Java (z wyjątkiem może naprawić błędy). Jeśli obawiasz się, że realizacja mogłaby się zmienić w nowszych wersjach Androida, z pewnością można użyć standardowej kontroli typu Java:

Buffer buf = glMapBufferRange(...); 
ByteBuffer byteBuf = null; 
if (buf instanceof ByteBuffer) { 
    byteBuf = (ByteBuffer)buf; 
} 

Albo można użyć bardziej skomplikowanej refleksji, począwszy nazywając getClass() na zwracanego bufora. Kolejnym pytaniem jest oczywiście to, co zrobisz, jeśli zwróconym buforem nie jest ByteBuffer. To naprawdę jedyny typ, który ma dla mnie sens.

+0

+1 za przejście do realizacji. Wdrożenie może się jednak zmienić, przynajmniej w teorii. Czy istnieje sposób na praktyczne wykorzystanie 'glMapBufferRange()' bez przyjmowania założeń dotyczących implementacji? Czy ta funkcja jest niewłaściwie określona? – rhashimoto

+0

@rhashimoto Dodałem trochę treści. Ale ta część była już dla ciebie jasna. –

+0

Myślę, że większość ludzi nie ma możliwości korzystania z ES 3.0+ lub OpenGL przez JNI na cokolwiek poważnego. Otworzyłem nagrodę za więcej ekspozycji. – rhashimoto

Powiązane problemy