2013-02-28 7 views
6

के साथ कस्टम आईओएस इंटरफेस अभिविन्यास परिवर्तन एनीमेशन मेरे पास एक आईपैड ऐप है और ओपनजीएल के साथ मुख्य दृश्य खींच रहा हूं और डिवाइस घुमाए जाने पर मैं अपना खुद का परिवर्तन एनिमेट करना चाहता हूं।ओपनजीएल

ध्यान दें कि यह ऐप केवल कभी-कभी आकर्षित होता है, यह लगातार एनिमेट नहीं होता है। इसके अलावा मेरा दृश्य एक (बहुत जटिल) 2 डी ड्राइंग है, न कि 3 डी। मैं सिर्फ डिवाइस प्रतिरोधी परिवर्तन के दौरान प्रदर्शन केंद्र के चारों ओर घूमना चाहता हूं, सही पहलू अनुपात को बनाए रखना चाहता हूं। ओपन

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 
{ 
    // nothing yet 
} 

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{ 
    IMMainView *mv = (IMMainView *)self.view; 
    [mv createRenderbuffer]; 
    [mv drawView]; 
} 

मैं सिर्फ फिर से बनाने के लिए नए चौड़ाई और ऊंचाई मैच के लिए एक बार रोटेशन पूरा करता बफर प्रस्तुत करना:

पल मैं बस निम्नलिखित कोड है पर

डिफ़ॉल्ट आईओएस व्यवहार दृश्य को घुमाता प्रतीत होता है लेकिन पहलू अनुपात में परिवर्तन के रूप में इसे अजीब रूप से फैलाता है।

मैं संक्रमण के दौरान कुछ बेहतर प्रदर्शन करने के लिए अपने ड्राइंग पैरामीटर को एनिमेट कर सकता हूं, लेकिन मुझे समझ में नहीं आता है (1) आईओएस को मेरी परत को एनिमेट करने से कैसे रोकें और (2) इन विधि कॉल से एनीमेशन लूप कैसे सेट करें जो आईओएस एनीमेशन से मेल खाता है।

उदाहरण के लिए, एनीमेशन के दौरान, वास्तविक दृश्य चौड़ाई और ऊंचाई क्रमशः बदल रही है?

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

किसी भी मदद की सराहना की जाएगी।

+0

ठीक है मुझे लगता है कि मैं अपने प्रश्न के उत्तर का हिस्सा समझता हूं, अर्थात् मुझे डिफ़ॉल्ट मामले में दिखाए गए ओवर-राइड पर अभिविन्यास परिवर्तन के दौरान रेंडर बफर प्रस्तुत करना होगा। फिलहाल मैं केवल तब प्रस्तुत करता हूं जब मुझे यूआई परिवर्तन के आधार पर दृश्य सामग्री को बदलने की आवश्यकता होती है। – Robotbugs

उत्तर

3

मैंने कुछ समय सही तरीके से करने के उचित तरीकों की तलाश में बिताया है और willRotateToInterfaceOrientation पर स्क्रीन को साफ़ करने के लिए और फिर didRotateFromInterfaceOrientation में सही जगह पर नई सामग्री प्रस्तुत करने के लिए सबसे सरल मार्ग तक पहुंच गया है। यह इतना बुरा नहीं लग रहा है और कुछ बेहतर के लिए अतिरिक्त जटिलता आईएमएचओ के लायक नहीं है।

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 
{ 
    IMMainView *mv = (IMMainView *)self.view; 
    [mv drawBlankScreen]; 

    m_oldviewsize = self.view.bounds.size; 
} 

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration 
{ 
    IMMainView *mv = (IMMainView *)self.view; 

    CGPoint neworigin = mv.origin; 

    neworigin.x += 0.5f*(self.view.bounds.size.width - m_oldviewsize.width); 
    neworigin.y += 0.5f*(self.view.bounds.size.height - m_oldviewsize.height); 

    mv.origin = neworigin; 

    [mv createRenderbuffer]; 
    [mv drawView]; 
} 

मूल के परिवर्तन फिर से करने का इरादा है:

वैकल्पिक रूप से, जबकि मैं इस समाधान, एनीमेशन है कि मैं बहुत ज्यादा नहीं काम के साथ प्राप्त के साथ सबसे अच्छा परिणाम के लिए जाना नहीं था कुछ इस तरह था घूर्णन से पहले उसी स्थान पर पोस्ट-रोटेटेड ड्राइंग को केंद्र दें।

