2013-02-11 12 views
5

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

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

ढांचे को हमारे (कंपनी के) नवीनतम उत्पाद में एकीकृत किया जाना है जो डेस्कटॉप और लैपटॉप के लिए एक डब्ल्यूपीएफ एप्लीकेशन है।

इसलिए मैंने वास्तव में ज्यामिति केवल प्रस्तुत करने के लिए WPF चुना है; दृश्यता और ऑक्लूजन कूलिंग स्वयं के साथ-साथ इनपुट हैंडलिंग (माउस पिकिंग), कैमरे को ले जाने, आदि ..

रीयल-टाइम एप्लिकेशन होने के कारण, इसे कम से कम 30 एफपीएस प्राप्त करने की आवश्यकता है। छवियों को प्रतिपादित करते समय ढांचा पर्याप्त प्रदर्शन करता है: मैं बिना किसी समस्या के प्रति फ्रेम कई हजार बिटमैप्स खींच सकता हूं, हालांकि पॉलीओनल डेटा एक बड़ी समस्या साबित होता है।

वास्तविक प्रश्न मैं WPF का उपयोग कर पॉलीलाइन और बहुभुज डेटा की मेरी काफी मात्रा में प्रतिपादन कर रहा हूँ, विशेष रूप से DrawingContext और StreamGeometry का उपयोग कर। मेरी समझ अब तक है कि अगर मुझे प्रदर्शन की ज़रूरत है तो यह तरीका है। हालांकि मैं उन परिणामों को प्राप्त करने में सक्षम नहीं हूं जिनसे मुझे उम्मीद थी।

यह कैसे मैं वास्तविक डेटा के साथ StreamGeometry भरने है:

using (StreamGeometryContext ctx = Geometry.Open()) 
{ 
     foreach (var segment in segments) 
    { 
     var first = ToWpf(segment[0]); 
     ctx.BeginFigure(first, false, false); 

     // Skip the first point, obviously 
     List<Point> points = segment.Skip(1).Select(ToWpf).ToList(); 
     ctx.PolyLineTo(points, true, false); 
    } 
} 
    Geometry.Freeze(); 

और यह कैसे मैं अपने ज्यामिति आकर्षित है:

_dc.PushTransform(_mercatorToView); 
_dc.DrawGeometry(null, _pen, polyline); 
_dc.Pop(); 

एक परीक्षण के रूप में, मैं में OpenStreetMap से ESRI आकार लोड मेरी अपने प्रदर्शन का परीक्षण करने के लिए आवेदन, हालांकि मैं बिल्कुल संतुष्ट नहीं हूं: मेरा परीक्षण डेटा कुल ~ 20k लाइनों के साथ ~ 3500 लाइन सेगमेंट होता है।

प्रत्येक सेगमेंट को अपने स्वयं के स्ट्रीमगेटोमेट्री में मैप करना बेहद खराब प्रदर्शन करता है, लेकिन मुझे उम्मीद है कि पहले से ही: रेंडरिंग में लगभग 14 सेकंड लगते हैं।

मैंने कई आंकड़ों का उपयोग करके, उसी स्ट्रीमगोमेट्री में अधिक सेगमेंट पैक करने का प्रयास किया है: 80 स्ट्रीमगेटोमेट्री, रेंडरिंग लगभग 50ms लेता है।

हालांकि मुझे इससे बेहतर परिणाम नहीं मिल सकते हैं। लगभग 100k तक लाइनों की मात्रा में वृद्धि करने से मेरा आवेदन लगभग अनुपयोगी हो जाता है: प्रतिपादन 100ms से अधिक लेता है। वेक्टर डेटा को प्रस्तुत करते समय ज्यामिति के साथ-साथ पेन दोनों को ठंडा करने के अलावा मैं और क्या कर सकता हूं?

मैं उस बिंदु पर हूं जहां मैं अपने लिए डब्ल्यूपीएफ पर भरोसा करने के बजाय डायरेक्टएक्स का उपयोग करना चाहता हूं क्योंकि ऐसा लगता है कि कुछ गलत हो रहा है।

संपादित

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

* क्षमा करें, लेकिन मैं पहले वास्तविक उत्पाद जारी किया गया है इस का एक वीडियो अपलोड नहीं करना चाहिए। हालांकि आप Google मानचित्र की तरह कुछ कल्पना कर सकते हैं, हालांकि वेक्टर डेटा (बहुभुज और पॉलीलाइन) के साथ। *

वहाँ दो समाधान, है, जिनमें से एक बहुत बार कहा गया हैं:

कैश भारी चित्र एक बिटमैप

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

