2011-08-11 29 views
5

में पिक्सेल डेटा का उपयोग कैसे यह StackOverflow पर कभी मेरा पहला सवाल है, हुर्रे है! मैं ईमानदारी से कह सकता हूं कि मैं अपने काम और व्यक्तिगत प्रोग्रामिंग रहस्य दोनों के लिए दैनिक आधार पर स्टैक ओवरव्लो का उपयोग करता हूं। 99.9% उस समय मुझे वास्तव में वह उत्तर मिलता है जिसकी मुझे आवश्यकता है, जो बहुत अच्छा है!SlimDX/DirectX9/सी # - एक बनावट

मेरे वर्तमान समस्या वास्तव में मुझे एक छोटे से स्टम्प्ड के रूप में मैं कुछ भी जो वास्तव में काम करता है नहीं कर पा रहे। मैंने गेमडेव.net पर पहले से ही कई पोस्ट पढ़ी हैं और नेट के आसपास अन्य संसाधन पाए हैं लेकिन इसे हल नहीं कर सकते हैं।

मैं XNA के लिए स्लिम डीएक्स (केवल इस समय डायरेक्टएक्स 9) के लिए लिखा गया एक छोटा 2 डी इंजन पोर्ट करने की प्रक्रिया में हूं, जो एक अच्छा कदम रहा है क्योंकि मैंने कुछ दिनों में डायरेक्टएक्स के आंतरिक कार्यों के बारे में और कुछ सीखा XNA के साथ काम करने के छह महीने में मैंने किया था। मैं अपने बुनियादी प्रतिपादन किया सुविधाओं का अधिकाधिक मिला है और वास्तव में अतिरिक्त सुविधाओं (जो मैं वास्तव में XNA में याद किया) की एक टन के साथ XNA SpriteBatch पुन: बनाने में कामयाब रहे।

आखिरी चीजों में से एक जो मैं काम करने की कोशिश कर रहा हूं, किसी दिए गए बनावट से स्रोत-आयत निकालना और टाइलिंग के लिए इसका उपयोग करना है। क्यों: जब आप सिर्फ यूवी के साथ गड़बड़ चारों ओर स्रोत आप प्रदर्शित करना चाहते प्राप्त करने के लिए कर सकते हैं खपरैल का छत नहीं (जैसे: 0.3; 0.5 करने के लिए 0.3; 0.5), लेकिन जब टाइलिंग आप टाइल (0 करने के लिए यूवी की जरूरत है; 0 2 के लिए, 2 मतलब टाइल छवियों को दो बार) और इसलिए एक कटआउट बनावट की जरूरत है।

एक लम्बी कहानी कम करने के लिए, मैं निम्नलिखित का उपयोग करने का प्रयास करें:

DataRectangle dataRectangle = sprite.Texture.LockRectangle(0, LockFlags.None); 
Format format = sprite.Texture.GetLevelDescription(0).Format; 

byte[] buffer = new byte[4]; 
dataRectangle.Data.Read(buffer, ([y] * dataRectangle.Pitch) + ([x] * 4), buffer.Length); 
texture.UnlockRectangle(0); 

मैं अलग पिक्सल की कोशिश की लेकिन सब फर्जी डेटा देने के लिए लग रहे हैं। उदाहरण के लिए, मैंने वास्तव में डेटारक्टेंगल से प्राप्त बफर को छवि में वास्तविक पिक्सेल से मेल खाने के लिए अपने वर्तमान अवतार का उपयोग करने का प्रयास किया, लेकिन कोई किस्मत नहीं है (यहां तक ​​कि अगर प्रारूप सही था, तो भी जांच की गई है)।

मैं क्या गलत कर रहा हूं? इसे करने का कोई बेहतर तरीका है? या मेरे यूवी कहानी गलत है और यह यह खपरैल का छत से पहले एक स्रोत-आयत बाहर काटने तुलना में बहुत सरल हल किया जा सकता?

अपने समय के लिए धन्यवाद,

लेनार्ड Fonteijn

अद्यतन # 1

मैं वास्तव में एक बाइट सरणी से निम्नलिखित रूपांतरण का उपयोग एक बिटमैप के लिए पिक्सेल डेटा निर्यात करने में कामयाब रहे:

int pixel = (buffer[0] & 0xFF) | ((buffer[1] & 0xFF) << 8) | ((buffer[2] & 0xFF) << 16) | ((255 - buffer[3] & 0xFF) << 24); 

तो डेटा इतना बेवकूफ प्रतीत नहीं होता जैसा मैंने सोचा था। मेरा अगला हालांकि, समस्या यह पिक्सल स्रोत आयत में निर्दिष्ट हथियाने और एक नया बनावट के लिए उन्हें कॉपी कर रहा है। जिस छवि को मैं कटौती करने की कोशिश कर रहा हूं वह 150x150 है, लेकिन किसी कारण से यह 256x256 छवि (दो की शक्ति) तक फैला हुआ है, लेकिन जब वास्तव में 150x150 से अधिक पिक्सल तक पहुंचने का प्रयास किया जाता है, तो यह आउटऑफबाउंड अपवाद फेंकता है। साथ ही, जब मैं वास्तव में आकार 256x256 का दूसरा रिक्त बनावट बनाने की कोशिश करता हूं, इससे कोई फर्क नहीं पड़ता कि मैंने इसमें क्या रखा है, यह पूरी तरह से काला हो जाता है।

यहाँ मेरे वर्तमान कोड है:

//Texture texture = 150x150 
DataRectangle dataRectangle = texture.LockRectangle(0, LockFlags.None); 
SurfaceDescription surface = texture.GetLevelDescription(0); 

Texture texture2 = new Texture(_graphicsDevice, surface.Width, surface.Height, 0, surface.Usage, surface.Format, surface.Pool); 
DataRectangle dataRectangle2 = texture2.LockRectangle(0, LockFlags.None); 

for (int k = sourceX; k < sourceHeight; k++) 
{ 
    for (int l = sourceY; l < sourceWidth; l++) 
    { 
     byte[] buffer = new byte[4]; 
     dataRectangle.Data.Seek((k * dataRectangle.Pitch) + (l* 4), SeekOrigin.Begin); 
     dataRectangle.Data.Read(buffer, 0, 4); 

     dataRectangle2.Data.Seek(((k - sourceY) * dataRectangle2.Pitch) + ((l - sourceX) * 4), SeekOrigin.Begin); 
     dataRectangle2.Data.Write(buffer, 0, 4); 
    } 
} 

sprite.Texture.UnlockRectangle(0); 
texture2.UnlockRectangle(0); 

_graphicsDevice.SetTexture(0, texture2); 

तो मेरी नई (अतिरिक्त) सवाल कर रहे हैं: मैं कैसे पिक्सल के ऊपर एक बनावट से दूसरे छोटे बनावट के लिए, अल्फा चैनल सहित स्थानांतरित कर सकते हैं? जब कोई मूल बनावट 150x150 है, तो SurfaceDescription रिपोर्ट 256x256 क्यों करती है?

+0

मैं यह वास्तव में http://gamedev.stackexchange.com के तहत तैनात किया जाना चाहिए। अगर यह सच है तो किसी भी मॉडरेटर को इसे स्थानांतरित करने के लिए स्वतंत्र महसूस करना चाहिए। –

+0

यह एक अच्छा सवाल है - और यहां विषय पर ... लेकिन हाँ, आपको वहां और सहायता मिल सकती है। – jcoder

+0

मैंने नई जानकारी के साथ प्रश्न अपडेट किया। –

उत्तर

5

यह मेरे अपने प्रश्न का उत्तर देने के लिए अजीब तरह का है, लेकिन कुछ और खुदाई और सरल परीक्षण और त्रुटि के बाद, मुझे समाधान मिला।

सबसे पहले, मुझे अपना बनावट लोड करने के तरीके को बदलना पड़ा।

Texture texture = Texture.FromFile(_graphicsDevice, [filePath], D3DX.DefaultNonPowerOf2, D3DX.DefaultNonPowerOf2, 1, Usage.None, Format.Unknown, Pool.Managed, Filter.None, Filter.None, 0); 

नोट कैसे मैं विशेष रूप से निर्दिष्ट किया है कि आकार गैर बिजली के- दो है: यह आंतरिक रूप से एक शक्ति-की-दो आकार के लिए आकार बदलने से रोकने के लिए, मैं निम्न विधि का उपयोग किया था।

अगला, मेरी नई बनावट परिभाषा में एक गलती हुई थी।

Texture texture2 = new Texture(_graphicsDevice, [sourceWidth], [sourceHeight], 1, surface.Usage, surface.Format, surface.Pool); 

किया होने के बाद, के लिए लूप मैं अपने विचाराधीन है, काम करता है: 0 के स्तर निर्दिष्ट करने के बजाय (और यह बनाने को स्वत: जनरेट एक मिपमैप), मैं इस तरह, 1 स्तर को निर्दिष्ट करने के लिए किया था ठीक है:

DataRectangle dataRectangle = texture.LockRectangle(0, LockFlags.None); 
SurfaceDescription surface = texture.GetLevelDescription(0); 

DataRectangle dataRectangle2 = texture2.LockRectangle(0, LockFlags.None); 

for (int y = [sourceX]; y < [sourceHeight]; k++) 
{ 
    for (int x = [sourceY]; x < [sourceWidth]; l++) 
    { 
     byte[] buffer = new byte[4]; 
     dataRectangle.Data.Seek((y * dataRectangle.Pitch) + (x * 4), SeekOrigin.Begin); 
     dataRectangle.Data.Read(buffer, 0, 4); 

     dataRectangle2.Data.Seek(((y - [sourceY]) * dataRectangle2.Pitch) + ((x - [sourceX]) * 4), SeekOrigin.Begin); 
     dataRectangle2.Data.Write(buffer, 0, 4); 
    } 
} 

texture.UnlockRectangle(0); 
texture2.UnlockRectangle(0); 

_graphicsDevice.SetTexture(0, texture2); 

ब्रैकेट में सब कुछ इस स्निपेट के बाहर से एक चर माना जाता है। मुझे लगता है कि _graphicsDevice पर्याप्त स्पष्ट है। मुझे पता है। चिकन को सरल बनाया जा सकता है, लेकिन मुझे लगता है कि यह उदाहरण उद्देश्यों के लिए ठीक काम करता है। ध्यान दें कि मुझे इस तरह के ऑपरेशन को हर फ्रेम करने की अनुशंसा नहीं की जाती है, क्योंकि गलत इस्तेमाल होने पर यह आपके एफपीएस को तेज़ी से निकाल देता है।

मुझे इसे समझने में काफी समय लगा, लेकिन परिणाम संतोषजनक है। मैं उन सभी को धन्यवाद देना चाहता हूं जिन्होंने इस सवाल पर झुकाया और मेरी मदद करने की कोशिश की है।

लेनार्ड Fonteijn

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

  • कोई संबंधित समस्या नहीं^_^