2012-08-29 20 views
8

प्रश्न का उत्तर दिया गया था। अधिक जानकारी के लिए, इस पाठ के अंत में संपादित करें # 4 देखें।योजक मिश्रण के साथ चित्रकारी चित्र

हम वर्तमान में गेममेकिंग इंजन पर काम कर रहे हैं जो बहुत अच्छी तरह से चल रहा है। मैं एनीमेशन निर्माता पर काम कर रहा हूं और सोच रहा था कि क्या मिश्रित मिश्रण के साथ एक छवि खींचना संभव था।

मुझे समझाएं।

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

वास्तविक समस्या यह है कि हम समझ नहीं सकते कि मिश्रित मिश्रण के साथ फ्रेम कैसे आकर्षित किया जाए।

यदि आप इसे प्राप्त नहीं करते हैं तो क्या जोड़ना मिश्रण है इसका एक उदाहरण यहां दिया गया है। मैं आपको दोष नहीं दूंगा, मुझे अंग्रेजी में कठिन समय लिखना है। Additive blending exemple

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

 using (Graphics g = Graphics.FromImage(MapBuffer as Image)) 
     using (Brush brush = new SolidBrush(Color.White)) 
     using (Pen pen = new Pen(Color.FromArgb(255, 0, 0, 0), 1)) 
     { 
      g.FillRectangle(brush, new Rectangle(new Point(0, 0), new Size(CurrentMap.MapSize.Width * TileSize, CurrentMap.MapSize.Height * TileSize))); 

      Tile tile = CurrentMap.Tiles[l, x, y]; 
      if (tile.Background != null) g.DrawImage(tile.Background, new Point(tile.X * TileSize, tile.Y * TileSize)); 

      g.DrawRectangle(pen, x * TileSize, y * TileSize, TileSize, TileSize); 
     } 

वहाँ एक additive चित्र के साथ और यदि ऐसा है तो एक छवि ड्राइंग के संभावित रास्ता नहीं है, मैं अगर किसी ने मुझे बाहर कैसे बात कर सकता है हमेशा के लिए आभारी होंगे। धन्यवाद।

संपादित करें # 1:

छवियों ड्राइंग के लिए, हम एक रंग मैट्रिक्स का उपयोग कर रहे रंग और alph (अस्पष्टता) इस तरह स्थापित करने के लिए:

ColorMatrix matrix = new ColorMatrix 
(
    new Single[][] 
    { 
     new Single[] {r, 0, 0, 0, 0}, 
     new Single[] {0, g, 0, 0, 0}, 
     new Single[] {0, 0, b, 0, 0}, 
     new Single[] {0, 0, 0, a, 0}, 
     new Single[] {0, 0, 0, 0, 1} 
    } 
); 

हो सकता है कि रंग मैट्रिक्स के लिए इस्तेमाल किया जा सकता additive मिश्रण?

संपादित करें # 2:

बस महेश चंद द्वारा this लेख पाया।

आगे ब्राउज़ करने के बाद, रंगीन मैट्रिक्स के साथ यह संभव नहीं हो सकता है, भले ही यह रंग परिवर्तन के संबंध में बहुत कुछ पूरा कर सके। समाधान मिलने पर मैं अपने स्वयं के प्रश्न का उत्तर दूंगा।

आपकी मदद के लिए धन्यवाद।

संपादित # 3:

XNA सम्मिश्रण के बारे में दस्तावेज़ here का एक बहुत है। मुझे एक छवि के प्रत्येक पिक्सेल पर मिश्रित मिश्रण को पूरा करने के लिए प्रयुक्त सूत्र मिला।

PixelColor = (स्रोत * [1, 1, 1, 1]) + (गंतव्य * [1, 1, 1, 1])

हो सकता है कि वहाँ वर्तमान संदर्भ में इस सूत्र का उपयोग करने का एक तरीका है? मैं अगले संपादन पर 50 बाउंटी शुरू करूंगा, हमें वास्तव में काम करने की आवश्यकता है।

आपके समय के लिए फिर से धन्यवाद।

संपादित करें # 4

अक्षतंतु के लिए धन्यवाद, अब समस्या हल हो रहा है। XNA का उपयोग करते हुए और उसके Spritebatch, आप Additive सम्मिश्रण ऐसा करने को पूरा कर सकते हैं:

सबसे पहले आप एक GraphicsDevice बना सकते हैं और एक SpriteBatch

// In the following example, we want to draw inside a Panel called PN_Canvas. 
// If you want to draw directly on the form, simply use "this" if you 
// write the following code in your form class 

PresentationParameters pp = new PresentationParameters(); 