दूसरा "समस्या" ज़ूमिंग से संबंधित है। हालांकि यह वास्तविक समस्या की तुलना में एक दृश्य आर्टिफैक्ट का अधिक है: चूंकि कैश किए गए बिटमैप को 30 एफपीएस पर ठीक से अपडेट नहीं किया जा सकता है, इसलिए मुझे ज़ूम करने पर भी इससे बचने की ज़रूरत है। मैं बहुत अच्छी तरह से बिटमैप पैमाने पर हो सकता है, जूमिंग के समय केवल एक नया बिटमैप बनाते समय ज़ूम समाप्त हो जाती है, फिर भी पोलीलाइंस की चौड़ाई एक निरंतर मोटाई नहींहैं, हालांकि वे ऐसा करना चाहिए।

यह दृष्टिकोण, मैपसूचना द्वारा इस्तेमाल किया जा प्रतीत होता है लेकिन मैं नहीं कह सकता मैं इसके बारे में बहुत शौकीन हूँ। हालांकि यह लागू करने के लिए सबसे आसान प्रतीत होता है। रेखाचित्र बनाने के विभिन्न दृश्यों

यह दृष्टिकोण में

स्प्लिट ज्यामिति अप अलग ढंग से समस्या से निपटने के लिए लगता है। मुझे यकीन नहीं है कि यह दृष्टिकोण बिल्कुल काम करता है: यह इस बात पर निर्भर करता है कि क्या मैं सही ढंग से समझता हूं कि इस क्षेत्र में डब्ल्यूपीएफ को कैसे काम करना है। इसके बजाय सब सामान तैयार करने की जरूरत है कि के लिए एक DrawingVisual का उपयोग कर के, मैं, कई का उपयोग करना चाहिए ताकि नहीं हर एक RenderOpened होने की जरूरत है()। मैं बस पैरामीटर बदल सकता हूं, उदाहरण के लिए ऊपर दिए गए नमूने में मैट्रिक्स, दोनों कैमरे पैनिंग और मूविंग को प्रतिबिंबित करने के लिए। हालांकि मैं इस दृष्टिकोण के साथ कुछ समस्याओं के साथ-साथ देखें: कैमरा पैन करना अनिवार्य रूप से व्यूपोर्ट में नए ज्यामिति लाएगा, इसलिए मैं, पहले दृष्टिकोण की तुलना में कुछ इसी तरह प्रदर्शन करने के लिए वास्तव में सामान जो वर्तमान में दिखाई नहीं देता है प्रस्तुत करना की आवश्यकता होगी, लेकिन हो सकता है कैमरा स्थानांतरण के कारण दृश्यमान; सबकुछ खींचना सवाल से बाहर है क्योंकि यह थोड़ी सी मात्रा में डेटा के लिए हास्यास्पद मात्रा ले सकता है।

दोनों से संबंधित समस्या एक बड़ी समस्या है जो इन दृष्टिकोण हल कर सकते हैं न कि समग्र फ्रेम दर स्थिर है, भले ही, कभी hickups, या तो कैश की गई बिटमैप्स को अपडेट करते समय (ठीक है, यह नहीं करता है दृष्टिकोण कैश किए गए बिटमैप को तब अपडेट किया जाता है जब कैमरे को अब पैन नहीं किया जाता है) या ज्यामिति के दृश्यमान हिस्से को खींचने के लिए रेंडर ओपन को कॉल करना अनिवार्य प्रतीत होता है।

मेरे विचार अब तक

चूंकि इन केवल दो समाधान मैंने कभी इस समस्या का देख रहे हैं (मैं अपने उचित हिस्सा एक वर्ष से अधिक के लिए googling के किया है), मैं एकमात्र समाधान ऐसा लगता व्यूपोर्ट में देरी अद्यतन करने के मामले में (यदि उस समय बिटकमैप केवल तभी अपडेट किया जाता है जब व्यूपोर्ट न हो तो सबसे शक्तिशाली जीपीयू (जो प्रति सेकंड लाखों प्राइमेटिव्स को रास्टराइज करने में सक्षम होना चाहिए) पर फ्रेम दर हिकअप स्वीकार करना है। लंबे समय तक चले गए) या WPF का उपयोग न करें और सीधे डायरेक्टएक्स का सहारा लें।

मैं मदद के लिए बहुत खुश हूँ, फिर भी मैं नहीं कह सकता मैं प्रदर्शन प्रतिपादन अब तक WPFs से प्रभावित हूँ।

+0

पोलीलाइंस वास्तव में, हर फ्रेम पर बदल दें ताकि वे दोबारा बनाई जा करने के लिए है? यदि नहीं, तो 'MercatorToView' ट्रांसफॉर्म को अपडेट करने के लिए पर्याप्त होगा। – Clemens

