Il loop di rendering di OpenGL ES è posizionato su un thread separato nella mia applicazione iphone. Tutto va bene, tranne che il metodo presentRenderbuffer di EAGLContext ha esito negativo. Il risultato è uno schermo bianco vuoto. Quando lo stesso codice viene eseguito sul thread principale, presentRenderbuffer ha esito positivo e la grafica viene visualizzata correttamente. Qual è il modo corretto di fare OpenGL su un thread separato?Come utilizzare OpenGL ES su un thread separato su iphone?
risposta
È necessario creare un EAGLSharegroup
.
Verificare this thread sulla condivisione di contesti OpenGL tra thread.
UPDATE
precedente per iOS5 ho condiviso contesti OpenGL tra fili per consentire il caricamento asincrono di texture dal disco. Ma gli CVOpenGLESTextureCaches
di iOS5 essenzialmente rendono i caricamenti di texture gratuiti, quindi non ho più bisogno di shareGroups e il mio codice è più semplice e veloce.
Non è necessario eseguire il rendering del contesto su un thread diverso. Invece, eseguire tutti i calcoli su un thread diverso e assicurarsi che il rendering si verifichi sul thread di visualizzazione principale.
Si può fare molto facilmente usando GCD. – Cthutu
Grazie, Fistman. L'ho fatto funzionare e ho ottenuto il guadagno di prestazioni che mi aspettavo dall'utilizzo di un thread separato. EAGLSharegroup ha risolto il problema.
Ho creato il contesto per il secondo thread come descritto here.
Ecco il codice standard:
#import <UIKit/UIKit.h>
#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/EAGLDrawable.h>
struct OpenGLContext
{
GLint Width;
GLint Height;
GLuint RenderBuffer;
GLuint FrameBuffer;
GLuint DepthBuffer;
UIView* View;
EAGLContext* MainContext;
EAGLContext* WorkingContext;
EAGLSharegroup* Sharegroup;
// Trivial constructor.
OpenGLContext();
// Call on the main thread before use.
// I call it in layoutSubviews.
// view must not be nil.
void MainInit(UIView* view);
// Call on the rendering thread before use, but
// after MainInit();
void InitOnSecondaryThread();
// Call before any OpenGL ES calls, at the
// beginning of each frame.
void PrepareBuffers();
// Present frame. Call at the end of each
// frame.
void SwapBuffers();
};
OpenGLContext::OpenGLContext()
{
Width = 0;
Height = 0;
RenderBuffer = 0;
FrameBuffer = 0;
DepthBuffer = 0;
View = 0;
MainContext = 0;
WorkingContext = 0;
Sharegroup = 0;
}
void OpenGLContext::InitOnSecondaryThread()
{
EAGLSharegroup* group = MainContext.sharegroup;
if (!group)
{
NSLog(@"Could not get sharegroup from the main context");
}
WorkingContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1 sharegroup:group];
if (!WorkingContext || ![EAGLContext setCurrentContext:WorkingContext]) {
NSLog(@"Could not create WorkingContext");
}
}
void OpenGLContext::MainInit(UIView* view)
{
View = view;
MainContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
if (!MainContext || ![EAGLContext setCurrentContext:MainContext]) {
NSLog(@"Could not create EAGLContext");
return;
}
NSLog(@"Main EAGLContext created");
glGenFramebuffersOES(1, &FrameBuffer);
glGenRenderbuffersOES(1, &RenderBuffer);
glGenRenderbuffersOES(1, &DepthBuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, FrameBuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, RenderBuffer);
if (![MainContext renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)View.layer])
{
NSLog(@"error calling MainContext renderbufferStorage");
return;
}
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, RenderBuffer);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &Width);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &Height);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, DepthBuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, Width, Height);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, DepthBuffer);
glFlush();
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
}
WorkingContext = MainContext;
}
void OpenGLContext::PrepareBuffers()
{
if (!WorkingContext || [EAGLContext setCurrentContext:WorkingContext] == NO)
{
NSLog(@"PrepareBuffers: [EAGLContext setCurrentContext:WorkingContext] failed");
return;
}
glBindFramebufferOES(GL_FRAMEBUFFER_OES, FrameBuffer);
}
void OpenGLContext::SwapBuffers()
{
if (!WorkingContext || [EAGLContext setCurrentContext:WorkingContext] == NO)
{
NSLog(@"SwapBuffers: [EAGLContext setCurrentContext:WorkingContext] failed");
return;
}
glBindRenderbufferOES(GL_RENDERBUFFER_OES, RenderBuffer);
if([WorkingContext presentRenderbuffer:GL_RENDERBUFFER_OES] == NO)
{
NSLog(@"SwapBuffers: [WorkingContext presentRenderbuffer:GL_RENDERBUFFER_OES] failed");
}
}
- 1. Qualsiasi alternativa glPolygonMode su iPhone (OpenGL ES)?
- 2. Come si attiva il multicampionamento in OpenGL ES su iPhone?
- 3. iPhone OpenGL ES - Come scegliere
- 4. OpenGL ES per Iphone
- 5. OpenGl ES su Iphone - Visualizzazione e rotazione di oggetti 3D
- 6. Consigli sull'accelerazione di OpenGL ES 1.1 su iPhone
- 7. Ottimizzazione di OpenGL ES su iPhone e interpretazione degli strumenti
- 8. OpenGL | ES su un PC desktop
- 9. OpenGL ES (iPhone) Touch Picking
- 10. Fullscreen texture iPhone OpenGL ES
- 11. iPhone OpenGL ES 2.0 - Pixel Perfect Textures
- 12. OpenGL ES iPhone - disegnare linee anti-aliasing
- 13. IPhone OpenGL ES viste singole o multiple?
- 14. Rendering OpenGL ES su richiesta con GLKit
- 15. Introduzione a OpenGL ES 2.0 su Windows
- 16. OpenGL ES black texture su Nexus S
- 17. Come posso eseguire il rendering dei riflessi in OpenGL ES su iPhone senza un buffer stencil?
- 18. Come utilizzare le funzioni OpenGL su un QT OpenGL Widget?
- 19. OpenGL o OpenGL ES
- 20. OpenGL ES (iPhone) alpha blending sembra strano
- 21. Scegli OpenGL ES 1.1 o OpenGL ES 2.0?
- 22. glGetUniformLocation ritorno -1 OpenGL ES (iPhone)
- 23. Tutorial e librerie per giochi OpenGL-ES su Android
- 24. Come caricare e visualizzare l'immagine in OpenGL ES per iphone
- 25. OpenGL ES arresto anomalo su spostamento sfondo, iOS 5.1
- 26. Come sviluppare le applicazioni OpenGL ES (GLES) 2.0 su Linux?
- 27. OpenGL ES Async texture loading
- 28. I timer C# vengono trascorsi su un thread separato?
- 29. Come utilizzare openGL con gcc su Mac?
- 30. OpenGL ES Render to Texture
Cosa intendi per "rendere gratuiti i caricamenti di texture"? Ho provato a chiamare CVOpenGLESTextureCacheCreateTextureFromImage() con un risultato di CVPixelBufferCreateWithBytes() e ci sono voluti solo il tempo necessario per caricare la texture con glTexImage2D(). – MoDJ
glTexImage2D fa l'equivalente di memcpy in una texture mentre TextureFromImage punta la texture sull'immagine - nessuna copia necessaria. È possibile risparmiare molta larghezza di banda della memoria. La tempistica da sola non rivelerà molto di quanto GL sia asincrono. È necessario esaminare l'utilizzo della GPU/CPU e la frequenza dei fotogrammi. –
Vedere http://stackoverflow.com/questions/12813442/cvopenglestexturecache-vs-gltexsubimage2d-on-ios, non sembra funzionare come si descrive quando l'utente passa in un buffer. In effetti, sto vedendo un sacco di tempo della CPU speso in glTexImage2D in questo percorso di esecuzione. – MoDJ