2009-08-10 12 views
18

ओपनजीएल ईएस रेंडरिंग लूप को मेरे आईफोन एप्लिकेशन में एक अलग थ्रेड पर रखा गया है। सब कुछ ठीक हो जाता है सिवाय इसके कि EAGLContext की वर्तमान रेंडरबफर विधि विफल हो जाती है। नतीजा एक खाली सफेद स्क्रीन है। जब एक ही कोड मुख्य थ्रेड पर चलाया जाता है, तो वर्तमान रेंडरबफर सफल होता है और ग्राफिक्स ठीक से दिखाया जाता है। ओपनजीएल को एक अलग धागे पर करने का सही तरीका क्या है?आईफोन पर एक अलग थ्रेड पर OpenGL ES का उपयोग कैसे करें?

उत्तर

14

आपको EAGLSharegroup बनाने की आवश्यकता है।

धागे के बीच ओपनजीएल संदर्भ साझा करने पर this thread देखें।

अद्यतन
iOS5 करने के लिए पिछला मैं डिस्क से बनावट के अतुल्यकालिक लदान करने के लिए धागे के बीच ओपन संदर्भों साझा की है। लेकिन आईओएस 5 के CVOpenGLESTextureCaches अनिवार्य रूप से बनावट अपलोड मुक्त कर देते हैं इसलिए मुझे अब शेयर समूह की आवश्यकता नहीं है और मेरा कोड सरल और तेज़ है।

+1

"बनावट अपलोड मुक्त" से आपका क्या मतलब है? मैंने CVPpenelBufferCreateWithBytes() से परिणामस्वरूप CVOpenGLESTextureCacheCreateTextureFromImage() को कॉल करने का प्रयास किया और यह glTexImage2D() के साथ बनावट को अपलोड करने तक ही लिया। – MoDJ

+0

glTexImage2D एक बनावट में memcpy के बराबर करता है जबकि TextureFromImage आपकी छवि पर बनावट को इंगित करता है - कोई प्रति आवश्यक नहीं है। आप बहुत मेमोरी बैंडविड्थ बचा सकते हैं। अकेले समय में उतना खुलासा नहीं होगा जितना जीएल असीमित है। आपको GPU/CPU उपयोग और फ्रेम दर को देखने की आवश्यकता है। –

+0

http://stackoverflow.com/questions/12813442/cvopenglestexturecache-vs-gltexsubimage2d-on-ios देखें, यह उपयोगकर्ता द्वारा बफर में गुजरने के तरीके का वर्णन करने जैसा प्रतीत नहीं होता है। असल में, मैं इस निष्पादन पथ में glTexImage2D में बिताए गए बहुत सारे CPU समय को देख रहा हूं। – MoDJ

2

आपको संदर्भ को एक अलग थ्रेड पर प्रस्तुत नहीं करना चाहिए। इसके बजाय, एक अलग थ्रेड पर सभी गणना करें, और फिर सुनिश्चित करें कि मुख्य प्रदर्शन थ्रेड पर प्रतिपादन होता है।

+0

आप यह वाकई आसानी से GCD उपयोग कर सकते हैं:

यहाँ बॉयलरप्लेट कोड है। – Cthutu

13

धन्यवाद, फिस्टमैन। मैंने इसे काम किया और प्रदर्शन लाभ प्राप्त किया जो मुझे एक अलग थ्रेड का उपयोग करने की उम्मीद थी। ईएजीएलशेयर समूह ने समस्या हल की।

मैंने here वर्णित दूसरे धागे के लिए संदर्भ बनाया।


#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"); 
    } 
} 


संबंधित मुद्दे