2014-10-02 11 views
14

मैं एक खिड़की पर डबल-बफर किए गए जीडीआई का उपयोग करके एक एनीमेशन ड्राइंग कर रहा हूं, एक सिस्टम पर जहां डीडब्लूएम संरचना सक्षम है, और स्पष्ट रूप से tearing ऑनस्क्रीन दिखाई दे रही है। क्या इसको रोकने के लिए कोई रास्ता है?डीडब्लूएम संरचना के साथ एक खिड़की पर जीडीआई का उपयोग करते समय ड्राइंग कलाकृतियों को रोकने के लिए संभव है?

विवरण

एनीमेशन एक ही छवि लेता है, और यह सही स्क्रीन पर छोड़ दिया करने के लिए ले जाता है; के साथ timeGetTime का उपयोग करके, पूरे समय की चौड़ाई पर लागू होने वाले अंश को पूरा करने के लिए, वर्तमान समय और अंतराल के समय के अंतराल के बीच अंतर के आधार पर पिक्सेल की संख्या निर्धारित होती है। एनीमेशन अनुप्रयोग संदेशों को संसाधित किए बिना लूप में खींचता है; यह (VCL लाइब्रेरी) विधि Repaint को कॉल करता है जो आंतरिक रूप से अमान्य करता है और फिर UpdateWindow को विंडो में प्रश्न के लिए कॉल करता है, सीधे WM_PAINT के साथ संदेश प्रक्रिया में कॉल करता है। पेंट हैंडलर का वीसीएल कार्यान्वयन BeginBufferedPaint का उपयोग करता है। चित्रकारी खुद को डबल-बफर किया गया है।

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

एनीमेशन देखते समय, स्पष्ट रूप से tearing दिखाई देता है। यह विभिन्न ग्राफिक्स कार्ड के साथ कई सिस्टम पर विंडोज विस्टा, 7 और 8.1 पर होता है।

इसे संभालने का मेरा दृष्टिकोण उस दर को कम करने के लिए किया गया है जिस पर यह चित्रित हो रहा है, या फिर चित्रकला से पहले वीएसआईएनसी की प्रतीक्षा करने का प्रयास किया गया है। यह गलत दृष्टिकोण हो सकता है, इसलिए इस प्रश्न का उत्तर "कुछ और पूरी तरह से करें: एक्स" हो सकता है। यदि ऐसा है तो महान, :)

(क्या मैं सच में करना चाहते हैं/इस विशिष्ट विंडो के लिए केवल पूरी तरह से चित्रित फ्रेम का इस्तेमाल रचना करने DWM पूछने के लिए एक तरीका है।)

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