+0

पॉलिलाइन हर फ्रेम बदल सकते हैं, लेकिन वर्तमान में वे नहीं करते हैं। हालांकि मेरे चित्र के अन्य भाग बहुत बार बदलते हैं, इसलिए मैं सबकुछ फिर से कर रहा हूं। क्या आप मेरे ड्राइंग को अलग-अलग DrawingContexts में विभाजित करने के लिए बुद्धिमान होना चाहते हैं, प्रत्येक आवश्यक होने पर केवल तभी प्रतिपादन करते हैं जबकि अन्यथा केवल पैरामीटर अपडेट करते हैं, foR उदाहरण matrices, लेकिन नए ड्राइंग आदेश जारी नहीं करते हैं? – Simon

+0

आपको हमेशा जितना संभव हो उतना चित्र खींचने की कोशिश करनी चाहिए। यदि कई अन्य चित्रों की तुलना में बहुत अधिक आवृत्ति के साथ केवल कुछ चित्र बदल रहे हैं, तो आप कई अपरिवर्तित चित्रों को अक्सर दोबारा हटाने के साथ समय बर्बाद कर देंगे। और आपके कोड नमूने में यह न केवल StreamGeometry को दोबारा शुरू कर रहा है, बल्कि आपके 'ToWpf' विधि पर लगातार कॉल करके पॉलीलाइन डेटा को फिर से बना रहा है। इसमें कुछ समय लगता है। – Clemens

उत्तर

2

2 डी WPF प्रतिपादन प्रदर्शन को बेहतर बनाने के लिए आप (WPF> = 3.5) या BitmapCache कक्षा (WPF> = 4 के लिए) पर एक नज़र डाल सकते हैं।

उन वर्गों Cached Composition

के लिए उपयोग किया जाता है MSDN से:

नई BitmapCache और BitmapCacheBrush कक्षाओं का उपयोग करके आप एक बिटमैप के रूप में दृश्य पेड़ की एक जटिल हिस्सा कैश और बहुत प्रतिपादन समय सुधार कर सकते हैं । बिटमैप उपयोगकर्ता इनपुट के लिए उत्तरदायी बना रहता है, जैसे कि माउस क्लिक, और आप इसे किसी भी ब्रश की तरह अन्य तत्वों पर पेंट कर सकते हैं।

+0

, आप उन सुझावों के लिए। बहुत सारी ज्यामिति ड्राइंग करते समय कैशिंग का उपयोग करना संभव हो सकता है, हालांकि मैं इस विकल्प से संतुष्ट नहीं हूं क्योंकि मैं समझ नहीं पा रहा हूं कि डब्ल्यूपीएफ क्या करता है, कि कुछ लाइनें प्रस्तुत करने में इतना समय लगता है। यहां तक ​​कि यदि वे सीपीयू पर कशेरुक और इंडेक्स बफर बनाते हैं (पेन चौड़ाई के लिए wrt) और उन्हें प्रत्येक फ्रेम वीडियो मेमोरी पर अपलोड करें, जो केवल 20k लाइन-सेगमेंट के लिए 50 एमएस नहीं लेना चाहिए। एक बार जब मैं घर पर हूं, तो मैं एप्लिकेशन का एक वीडियो अपलोड करेगा, जिसे यह भी स्पष्ट करना चाहिए कि मैं कैश किए गए बिटमैप का उपयोग करने से संतुष्ट क्यों नहीं हूं। – Simon

+0

Klaus78, तुम मेरे स्वाद हो! बहुत बहुत धन्यवाद।मुझे डब्ल्यूपीएफ बहुभुज की धीमी प्रतिपादन के साथ जूझ रहा है (मेरे पास लाखों से 100,000 हैं)। प्रतिपादन के बाद, स्क्रॉल, पैन और ज़ूम करने के लिए यह बहुत सुस्त है। उल्लेख नहीं है कि मुझे ऑब्जेक्ट को खींचने, स्केल करने, घूमने और स्कू करने की भी आवश्यकता है। मैंने एनवीडिया क्वार्ड्रो के 2200 इंस्टॉल करने का प्रयास किया है लेकिन इसमें काफी सुधार नहीं हुआ है। इसका कारण यह है कि डब्ल्यूपीएफ केवल ऑनरेंडर के दौरान जीपीयू (इसकी पूरी ताकत का 20%) का उपयोग करता है। जब पैन, ज़ूम, स्क्रॉल, आदि, GPU 0% है। बिटमैप कैश द्वारा UIElement जिसमें इन बहुभुज हैं, ये समस्या दूर हो जाती है। –

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