// Replace PN_Canvas with the control to be drawn on 
pp.BackBufferHeight = PN_Canvas.Height; 
pp.BackBufferWidth = PN_Canvas.Width; 
pp.DeviceWindowHandle = PN_Canvas.Handle; 
pp.IsFullScreen = false; 

device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, GraphicsProfile.Reach, pp); 
batch = new SpriteBatch(device); 

तब, जब यह नियंत्रण पर या फार्म पर आकर्षित करने के लिए समय (है उदाहरण के लिए OnPaint घटना) के साथ, आप निम्न कोड ब्लॉक

// You should always clear the GraphicsDevice first 
device.Clear(Microsoft.Xna.Framework.Color.Black); 

// Note the last parameter of Begin method 
batch.Begin(SpriteSortMode.BackToFront, BlendState.Additive); 
batch.draw(/* Things you want to draw, positions and other infos */); 
batch.End(); 

// The Present method will draw buffer onto control or form 
device.Present(); 
+1

मुझे यकीन नहीं है कि यह सीधे पिक्सेल मूल्यों को छेड़छाड़ किए बिना सीधे ऊपर Winforms में संभव है। ड्राइंग के लिए एक WPF होस्टेड घटक का उपयोग करना एक विकल्प होगा?डब्ल्यूपीएफ में मिश्रण मोड को अधिक आसान बनाने की क्षमता है। – Dervall

+0

@Dervall जितना अधिक हम खोजते हैं उतना ही हम सोचते हैं कि एक WPF होस्टेड घटक का उपयोग करना एक बहुत अच्छा विचार है। हो सकता है कि विनफॉर्म के साथ सीधे बाय-पिक्सेल अलगो का उपयोग किए बिना कोई समाधान न हो। या शायद कोई किसी प्रकार के चमत्कार के साथ आएगा? –

+0

संभव डुप्लिकेट [अस्पष्टता के साथ ड्रामाइमेज?] (Http://stackoverflow.com/questions/5519956/drawimage-with-opacity) –

उत्तर

7

या तो 1 का उपयोग करें) XNA (गति के लिए अनुशंसित) का उपयोग कर सकते हैं, या 2) सी # में पिक्सेल संचालन का उपयोग करें। अन्य विधियां हो सकती हैं, लेकिन इनमें से कोई भी काम (मैं उनमें से प्रत्येक का उपयोग 3 डी प्रभाव और छवि विश्लेषण ऐप्स (क्रमशः) के लिए कर रहा हूं जो मैं बनाए रखता हूं)।

सी #: में पिक्सेल ऑपरेशंस 3 बिटमैप्स का उपयोग करना; बीएमपीए, बीएमपीबी, बीएमपीसी, जहां आप बीएमपीसी में बीएमपीए + बीएमपीबी स्टोर करना चाहते हैं।

for (int y = 0; y < bmp.Height; y++) 
{ 
    for (int x = 0; x < bmp.Width; x++) 
    { 
     Color cA = bmpA.GetPixel(x,y); 
     Color cB = bmpB.GetPixel(x,y); 
     Color cC = Color.FromArgb(cA.A, cA.R + cB.R, cA.G + cB.G, cA.B + cB.B); 
     bmpC.SetPixel(x, y, cC); 
    } 
} 

उपरोक्त कोड बहुत धीमा है। सी # में एक तेजी से समाधान इस तरह संकेत इस्तेमाल कर सकते हैं:

// Assumes all bitmaps are the same size and same pixel format 
    BitmapData bmpDataA = bmpA.LockBits(new Rectangle(0, 0, bmpA.Width, bmpA.Height), ImageLockMode.ReadOnly, bmpA.PixelFormat); 
    BitmapData bmpDataB = bmpB.LockBits(new Rectangle(0, 0, bmpA.Width, bmpA.Height), ImageLockMode.ReadOnly, bmpA.PixelFormat); 
    BitmapData bmpDataC = bmpC.LockBits(new Rectangle(0, 0, bmpA.Width, bmpA.Height), ImageLockMode.WriteOnly, bmpA.PixelFormat); 
    void* pBmpA = bmpDataA.Scan0.ToPointer(); 
    void* pBmpB = bmpDataB.Scan0.ToPointer(); 
    void* pBmpC = bmpDataC.Scan0.ToPointer(); 
    int bytesPerPix = bmpDataA.Stride/bmpA.Width; 
    for (int y = 0; y < bmp.Height; y++) 
    { 
     for (int x = 0; x < bmp.Width; x++, pBmpA += bytesPerPix, pBmpB += bytesPerPix, pBmpC += bytesPerPix) 
     { 
      *(byte*)(pBmpC) = *(byte*)(pBmpA) + *(byte*)(pBmpB); // R 
      *(byte*)(pBmpC + 1) = *(byte*)(pBmpA + 1) + *(byte*)(pBmpB + 1); // G 
      *(byte*)(pBmpC + 2) = *(byte*)(pBmpA + 2) + *(byte*)(pBmpB + 2); // B 
     } 
    } 
    bmpA.UnlockBits(bmpDataA); 
    bmpB.UnlockBits(bmpDataB); 
    bmpC.UnlockBits(bmpDataC); 