प्रयास करने की कोशिश की:

  • GetDeviceCaps(Application.MainForm.Handle, VREFRESH) के माध्यम से नजर रखने के ताज़ा दर हो रही है; 1/ताज़ा दर मिलीसेकंड के लिए सो रहा है। जितनी जल्दी हो सके पेंटिंग पर थोड़ा सुधार हुआ, लेकिन इच्छापूर्ण सोच हो सकती है। संकल्पनात्मक रूप से थोड़ा कम चिकनी एनीमेशन दर। (बदलाव: सामान्य Sleep और एक उच्च संकल्प timeGetTime का उपयोग कर स्पिन प्रतीक्षा करें।)

  • एक ही दर, जिस पर कोड ड्रॉ करने के लिए अद्यतन करने को सीमित करने की कोशिश करने के DwmSetPresentParameters का उपयोग करना। (विविधताएं: बफर के बहुत सारे (cBuffer = 8) (कोई दृश्य प्रभाव नहीं); मॉनिटर रीफ्रेश दर/1 की स्रोत दर निर्दिष्ट करना और उपरोक्त कोड (जैसे नींद के दृष्टिकोण की कोशिश करने के समान) का उपयोग करके सोना; प्रति फ्रेम रीफ्रेश निर्दिष्ट करना 1, 10, आदि (कोई दृश्य प्रभाव नहीं); स्रोत फ्रेम कवरेज बदलना (कोई दृश्य प्रभाव नहीं।)

  • विभिन्न तरीकों से में DwmGetCompositionTimingInfo का उपयोग करना:

      • जबकि cFramesPending> 0, स्पिन;
      • cFrame (फ्रेम बना) और स्पिन जाओ, जबकि इस नंबर को बदल नहीं करता है;
      • cFrameDisplayed और स्पिन जाओ, जबकि इस परिवर्तन नहीं करता है;
      • qpcVBlank + qpcRefreshPeriod जोड़कर एक समय के लिए सोने के लिए गिना जा रहा है, और फिर थोड़ी देर QueryPerformanceCounter एक समय यह कम से कम, स्पिन रिटर्न
  • इन सभी दृष्टिकोण भी पेंटिंग से अलग कर दिया गया है , फिर पेंटिंग से पहले कताई/सोना; या उल्टा: सोना और फिर पेंटिंग।

कुछ ऐसा दिखाई देने वाला प्रभाव प्रतीत होता है और योग्यता प्राप्त करने के लिए मुश्किल क्या है और केवल निम्न फ्रेम दर का परिणाम हो सकता है। कोई भी फाड़ने से नहीं रोकता है, यानी कोई भी डीडब्लूएम खिड़की के डीसी की सामग्री की "पूरी" प्रतिलिपि के साथ खिड़की बना देता है।

सलाह की सराहना की :)

+1

जीडीआई पुराना और क्रिस्टी है और एनीमेशन चिकनी नहीं है। शायद Direct2D आज़माएं? –

+1

@ जोनाथनपोटर अच्छा बिंदु। मेरी बाधाओं में से एक है किसी भी प्रकार के डीएक्स का उपयोग नहीं करना - एक कारण प्लेटफार्मों की संख्या और आवश्यकताओं की कमी है, अंतिम कोड को चलाने की जरूरत है। (सभी आधुनिक विंडोज नहीं हैं।) शायद एरो मौजूद होने पर सहायक डीएक्स कोड ...? हालांकि, इसे बिना किसी दृश्य ग्लिच के जीडीआई/डीएक्स पर स्विच करना होगा, क्योंकि यह एनीमेशन चालू/बंद करता है। क्या यह संभव है? –

+0

हो सकता है कि आप एक ड्रॉइंग हेल्पर क्लास लिख सकें जो उपलब्ध होने पर डीएक्स का उपयोग करता है और अन्यथा जीडीआई पर वापस आ जाता है। यह एक ऐसा सिस्टम ढूंढना बहुत दुर्लभ होगा जो डायरेक्ट 3 डी का समर्थन नहीं करता है, भले ही डी 2 डी न हो। –

उत्तर

2

जब से तुम BitBlt उपयोग कर रहे हैं, सुनिश्चित करें कि आपके झलक 4-बाइट/पिक्सेल कर रहे हैं। 3 बाइट्स/पिक्सेल के साथ, जीडीआई बहुत धीमी है जबकि डीडब्लूएम चल रहा है, यह आपके फाड़ने का स्रोत हो सकता है। एक और BitBlt मुद्दा जो मैंने चलाया है, यदि आपका डीआईबी BitBlt कॉल की तुलना में कुछ हद तक बड़ा है, तो अप्रत्याशित रूप से लंबा समय लगता है। यदि आप डेटा के एक हिस्से को आकर्षित करने के बजाय एक कॉल को छोटी कॉल में विभाजित करते हैं, तो इससे मदद मिल सकती है। इन दोनों वस्तुओं ने मुझे अपने मामले के लिए मदद की, केवल इसलिए कि BitBlt स्वयं बहुत धीमी गति से चल रहा था, इस प्रकार वीडियो कलाकृतियों की ओर अग्रसर था।

+0

बस जोड़ने के मामले में: पूरी खिड़की के बजाय केवल गंदा आय (GetUpdateRect) को अपडेट करना न भूलें ... – Jurlie

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

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