मैंने पाया कि willAnimateToInterfaceOrientation को नए दृश्य सीमाओं की गणना के बाद एक बार बुलाया जाता है। इसलिए मैंने उस बिंदु पर नया रेंडरबफर स्थापित किया क्योंकि पहलू परिवर्तन से जुड़े विकृति मेरे मूल मामले के रूप में काफी ध्यान देने योग्य नहीं है। मुझे willRotateToInterfaceOrientation में स्क्रीन को भी साफ़ करना पड़ा क्योंकि वहां एक देरी है जिसके दौरान मूल ड्राइंग का विकृत संस्करण स्पष्ट रूप से दिखाई देता है।

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

0

आप इस प्रकार शिखर शेडर में ओपन उत्पादन बारी बारी से कर सकते हैं: प्रत्येक VSync साथ

#version 300 es 


in vec4 position; 
in mediump vec4 texturecoordinate; 

in vec4 color; 

uniform float preferredRotation; 

out mediump vec2 coordinate; 

void main() 
{ 
    //const float pi = 4.0 * atan(1.0); 
    //float radians = ((-90.0)/180.0 * pi); 

    // Preferred rotation of video acquired, for example, by: 
    // AVAssetTrack *videoTrack = [tracks objectAtIndex:0]; 
    // CGAffineTransform preferredTransform = [videoTrack preferredTransform]; 
    // self.glKitView.preferredRotation = -1 * atan2(preferredTransform.b, preferredTransform.a); 

    // Preferred rotation for both portrait and landscape   
    mat4 rotationMatrix = mat4(cos(preferredRotation), -sin(preferredRotation), 0.0, 0.0, 
           sin(preferredRotation), cos(preferredRotation), 0.0, 0.0, 
           0.0,      0.0,     1.0, 0.0, 
           0.0,      0.0,     0.0, 1.0); 

    // Mirror vertical (portrait only) 
    mat4 rotationMatrix = mat4(cos(preferredRotation), sin(preferredRotation), 0.0, 0.0, 
           -sin(preferredRotation), cos(preferredRotation), 0.0, 0.0, 
           0.0,   0.0,   1.0, 0.0, 
           0.0,   0.0,   0.0, 1.0); 

    // Mirror horizontal (landscape only) 
    mat4 rotationMatrix = mat4(1.0, 0.0,      0.0,     0.0, 
           0.0, cos(preferredRotation), -sin(preferredRotation), 0.0, 
           0.0, sin(preferredRotation), cos(preferredRotation), 0.0, 
           0.0, 0.0,      0.0,     1.0); 

    // Mirror vertical (landscape only) 
    mat4 rotationMatrix = mat4(cos(preferredRotation), 0.0, sin(preferredRotation), 0.0, 
           0.0,     1.0, 0.0,     0.0, 
           -sin(preferredRotation), 0.0, cos(preferredRotation), 0.0, 
           0.0,     0.0, 0.0,     1.0); 

    gl_Position = position * rotationMatrix; 
    coordinate = texturecoordinate.xy; 
} 

, आप preferredRotation के लिए एक नया मूल्य, जो अधिक समय दिए बिना दृश्य को घुमाने होगा पारित कर सकते हैं।

जाहिर है, आप वीडियो के अभिविन्यास और उसके घूर्णन के आधार पर केवल एक मैट्रिक्स 4 चुनते हैं। प्रत्येक matrix4 वीडियो विंडो flips - इसे घुमाता नहीं है। रोटेशन के लिए, आपको पहले ओरिएंटेशन के आधार पर मैट्रिक्स 4 चुनना होगा, और उसके बाद पसंदीदा रोटेशन वैरिएबल को डिग्री की संख्या (रेडियंस में, फॉर्मूला भी प्रदान किया जाता है) के साथ प्रतिस्थापित करना होगा।

दृश्य, परत, वस्तु इत्यादि को घुमाने के कई तरीके हैं; लेकिन, यदि आप ओपनजीएल के माध्यम से एक छवि प्रस्तुत कर रहे हैं, तो आपको यह विधि चुननी चाहिए, और केवल यह विधि।