2011-08-17 19 views
8

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

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

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

EDIT :: यहां मेरा टुकड़ा शेडर है, जो मुझे लगता है कि यह कारण है। यह एकमात्र ऐसा हिस्सा है जिसे मैंने कभी पारदर्शिता के साथ काम करने के लिए एक सभ्य उदाहरण नहीं मिला है, और बाकी सब कुछ जो मैंने कहीं और देखा है उससे मेल खाता है।

 final String fragmentShader =   
     "precision mediump float;  \n" 
     + "varying vec2 v_Color;   \n"  
     + "uniform sampler2D s_baseMap; \n" 
     + "void main()     \n"  
     + "{        \n" 
     + " vec4 baseColor;    \n" 
     + " baseColor = texture2D(s_baseMap, v_Color); \n" 
     + " gl_FragColor = baseColor;  \n"  
     + "}        \n"; 

यह कभी नहीं करता है अल्फा स्पष्ट रूप से कुछ भी, यह एक उदाहरण है कि यह सब के बाद का उपयोग नहीं करता से है, लेकिन मैं अभी भी टुकड़ा shaders के बारे में ज्यादा पता नहीं है और क्योंकि यह लग रहा था करने के लिए "एक तरह से" जब यह पृष्ठभूमि में छवि को मिश्रित करता है, तो मुझे लगता है कि यह कुछ रूपों में अल्फा के साथ काम कर रहा था और मैंने अभी कुछ गलत सेट किया था।

EDIT :: यहां "लोडटेक्चर" विधि है। यह लगभग ओपनजीएल ईएस 2.0 पुस्तक के उदाहरण जैसा ही है, जिसे मैं सीखने की कोशिश कर रहा हूं, कुछ बदलावों के साथ जो छवि को ठीक से काम करने के करीब लगती हैं।

