2011-10-12 10 views
18

का उपयोग करके मैं GLKit (अर्थात् एसिंक्रोनस बनावट लोडिंग और GLKView/Controller द्वारा प्रदान किया गया स्वचालन) की कुछ विशेषताओं का लाभ उठाने के लिए अपने ओपनजीएल रेंडरिंग कोड को परिवर्तित करने के लिए देख रहा हूं। हालांकि, ऐसा प्रतीत होता है कि कक्षाएं मुख्य रूप से एनीमेशन लूप का उपयोग करके प्रतिपादन करने वाले लोगों को समायोजित करने के लिए डिज़ाइन की गई हैं, जबकि मैं ऑन-डिमांड रेंडरिंग के साथ काम कर रहा हूं। इसके अतिरिक्त, कुछ प्रतिपादन GLKView के फ्रेमबफर की बजाय बनावट के लिए है, तो क्या मुझे केवल GLKView को उप-वर्गीकृत करना और अतिरिक्त एफबीओ जोड़ना चाहिए?ऑन-डिमांड ओपनजीएल ईएस प्रतिपादन जीएलकिट

क्या इस प्रकार के सेटअप के लिए कोई अनुशंसित दृष्टिकोण है? मैं की तर्ज पर कुछ उम्मीद करेंगे:

  • सेट दृश्य नियंत्रक के preferredFramesPerSecond0, या सिर्फ फ्रेम अपडेट थामने?
  • glkViewControllerUpdate या glkView:drawInRect: विधियों को अनदेखा करें और जब मुझे इसकी आवश्यकता हो, तो बस मुझे जो चाहिए, उसे खींचें।
  • उपयोग दृश्य की setNeedsDisplay एक सामान्य UIView साथ के रूप में आदेश फ्रेम प्रदर्शित करने के लिए (मैं फोन करने के लिए bindDrawable यह देखते हुए कि मैं एक बनावट के प्रतिपादन किया जाएगा और साथ ही जरूरत है?)।

शायद यह प्रयास करने योग्य नहीं है यदि यह नया एपीआई डिज़ाइन नहीं किया गया है? मेरी इच्छा है कि दस्तावेज थोड़ा अधिक गहरा था। शायद अधिक नमूने जब एपीआई 'परिपक्व' है एक छोटे से ...

धन्यवाद

+0

आप अभी भी जीएलकिट के साथ संयोजन में माध्यमिक एफबीओ को प्रस्तुत कर सकते हैं। http://mickyd.wordpress.com/2012/05/20/creating-render-to-texture-secondary-framebuffer-objects-on-ios-using-opengl-es-2/ – MickyD

उत्तर

22

जिस दृष्टिकोण का मैंने उपयोग किया, वह GLKViewController से परेशान नहीं था, लेकिन GLKView का उपयोग सीधे UIViewController सबक्लास के तहत करें।

स्पष्ट रूप से, GLKViewController उन लोगों द्वारा उपयोग के लिए लक्षित है जिन्हें गेम जैसे ऐप्स के लिए लगातार प्रतिपादन लूप की आवश्यकता होती है। इसके बिना, GLKView पर चित्रण [glkView setNeedsDisplay] पर कॉल करने जितना सरल है। इस व्यवहार को सक्षम करने के लिए enableSetNeedsDisplay से YES सेट करना सुनिश्चित करें।

आप अभी भी एक GLKViewController का उपयोग करना चाहता था, तो आप ऐसा तरह viewWillAppear में एनीमेशन प्रतिपादन पाश निष्क्रिय कर सकते हैं:

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; // setPaused automatically set to NO in super's implementation 

    [self setPaused:YES]; 
} 

इसके अलावा, NO को resumeOnDidBecomeActive सेट स्वचालित रूप से फिर से शुरू करने से देखने नियंत्रक को रोकने के लिए ।

एक सादे UIViewController एक GLKView साथ का उपयोग करते हुए हालांकि पूरी तरह से स्वीकार्य है, और मैं इसे पर मांग ड्राइंग प्रदर्शन करने के लिए एक उपयुक्त तरीका के रूप में एक एप्पल इंजीनियर द्वारा सिफारिश देखा है।

+0

यह मदद करेगा यदि आप स्पष्टीकरण दे सकते हैं कि कौन से तरीकों को सक्षम किया गया है SetNeedsDisplay और resumeOnDidBecomeActive को उल्लिखित सेट करने की आवश्यकता है, क्योंकि आपने उन्हें VisualAppear (BOOL) एनिमेटेड में नहीं रखा है। धन्यवाद। –

+0

जब आप व्यू/व्यू कंट्रोलर बनाते हैं तो इन गुणों को सेट करें। उदाहरण के लिए, यदि आप कोड में अपना 'GLKViewController' बनाते हैं, तो शायद इसे अपने' alloc'/'init' के बाद लाइन पर सेट करें। यदि आप इसे इंटरफ़ेस बिल्डर में बनाते हैं, तो अपने व्यू कंट्रोलर में '-awakeFromNib' विधि को कार्यान्वित करना इसके लिए एक अच्छी जगह हो सकता है। सामान्य रूप से, इस तरह के गुणों को ऑब्जेक्ट के निर्माण के बाद सेट किया जाना चाहिए, लेकिन इसका उपयोग करने से पहले। – Stuart