उपरोक्त विधि संकेत की आवश्यकता है और इसलिए "असुरक्षित" निर्देश के साथ संकलित किया जाना चाहिए। आर, जी, और बी के लिए 1-बाइट भी मानते हैं। अपने पिक्सेल प्रारूप के अनुरूप कोड बदलें।

XNA का उपयोग करना बहुत तेज़ (प्रदर्शन) है क्योंकि यह हार्डवेयर त्वरित (GPU द्वारा) है। इसमें मूल रूप से निम्न शामिल होते हैं: 1. छवि खींचने के लिए आवश्यक ज्यामिति बनाएं (एक आयताकार, संभवतः एक पूर्ण-स्क्रीन क्वाड)। 2. एक कशेरुक-शेडर और पिक्सेल-शेडर लिखें। कशेरुक-शेडर आसानी से ज्यामिति को निष्क्रिय कर सकता है। या आप एक ऑर्थोगोनल प्रक्षेपण लागू कर सकते हैं (क्वाड के लिए आप किस निर्देशांक के साथ काम करना चाहते हैं) के आधार पर। पिक्सेल शेडर में निम्नलिखित पंक्तियां होंगी (एचएलएसएल):

float4 ps(vertexOutput IN) : COLOR 
{ 
    float3 a = tex2D(ColorSampler,IN.UV).rgb; 
    float3 b = tex2D(ColorSampler2,IN.UV).rgb; 
    return float4(a + b,1.0f); 
} 

बनावट तक पहुंचने के लिए विभिन्न विधियां उपलब्ध हैं। निम्नलिखित भी काम करेंगे (कैसे आप XNA कोड शेडर मानकों करने के लिए बाध्य करना चाहते हैं पर निर्भर करता है):

float4 ps(vertexOutput IN) : COLOR 
{ 
    float3 a = texA.Sample(samplerState, IN.UV).xyz; 
    float3 b = texB.Sample(samplerState, IN.UV).xyz; 
    return float4(a + b,1.0f); 
} 

ऊपर shaders आप आप "sampler2D" या "का उपयोग करना चाहते हैं, इस पर निर्भर करेगा का उपयोग में से कौन सा बनावट "एचएलएसएल बनावट तक पहुंचने के लिए इंटरफेस।

आपको यह भी सुनिश्चित करने के लिए उचित नमूना सेटिंग का उपयोग करने के लिए सावधान रहना चाहिए कि रंग मानों को देखते समय कोई नमूनाकरण (उदाहरण के लिए रैखिक इंटरपोलेशन) का उपयोग नहीं किया जाता है जब तक कि आप ऐसा कुछ नहीं चाहते (जिस स्थिति में कुछ उच्च गुणवत्ता/उच्च-आदेश का उपयोग करें)।

एक्सएनए में अंतर्निहित ब्लेंडस्टेट्स भी हैं जो आप यह निर्दिष्ट करने के लिए उपयोग कर सकते हैं कि ओवरलैप्ड बनावट कैसे संयुक्त किए जाएंगे। अर्थात। BlendState.Additive (अद्यतन मूल पोस्ट देखें)।

+0

जैसे ही मैं टीम के साथ आता हूं, मुझे कल इसे आजमाएं। यह बहुत समझ में आता है; आप जिस ड्रॉ को आकर्षित करना चाहते हैं उसके साथ पिक्सल को मिश्रित करने के लिए आपको स्रोत छवि की आवश्यकता है। घटनाक्रम हमने XNA का उपयोग न करने का निर्णय लिया है, मैं आपको प्रदान किए गए इस बेहद सुसंगत उत्तर के साथ उन्हें मनाने में सक्षम हो सकता हूं। –

+0

ठीक है, इसलिए टीम ने अंततः WinForms के साथ XNA का उपयोग करने का निर्णय लिया। महोदय, आपने बस दिन बचा लिया। धन्यवाद! 14 घंटों तक इंतजार करना पड़ेगा जब तक कि मैं आपको 50pts दे सकता हूं। –

+0

Nooo problemo। शुभकामनाएँ! – axon

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