private int loadTexture (InputStream is) 
{ 
    int[] textureId = new int[1]; 
    Bitmap bitmap; 
    bitmap = BitmapFactory.decodeStream(is); 
    byte[] buffer = new byte[bitmap.getWidth() * bitmap.getHeight() * 4]; 

    for (int y = 0; y < bitmap.getHeight(); y++) 
     for (int x = 0; x < bitmap.getWidth(); x++) 
     { 
      int pixel = bitmap.getPixel(x, y); 
      buffer[(y * bitmap.getWidth() + x) * 4 + 0] = (byte)((pixel >> 16) & 0xFF); 
      buffer[(y * bitmap.getWidth() + x) * 4 + 1] = (byte)((pixel >> 8) & 0xFF); 
      buffer[(y * bitmap.getWidth() + x) * 4 + 2] = (byte)((pixel >> 0) & 0xFF); 
     } 

    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(bitmap.getWidth() * bitmap.getHeight() * 4); 
    byteBuffer.put(buffer).position(0); 

    GLES20.glGenTextures (1, textureId, 0); 
    GLES20.glBindTexture (GLES20.GL_TEXTURE_2D, textureId[0]); 

    GLES20.glTexImage2D (GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, bitmap.getWidth(), bitmap.getHeight(), 0, 
          GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, byteBuffer); 

    GLES20.glTexParameteri (GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
    GLES20.glTexParameteri (GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 
    GLES20.glTexParameteri (GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
    GLES20.glTexParameteri (GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 

    return textureId[0]; 
} 

मैं समझता हूँ कि क्या कोड क्या कर रहा है, लेकिन बेशक यह अभी भी मुझे ज्ञान की मेरी कमी के कारण एक सा तो मैं बस कुछ स्पष्ट गायब हो सकता है confuses।

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

+0

सुनिश्चित करें कि पीएनजी से अल्फा चैनल बनावट में छवि लोड करते समय संरक्षित है (आरजीबी छवि लोड करने या आरजीबी बनावट बनाने के बजाय)। और निश्चित रूप से सुनिश्चित करें कि आप 'glEnable (GL_BLEND)' (सही 'glblendFunc' सेट करने के अलावा) को कॉल करें। लेकिन कुछ कोड निश्चित रूप से आपकी मदद करने के लिए थोड़ा और मदद करेंगे। शायद सिर्फ छवि लोडिंग और बनावट निर्माण कोड और कोड जहां आप मिश्रण स्थिति सेट करते हैं। और निश्चित रूप से, जैसा कि आप यहां नए हैं, स्वीकृति और अप-वोट सुविधाओं के बारे में खुद को सूचित करना न भूलें। –

+0

टुकड़ा शेडर मान्य लगता है, क्योंकि यह सही रूप से बनावट के रंग में बनावट के अल्फा को प्रतिनिधि करता है। तो आप अपने कुछ लोडिंग और बनावट निर्माण कोड पोस्ट करने के आसपास नहीं मिलेंगे। –

+0

आप ब्लेंडिंग अक्षम के साथ 'gl_FragColor = vec4 (baseColor.aaa, 1.0)' आज़मा सकते हैं। यह आपको अल्फा चैनल की एक ग्रेस्केल छवि देनी चाहिए। – trenki

उत्तर

3

आप संभवतः glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) को मिश्रण समारोह के रूप में उपयोग करना चाहते हैं और आपको gl_FragColor खंड शतरंज आउटपुट चर में बनावट के अल्फा मान को भी लिखना है।

आपके अपलोड किए गए बनावट डेटा को काम करने के लिए सभी को अल्फा मान होना चाहिए और आपने अल्फा चैनल (आरजीबीए, आरजीबीए 8 इत्यादि) का समर्थन करने वाले एक बनावट प्रारूप का उपयोग किया होगा।

आप आरजीबी रंग घटकों को अल्फा मान को रूट करके और आपको प्राप्त होने वाली छवि का निरीक्षण करके इसे सत्यापित कर सकते हैं।

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

अपनी छवि लोड हो रहा है कोड में आप अल्फ़ा चैनल पर कॉपी करने भूलना! सुझाव दें कि डेवबाइट देता है।

+0

यदि मैं glblendFunc पर उस सेटअप का उपयोग करता हूं तो छवि बिल्कुल दिखाई नहीं देती है। ऐसा लगता है कि glblendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA) मेरे लिए सबसे अच्छा काम करता है, या कम से कम काम करने के लिए निकटतम काम करता है। मुझे यह भी जिक्र करना चाहिए कि जब छवि पृष्ठभूमि में मिश्रित हो रही है, तो यह छवि के पारदर्शी हिस्सों को भी हटा देता है। मेरा मानना ​​है कि मेरी समस्या खंड के शेडर में निहित है, क्योंकि मुझे इसके बारे में अभी तक बहुत कुछ नहीं पता है और यह ज्यादातर एक उदाहरण से कोड की प्रति है जो पारदर्शिता का उपयोग नहीं कर रहा था। मैं इसे मुख्य पोस्ट में पोस्ट करूंगा। – DaeKo

1

आपका प्रारंभिक शेडर ठीक है। अल्फा रंग ops में अंतर्निहित है, यह मिश्रण/मोड/आदि के आधार पर लागू नहीं किया जा सकता है।

यह देखते हुए कि यदि आप fragcolor = base.aaa करते हैं तो आपका बनावट काला हो जाता है, जिसका अर्थ है कि आपका बनावट डेटा 'खराब' है।

अपने बनावट लोड को देखते हुए, हाँ, यह गलत है। आप अल्फा, बस आरजीबी पर कभी कॉपी नहीं करते हैं। मानते हुए कि जावा बाइट सरणी को 0s पर साफ़ करता है, सभी अल्फा शून्य होंगे, जो आपको अपना ब्लैक बॉक्स प्राप्त करेंगे, जिससे आप अल्फा ब्लेंडिंग सक्षम करते समय छवि को 'गायब' कर देंगे।

अपने जीवन को आसान बनाने के लिए, सभी हाथ नकल और सामान के बजाय, आप बस सामान्य रूप से बिटमैप लोड और बजाय सीधे glTexImage2d का उपयोग कर के अपलोड करने के लिए GLUtils सहायक का उपयोग कर सकते हैं:

bitmap = BitmapFactory.decodeStream(is); 
    GLES20.glGenTextures (1, textureId, 0); 
    GLES20.glBindTexture (GLES20.GL_TEXTURE_2D, textureId[0]); 
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 

कुछ ऐसे ही। फिर मिश्रण को सक्षम करें, अगर preultiplied नहीं है, तो src + invsrc मिश्रण मोड का उपयोग करें, और प्रस्तुत करें, आपको वांछित परिणाम प्राप्त करना चाहिए।

9

बदलें

for (int y = 0; y < bitmap.getHeight(); y++) 
    for (int x = 0; x < bitmap.getWidth(); x++) 
    { 
     int pixel = bitmap.getPixel(x, y); 
     buffer[(y * bitmap.getWidth() + x) * 4 + 0] = (byte)((pixel >> 16) & 0xFF); 
     buffer[(y * bitmap.getWidth() + x) * 4 + 1] = (byte)((pixel >> 8) & 0xFF); 
     buffer[(y * bitmap.getWidth() + x) * 4 + 2] = (byte)((pixel >> 0) & 0xFF); 
    } 

for (int y = 0; y < bitmap.getHeight(); y++) 
    for (int x = 0; x < bitmap.getWidth(); x++) 
    { 
     int pixel = bitmap.getPixel(x, y); 
     buffer[(y * bitmap.getWidth() + x) * 4 + 0] = (byte)((pixel >> 16) & 0xFF); 
     buffer[(y * bitmap.getWidth() + x) * 4 + 1] = (byte)((pixel >> 8) & 0xFF); 
     buffer[(y * bitmap.getWidth() + x) * 4 + 2] = (byte)((pixel >> 0) & 0xFF); 
     buffer[(y * bitmap.getWidth() + x) * 4 + 3] = (byte)((pixel >> 24) & 0xFF); 
    } 

में अल्फा जानकारी शामिल करने के तो बस

GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); 
GLES20.glEnable(GLES20.GL_BLEND); 

जोड़ने सही इससे पहले कि आप बनावट आकर्षित। एक बार पूरा होने के बाद GL_BLEND को अक्षम करना याद रखें।

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