+0

क्या आपके पास इसका नमूना दिखाने वाला ओपन सोर्स कोड उपलब्ध है? धन्यवाद – aehlke

3

मैं सिर्फ एक EAGLContext प्रबंधक मैं अपने आप को GLKit वर्गों का उपयोग करने के लिए लुढ़का का उपयोग करने से मेरी कोड परिवर्तित कर दिया है प्रदान की जाएगी।

आप सुझाव देते हैं कि आप .. .. glkView:drawInRect: विधियों को हस्ताक्षर कर सकते हैं और जब मुझे इसकी आवश्यकता हो, तो बस [आपको] क्या चाहिए "खींचें। यह प्रदर्शन के अनुसार एक समझदार विकल्प की तरह लगता है; मुझे लगता है कि (हालांकि कोशिश नहीं की गई है) यदि आप बस GLKViewDelegate निर्दिष्ट नहीं करते हैं या GLKView को drawInRect: परिभाषित करते हैं तो कोई एनीमेशन पाश प्रतिपादन नहीं होगा। क्या आपने इसका प्रयास किया है?

[self setDelegate:self]; // in init or awakeFromNib or other.. 

-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect { 
    if ([self shouldUpdate]) { ... 

मुझे यकीन है कि आप विचार प्राप्त कर रहा हूँ, यह शायद ही जटिल है:

विकल्प बस अपने MyController : GLKViewController <GLKViewDelegate> कक्षा में कुछ @property (assign, nonatomic) BOOL shouldUpdate; जो केवल अद्यतन करेगा बनाने के लिए अगर वहाँ कुछ करने के लिए है हो सकता है।

उल्लेख करने योग्य एक बात: आधिकारिक एपीआई दस्तावेज़ बताते हैं कि viewDidLoad प्रारंभिक जीएल सेटअप के लिए आपके GLKViewController में उपयोग किया जाना चाहिए। मुझे इसके साथ समस्याएं थीं; किसी कारण से मेरे glCreateShader कॉल हमेशा शून्य लौटा दी। यह EAGLContext पोस्ट-प्रारंभिकरण की सेटिंग के कारण हो सकता है; मैं इसे init पैरामीटर के रूप में पास नहीं कर सका क्योंकि मैंने स्टोरीबोर्ड में नियंत्रक बनाया था। हालांकि, कोड के साथ तर्कसंगत रूप से कुछ भी गलत नहीं था, इसलिए यदि आप समान मुद्दों का सामना करते हैं तो मैं इस अनुकूल चेतावनी प्रदान करता हूं। मेरे समाधान मेरी drawInRect में निम्न होना करने के लिए है:

-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect { 
    if ([self initialGLSetupDone] == NO) { 
     [self beforeFirstRender]; 
     [self setInitialGLSetupDone:YES]; 
    } 
    // .. rest of render code goes here. 
} 

जाहिर है यह अनावश्यक रूप से वहाँ में एक यदि के लिए आदर्श नहीं है, लेकिन यह एक आसान समाधान था।

मुझे बताएं कि अगर आप जीएलकिट का उपयोग करने के लिए अद्यतन करने का प्रयास करते हैं तो यह कैसे चलता है।

+0

'viewDidLoad' के संबंध में मुद्दा, आपके शेडर्स बनाने से पहले आपका 'EAGLContext' सेट होना चाहिए, जैसा आपने स्वयं देखा था। अपने शेष जीएल कोड को सेट करने से पहले, सीधे 'viewDidLoad' में ऐसा करने में कोई हानि नहीं है। इस सेटअप को निष्पादित करने के तरीके के लिए एक अच्छा उदाहरण के लिए एक्सकोड में 'ओपनजीएल गेम' टेम्पलेट प्रोजेक्ट पर नज़र डालें। – Stuart

+0

लोच टिप के लिए धन्यवाद। CAEAGLLayer या अन्य कामकाज मैन्युअल रूप से आकर्षित करने की कोशिश करने से कहीं अधिक आसान है। –

1

के बाद आप GLKView बनाया है, इस पंक्ति जोड़ें:

glkView.enableSetNeedsDisplay = TRUE;

जब आप पुनः बनाने करना चाहते हैं (क्योंकि यह की, कोई भी स्वचालित रूप से दृश्य पुनः बनाने होगा), इस लाइन डालने:

[glkView setNeedsDisplay]; 

... फिर drawInRect दिनचर्या केवल एक बार बुलाया जाएगा।

उम्मीद है कि यह मदद करता है।

+1

-1। यह गलत है - 'सक्षम करेंडेट्सडिस्प्ले 'को' NO' ** पर सेट करना ** 'GLKView' की' setNeedsDisplay' विधि अक्षम करता है। 'GLKViewController' का उपयोग करते समय यह गुण स्वचालित रूप से' NO' पर सेट हो जाता है, और इसलिए, वास्तव में, _required_ है जिसे आपने मैन्युअल रूप से सेट YeedsDisplay "मोड" में चित्रित करते समय इसे 'YES' पर सेट किया है। – Stuart

+1

इस उत्तर को सही किया गया ... – rodamn

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