Potrzebuję napisać 2-wymiarowy renderer OpenGL ES na iOS. Powinien narysować pewne prymitywy, takie jak linie i wielokąty na obrazie 2D (będzie to renderowanie mapy wektorowej). Który sposób jest najlepszy do uzyskania obrazu z kontekstu OpenGL w tym zadaniu? Mam na myśli, czy powinienem uczynić te prymitywy teksturami, a potem uzyskać z nich obraz, czy co? Będzie też świetnie, jeśli ktoś da przykłady lub samouczki, które wyglądają jak to, czego potrzebuję (2d renderowania GL do obrazu). Z góry dziękuję!OpenGL ES 2d renderowanie do obrazu
Odpowiedz
Jeśli potrzebujesz renderować scenę OpenGL ES 2-D, a następnie wyodrębnić obraz tej sceny do użycia poza OpenGL ES, masz dwie główne opcje.
Pierwszym z nich jest po prostu renderować scenę i używać glReadPixels()
aby pobrać dane RGBA na scenie i umieścić ją w tablicy bajtów, jak w poniższym przykładzie:
GLubyte *rawImagePixels = (GLubyte *)malloc(totalBytesForImage);
glReadPixels(0, 0, (int)currentFBOSize.width, (int)currentFBOSize.height, GL_RGBA, GL_UNSIGNED_BYTE, rawImagePixels);
// Do something with the image
free(rawImagePixels);
Druga, o wiele szybciej, sposób robienie tego ma na celu renderowanie twojej sceny do obiektu bufora ramki (FBO) z teksturami, na którym tekstura została dostarczona przez pamięci podręczne tekstur w systemie iOS 5.0. Opisuję to podejście w this answer, chociaż nie pokazuję tam kodu dostępu do surowych danych.
wykonać następujące czynności, aby skonfigurować pamięć podręczną tekstury i wiążą FBO Tekstura:
CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, (__bridge void *)[[GPUImageOpenGLESContext sharedImageProcessingOpenGLESContext] context], NULL, &rawDataTextureCache);
if (err)
{
NSAssert(NO, @"Error at CVOpenGLESTextureCacheCreate %d");
}
// Code originally sourced from http://allmybrain.com/2011/12/08/rendering-to-a-texture-with-ios-5-texture-cache-api/
CFDictionaryRef empty; // empty value for attr value.
CFMutableDictionaryRef attrs;
empty = CFDictionaryCreate(kCFAllocatorDefault, // our empty IOSurface properties dictionary
NULL,
NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
attrs = CFDictionaryCreateMutable(kCFAllocatorDefault,
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(attrs,
kCVPixelBufferIOSurfacePropertiesKey,
empty);
//CVPixelBufferPoolCreatePixelBuffer (NULL, [assetWriterPixelBufferInput pixelBufferPool], &renderTarget);
CVPixelBufferCreate(kCFAllocatorDefault,
(int)imageSize.width,
(int)imageSize.height,
kCVPixelFormatType_32BGRA,
attrs,
&renderTarget);
CVOpenGLESTextureRef renderTexture;
CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
rawDataTextureCache, renderTarget,
NULL, // texture attributes
GL_TEXTURE_2D,
GL_RGBA, // opengl format
(int)imageSize.width,
(int)imageSize.height,
GL_BGRA, // native iOS format
GL_UNSIGNED_BYTE,
0,
&renderTexture);
CFRelease(attrs);
CFRelease(empty);
glBindTexture(CVOpenGLESTextureGetTarget(renderTexture), CVOpenGLESTextureGetName(renderTexture));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, CVOpenGLESTextureGetName(renderTexture), 0);
a następnie można tylko odczytać bezpośrednio z bajtów, które z powrotem w tym faktury (w formacie BGRA, a nie RGBA z glReadPixels()
) używając coś takiego:
CVPixelBufferLockBaseAddress(renderTarget, 0);
_rawBytesForImage = (GLubyte *)CVPixelBufferGetBaseAddress(renderTarget);
// Do something with the bytes
CVPixelBufferUnlockBaseAddress(renderTarget, 0);
Jednakże, jeśli po prostu chcesz ponownie użyć obrazu w OpenGL ES, wystarczy, aby uczynić swoją scenę tekstury oparciem FBO a następnie wykorzystać tę fakturę w swoim drugim poziomie wykonanie.
Pokazuję przykład renderowania do tekstury, a następnie wykonuję na niej przetwarzanie, w przykładowej aplikacji CubeExample w ramach mojego open source GPUImage, jeśli chcesz zobaczyć to w akcji.
- 1. Renderowanie OpenGL ES 2.0 do obrazu
- 2. OpenGL ES Renderowanie do tekstury
- 3. Jak ponownie napisać aplikację 2D OpenGL dla OpenGL ES?
- 4. Android OpenGL ES Support Everywhere?
- 5. OpenGL lub OpenGL ES
- 6. Używanie OpenGL do 2D
- 7. Narysuj obraz 2D przy użyciu OpenGL ES 2.0
- 8. iPhone OpenGL ES - jak wybrać
- 9. Wybierz OpenGL ES 1.1 lub OpenGL ES 2.0?
- 10. OpenGL - Renderowanie w teksturę
- 11. Różnica w iOS OpenGL ES i Android OpenGL ES
- 12. OpenGL ES 2.0 IllegalArgumentException
- 13. OpenGL-ES i Cg
- 14. OpenGL ES For Iphone
- 15. Suwaki obsługujące OpenGL ES i OpenGL
- 16. Mgła OpenGL a mgła OpenGL ES
- 17. Renderowanie ognia w OpenGL
- 18. Renderowanie wielowątkowe na OpenGL
- 19. Renderowanie oparte na wektorze OSM w czasie rzeczywistym w systemie iOS (przy użyciu OpenGL ES)
- 20. OpenGL: Szybkie renderowanie poza ekranem
- 21. Nauka OpenGL ES 1.x
- 22. Renderowanie strony internetowej do obrazu
- 23. OpenGL ES 2.0 + Cairo: HUD
- 24. Algorytmy transformacji wierzchołków OpenGL ES 2.0
- 25. Renderowanie obiektu CII w teksturę OpenGL ES 2.0 w systemie iOS
- 26. OpenGL es 2.0 Czytaj bufor głębokości
- 27. Core Animation lub OpenGL ES?
- 28. OpenGL ES Tekstury asynchroniczne ładowanie
- 29. Renderowanie wielowątkowe D3D/OpenGL/Cokolwiek
- 30. Samouczki i biblioteki do gier OpenGL-ES na Androida
wielkie dzięki, ale czy to działa tylko z iOS 5? – medvedNick
@medvedNick - 'glReadPixels()' działa we wszystkich wersjach systemu operacyjnego, ale pamięci podręczne tekstur zostały wprowadzone dopiero w iOS 5.0. Są znacznie, dużo szybsze, ale mają tylko 5.0. Możesz jednak wykonać sprawdzanie w czasie wykonywania i powrócić do wolniejszego 'glReadPixels()' na starszych wersjach systemu operacyjnego. Ponownie sprawdź mój kod GPUImage, ponieważ robię to tutaj. –
Skrytki tekstur mają wersję 5.0 i wyższą, ale czy nie są one szybkie tylko na niektórych urządzeniach? na przykład Szybko na 4S/iPad2 i odpowiednik glReadPixels/glTexImage2D wszędzie indziej. –