2010-07-29 18 views
7

मेरे पास एक कक्षा है जो घन खींचती है और घूमती है। हर बार जब मैं घन घुमाता हूं तो मैं घन के लिए नए मानों के साथ बफर को फिर से लोड करता हूं।क्यूब ड्राइंग करते समय आउटऑफमेमरी अपवाद

public void LoadBuffer(GraphicsDevice graphicsDevice) 
    { 
     buffer = new VertexBuffer(graphicsDevice, VertexPositionNormalTexture.VertexDeclaration, triangles * 3, BufferUsage.None); 
     buffer.SetData<VertexPositionNormalTexture>(verts); 
     graphicsDevice.SetVertexBuffer(buffer); 
    } 

    public void Draw(GraphicsDevice graphicsDevice) 
    { 
     graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, triangles); 
    } 

तो कुछ मिनटों के बाद Game.Draw

protected override void Draw(GameTime gameTime) 
    { 
     GraphicsDevice.Clear(ClearOptions.DepthBuffer | ClearOptions.Target, Color.White, 1f, 0); 

     basicEffect.Parameters["WorldViewProj"].SetValue(world * view * projection); 

     EffectPass pass = basicEffect.CurrentTechnique.Passes[0]; 
     if (pass != null) 
     { 
      pass.Apply(); 
      cube1.LoadBuffer(GraphicsDevice); 
      cube1.Draw(GraphicsDevice); 
      cube2.LoadBuffer(GraphicsDevice); 
      cube2.Draw(GraphicsDevice); 
      cube3.LoadBuffer(GraphicsDevice); 
      cube3.Draw(GraphicsDevice); 
     } 
     base.Draw(gameTime); 
    } 

में Cube.Draw विधि कॉल या तो मैं लाइन पर एक OutOfMemory अपवाद प्राप्त करें:

buffer.SetData<VertexPositionNormalTexture>(verts); 

सकता है किसी को कृपया बताएं कि यह क्यों हो रहा है और मैं इसे हल करने के लिए क्या कर सकता हूं।

+0

हाय , @harryovers, क्या आपको इस तरह के "बग" के साथ एक काम मिल गया, मुझे एक्सएनए चुनने में बहुत दुःख हुआ। –

+0

@DuSijun मुझे यह काम करने के लिए मिला लेकिन यह 2 था।5 साल पहले तो मुझे खेद है कि मुझे इसके बारे में अधिक जानकारी याद नहीं है। – harryovers

उत्तर

8

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

मैं my answer to this question में XNA में अप्रबंधित संसाधनों के बारे में अधिक बात करते हैं।

आप पर प्रत्येक VertexBuffer पर इसे रिसा करने से पहले कॉल कर सकते हैं (लेकिन ड्राइंग के बाद, क्योंकि यह अभी भी उपयोग में होगा!), अप्रबंधित संसाधनों को रिलीज़ करने के लिए। यह स्मृति त्रुटि से बाहर निकल जाएगा, लेकिन अभी भी बहुत धीमा हो जाएगा!

आपको वास्तव में क्या करना चाहिए, न्यूनतम आवश्यक वर्टेक्स बफर केवल एक बार बना रहा है। ऐसा करने के लिए आदर्श स्थान आपके LoadContent फ़ंक्शन में है (और फिर Dispose() उन्हें UnloadContent फ़ंक्शन में)। यदि आपके पास क्यूब्स का पूरा गुच्छा है, तो आपको केवल एक कशेरुक बफर है जो एक घन का वर्णन करता है, जिसे आप हर बार घन खींचते समय पुन: उपयोग करते हैं।

जाहिर है आप एक ही स्थान में अपने सभी क्यूब्स आकर्षित करने के लिए नहीं करना चाहती। यह विश्व मैट्रिक्स के लिए है। प्रत्येक बार जब आप घन खींचते हैं, तो BasicEffect.World को उस घन के लिए अपने रूपांतरण मैट्रिक्स पर सेट करें और Apply() पर कॉल करें।

(जिस तरह से आप WorldViewProj सीधे सेट कर रहे हैं, भी ठीक है। लेकिन अच्छा एपीआई का उपयोग कर, अच्छी तरह से है अच्छे।)

तो रोटेशन आप क्या चाहते है, Matrix.CreateFromYawPitchRoll(yaw, pitch, roll) का उपयोग अपने परिवर्तन मैट्रिक्स बनाने के लिए।

इसके बारे में अधिक जानकारी के लिए, आपकी समस्या another question I have answered के समान है।

(कि ध्यान दें, यदि कोने खुद को वास्तव में परिवर्तन प्रत्येक फ्रेम करते हैं, आप DrawUserPrimitives उपयोग करना चाहिए। लेकिन ध्यान दें कि यह अभी भी काफी GPU पर शिखर शेडर दे किसी भी परिवर्तनों को संभालने की तुलना में धीमी है।)

0

ऐसा लगता है कि आप एक नया शिखर बफर हर फ्रेम बना रहे हैं और पुराने एक दायरे से बाहर गिर कचरा एकत्र करने की अनुमति नहीं दे रहा है। वास्तव में आप अपने प्रत्येक क्यूब्स के लिए यह कर रहे हैं।

एक बेहतर दृष्टिकोण सिर्फ शिखर मूल्यों प्रत्येक फ्रेम अद्यतन करने के लिए हो सकता है, या बेहतर अभी भी घन प्रत्येक फ्रेम पर बदलने अद्यतन करें।

+0

प्रत्येक बफर के सभी संदर्भ हटा दिए जाते हैं, इसलिए मैं तर्क दूंगा कि अगर कचरा कलेक्टर कोई अच्छा था तो पुराने पुराने लंबे समय तक इस्तेमाल किए गए बफर को हटाना चाहिए। ऐसा नहीं है कि पुराने बफर को किसी सूची या किसी चीज़ में संग्रहीत किया जा रहा है। क्या मै गलत हु? किसी भी मामले में यह निश्चित रूप से जाने का तरीका नहीं है, क्योंकि बार-बार आवंटन और विलोपन बहुत अक्षम है, जैसा कि "नया वर्टेक्सबफर" द्वारा प्रत्येक कॉल के साथ लोडबफर को क्रियान्वित किया जाता है। – Ricket

+0

@Ricket - बार-बार आवंटन वह चीज थी जिसने मुझे मारा, और इसके विपरीत कोई सबूत नहीं है कि इस विचार को खुद को उधार दिया जाता है कि पुराना बफर मुक्त नहीं किया जा रहा है। – ChrisF

+0

@ जीसी को रद्द करें कशेरुक बफर का समर्थन करने वाले अप्रबंधित संसाधनों के बारे में नहीं पता। यही कारण है कि ऐसा लगता है कि इसमें स्मृति की ऊन है, जब ऐसा नहीं होता है। –

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