2013-06-09 10 views
6

Mam następującą sytuację:Co Surface użyć do eglMakeCurrent do kontekstu, który renderuje tylko do FBOs

w pole karne platformie renderowania biblioteki dla iOS i Androida (napisany w C (++)), mam dwa wątki, z których każdy potrzebuje własnego EGLContekstu: Gwint A jest głównym wątkiem; renderuje się do okna. Wątek B jest wątek generator, który robi różne obliczenia i czyni wyniki do tekstur, które są później wykorzystywane przez gwint A.

ponieważ nie mogę używać EGL na iOS, biblioteka używa wskaźników funkcji na statyczną Obj.- C służy do tworzenia nowego kontekstu i ustawiania go jako bieżącego. To już działa, tworzę kontekst wątku using

EAGLContext *contextA = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 

Kontekst dla gwintu B jest tworzony przy użyciu

EAGLContext *contextB = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:[contextA sharegroup]]; 

mogę następnie ustawić jedną z dwóch prąd:

[EAGLContext setCurrentContext:context]; 

Aby użyć tej samej logiki (wskaźników funkcji przekazanych do biblioteki) w systemie Android, chcę to zrobić po stronie C powiązań JNI, tym razem używając rzeczywistego EGL zamiast EAGL firmy Apple. Mogę łatwo utworzyć contextA przy użyciu WindowSurface i natywnego Window, mogę utworzyć contextB i przekazać contextA do parametru shareContext z połączenia eglCreateContext.

Ale gdy chcę, aby kontekstB był aktualny, muszę przekazać powierzchnię do wywołania eglMakeCurrent, i próbuję ustalić, jaki rodzaj powierzchni przejść.

  • Nie mogę użyć WindowSurface używam do contextA jak spec mówi w rozdziale 3.7, że „Co najwyżej jeden kontekst dla każdej obsługiwanej API klienta może być obecny na danym wątku w danym czasie, a co najwyżej jednym kontekście może być związany z określoną powierzchnią w danym czasie. "
  • Nie mogę podać wartości EGL_NO_SURFACE, ponieważ spowodowałoby to błąd EGL_BAD_MATCH w wywołaniu eglMakeCurrent.
  • Wygląda na to, że mógłbym użyć powierzchni PBuffer, ale waham się, ponieważ muszę określić szerokość i wysokość, gdy utworzę taką powierzchnię, a wątek B może chcieć tworzyć tekstury o różnych rozmiarach. Oprócz tego, "OpenGL ES 2.0 Programming Guide" Munshi, Ginsburg i Shreiner stwierdza w sekcji 3.8, że "Pbuffery są najczęściej używane do generowania map tekstur. Jeśli wszystko, co chcesz zrobić, to renderowanie do tekstury, zalecamy użycie obiektów framebuffer [.. .] zamiast pbuffers ponieważ są one bardziej wydajne”, który jest dokładnie to, co chcę robić w wątku B.

nie rozumiem co Munshi, Ginsurg i Shreiner myśli o tym zdaniu, w jaki sposób bufora ramki obiekt zastąpić powierzchnię bufora? Co się stanie, jeśli utworzę bardzo małą (powiedzmy 1x1px) powierzchnię pbuffera, aby kontekst był aktualny - czy mogę nadal renderować dowolnie duże FBO? Czy są jakieś inne możliwości, których jeszcze nie znam?

Bardzo dziękuję za pomoc!

Odpowiedz

2

skończyło się za pomocą powierzchni PBuffer wielkości (1x1) - i następnie utworzyć FBO i uczynienia do tekstury dobrze. Do ich wyświetlania (w innym wątku i innym (współdzielonym) kontekście OpenGL) używam powierzchni okna z ANativeWindow (jest tam przykład tego gdzieś w sdk).

3

Powierzchnia przechodząca do eglMakeCurrent() musi być powierzchnią EGL z eglCreateWindowSurface().Na przykład:

EGLSurface EglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, maEGLconfigs[0], surfaceTexture, null); 
    mEgl.eglMakeCurrent(mEglDisplay, EglSurface, EglSurface, mEglContext); 

Ale eglCreateWindowSurface() wymaga SurfaceTexture który jest dostarczany do onSurfaceTextureAvailable() wywołania zwrotnego, gdy TextureView jest tworzony, ale można też tworzyć off ekranie SurfaceTextures bez View.

Jest to przykład aplikacja, która wykorzystuje TextureView w Android SDK tutaj, chociaż używa SurfaceTexture dla kamer wideo, zamiast OpenGL ES rendering:

sources\android-17\com\android\test\hwui\GLTextureViewActivity.java 

Standardowo powierzchnia EGL dla FBOs będzie miał taki sam rozmiar jak SurfaceTexture, z którego zostały utworzone. Można zmienić rozmiar SurfaceTexture z:

surfaceTexture.setDefaultBufferSize(width, height); 

Nie używaj pbuffers na Androida, ponieważ niektóre platformy (Nvidia Tegra) nie obsługuje ich. Artykuł ten opisuje zalety FBOs ponad pbuffers szczegółowo:

http://processors.wiki.ti.com/index.php/Render_to_Texture_with_OpenGL_ES

+1

mógłbyś wyjaśnić, w jaki sposób można utworzyć SurfaceTexture off-screen bez żadnego widoku? Wiem, że to szerokie pytanie, ale wystarczy kilka wskazówek. –

+0

Zasadniczo używasz nowego operatora, takiego jak to: mSurfaceTexture = new SurfaceTexture (1); mSurfaceTexture.setDefaultBufferSize (miMaxWidth, miMaxHeight); – ClayMontgomery

+0

Czy można to zrobić z natywnego kodu? Próbowałem użyć SurfaceTexture (w tym nagłówka z frameworks/native/include/gui/SurfaceTexture.h), ale nadal otrzymuję błąd kompilacji: deklaracji SurfaceTexture nie można znaleźć w tym zakresie. –

0

Jeśli rysunek do FBO jest jedyną rzeczą, jaką chcesz zrobić, możesz pobrać dowolny EGLContext, który już został utworzony przez Ciebie lub kogoś innego (np. GLSurfaceView) i sprawić, by był aktualny, po prostu wygeneruj swój FBO, a następnie narysuj za jego pomocą. Problem polega na tym, jak udostępnić kontekstowy napis stworzony przez GLSurfaceView do wieloplatformowej biblioteki C++. Zrobiłem to, wywołując funkcję statyczną wewnątrz C++, aby uzyskać eglcontext i powierzchnię natychmiast po tym, jak kontekst został zmieniony przez warstwę Java. jak poniższy kod:

//This is a GLSurfaceView renderer method 
@override 
public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
    //up to this point, we know the EGLContext 
    //has already been set current on this thread. 
    //call JNI function to setup context 
    graphics_library_setup_context(); 
} 

C++ odpowiednik

void setup_context() { 
    context = eglGetCurrentContext(); 
    display = eglGetCurrentDisplay(); 
    surface = eglGetCurrentSurface(EGL_DRAW); 
} 
Powiązane problemy