2012-11-14 22 views
9

मैं कुछ ओवरले बनावट के साथ कैमरा पूर्वावलोकन सतहफलक मिश्रण मिश्रण करना चाहता हूं। मैं प्रसंस्करण के लिए इन shaders का उपयोग कर रहा हूँ:भूतलटेक्चर (बाहरी छवि) और सामान्य बनावट के एंड्रॉइड ओपनजीएल संयोजन

private final String vss = "attribute vec2 vPosition;\n" 
     + "attribute vec2 vTexCoord;\n" 
     + "varying vec2 texCoord;\n" 
     + "void main() {\n" 
     + " texCoord = vTexCoord;\n" 
     + " gl_Position = vec4 (vPosition.x, vPosition.y, 0.0, 1.0);\n" 
     + "}"; 

private final String fss = "#extension GL_OES_EGL_image_external : require\n" 
     + "precision mediump float;\n" 
     + "uniform samplerExternalOES sTexture;\n" 
     + "uniform sampler2D filterTexture;\n" 
     + "varying vec2 texCoord;\n" 
     + "void main() {\n" 
     +" vec4 t_camera = texture2D(sTexture,texCoord);\n" 
     //+" vec4 t_overlayer = texture2D(filterTexture, texCoord);\n" 
     //+ " gl_FragColor = t_overlayer;\n" + "}"; 
     + " gl_FragColor = t_camera;\n" + "}"; 

मेरा लक्ष्य t_camera और t_overlayer मिश्रण है। जब मैं t_camera या t_overlayer को अलग से दिखाता हूं, यह काम करता है (कैमरा पूर्वावलोकन या बनावट दिखा रहा है)। लेकिन जब मैं t_overlayer को अपूर्ण करता हूं, तो t_camera काला हो जाता है (किसी भी तरह से बुरी तरह नमूना)। मेरा ओवरलेयर बनावट 512x512 और CLAMPT_TO_EDGE है। यह समस्या केवल उदाहरण के लिए होती है: एंड्रॉइड एमुलेटर, एचटीसी ईवो 3 डी। लेकिन एसजीएस 3, एचटीसी वन एक्स पर, यह ठीक काम करता है।

क्या गलत है? क्या यह ईवो 3 डी कुछ विस्तार खो रहा है या क्या?

+0

आपने बताया कि यह एंड्रॉइड एमुलेटर पर काम नहीं करता है। आपने किस ओएस संस्करण का प्रयास किया? क्या आपने x86 कोशिश की? –

+0

मै मैकॉक्स 10.8.2 पर x64 एमुलेटर का उपयोग कर रहा हूं। –

उत्तर

3

मुझे अपने नेक्सस 7 पर एक ही समस्या मिली और यह मुझे पागल कर दिया। या तो सैम्पलर एक्सेलनेट्स या सैम्पलर 2 डी तक पहुंचने से पूरी तरह से ठीक काम किया जाता है, लेकिन उसी शेडर में उन्हें एक्सेस करने से अप्रत्याशित परिणाम मिलते हैं। कभी-कभी आउटपुट काला होगा। कभी-कभी लुकअप में से किसी एक के आउटपुट में खराब क्वांटिज़ेशन कलाकृतियां होती हैं। यह व्यवहार भी बनावट के नमूने वाले बनावट इकाई के आधार पर अलग-अलग होगा। मैंने प्रत्येक opengl त्रुटि की जांच की और प्रोग्राम परिणाम मान्य।

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

+1

मैंने इसे नमूनाकरण का उपयोग न करके हल किया है:/ –

+0

आप कैमरे बफर को ओपनजीएल में कैसे पास करते हैं? सब मुझे मिल सकता है SurfaceTexture के माध्यम से जा रहा था, जो मुझे samplerExternalOES का उपयोग करने के लिए मजबूर करता है। – user1924406

+1

आइडिया: मैं ऑनप्रूफ्रेम का उपयोग कर कैमरा बफर कैप्चर कर रहा हूं, बफर YUV21 प्रारूप में है। फिर मैं बफर को बफर में अलग करता हूं - वाई, यू, वी - वाईयूवी 21 प्रारूप सरल है। फिर मैं इन बफर को बनावट - जीएल_एएलपीएचए का उपयोग करके जीपीयू में अपलोड करता हूं। खंड शतरंज में मेरे पास 3 वर्दी नमूना 2 डी (वाई, यू, वी) है। और फिर खंडक शेडर में मेरे पास वाईयूवी-> आरजीबी: –

3

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

प्रत्येक TEXTURE_EXTERNAL_OES बनावट वस्तु आवश्यकता हो सकती है 3 बनावट को छवि इकाइयों के लिए जो यह स्वाभाविक है: यदि आप इस विस्तार आप निम्नलिखित (संपादित) पाठ को देखने के प्रलेखन देखें। जब TEXTURE_EXTERNAL_OES पर सेट किया गया है यह मान 1 और 3 (समावेशी) के बीच होगा। अन्य मान्य बनावट लक्ष्यों के लिए यह मान हमेशा होगा 1. ध्यान दें कि, जब एक टेक्स्ट_EXTERNAL_OES बनावट ऑब्जेक्ट बाध्य होता है, तो बनावट एक बनावट इकाई द्वारा आवश्यक छवि इकाइयां 1, 2, या 3 हो सकती हैं, जबकि अन्य बनावट ऑब्जेक्ट्स प्रत्येक बनावट इकाई को बिल्कुल 1 बनावट छवि इकाई की आवश्यकता होती है।

इसका मतलब है कि लीस पर एक अतिरिक्त काम करेगा, बशर्ते आप इसके लिए आईडी 0 का उपयोग करें।

GLES20.glUniform1i(sTextureHandle, 1); 
GLES20.glActiveTexture(GLES20.GL_TEXTURE1); 
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 
     sTextureId); 

अपने 2 डी बनावट के लिए:: आपके मामले में

GLES20.glUniform1i(filterTextureHandle, 0); 
GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, filterTextureID); 

मुझे यकीन है कि आप के लिए यह इच्छा कसरत कर रहा हूँ।

+0

अच्छी तरह से, मुझे बिल्कुल वही समस्या मिलती है, और GL_TEXTURE_EXTERNAL_OES और बनावट बनावट बनावट आईडी बिल्कुल काम नहीं कर रही है। मुझे लगता है कि बस अन्य लोगों की तरह, यह हार्डवेयर और विभिन्न फोन से संबंधित एक समस्या है जो इसे अलग-अलग समर्थन देती है। – flankechen

+0

यह स्पष्ट नहीं है कि 'आईडी' का अर्थ है 'आप इसके लिए आईडी 0 का उपयोग करते हैं'। मैं एक वर्दी में 0 देखता हूं, जो एक आईडी नहीं बल्कि एक इकाई है। एक बनावट आईडी sTextureId और फ़िल्टरटेक्चर आईडी पर है, और हम इसे मनमाने ढंग से सेट नहीं कर सकते हैं। –

+0

हाय लियोन, मेरा मतलब था: sTextureId = GL_TEXTURE1 जो बदले में glUniform1i (sTextureHandle, 1) की आवश्यकता होती है; शेडर के लिए 0 के लिए वही। सुनिश्चित नहीं है कि आप इसका क्या मतलब है "हम इसे मनमाने ढंग से सेट नहीं कर सकते हैं।" मैं केवल 0 और 1 का उपयोग करके, GL_TEXTURE0 और GL_TEXTURE1 शेडर को बता रहा हूं। मेरे लिए काम करता है। – Marco

3

यह कोई जवाब नहीं है, बल्कि सवाल का एक विस्तार है - शायद यह समस्या का विचार पाने के लिए ओपनजीएल ईएस विशेषज्ञ की मदद करेगा।


मेरे पास ओवरले के लिए 3 बनावट हैं, और एक बाहरी बनावट है, जो मीडिया प्लेयर से आउटपुट कैप्चर करने के लिए उपयोग की जाती है।अगर मैं केवल बाहरी बनावट का उपयोग करता हूं, तो आउटपुट अपेक्षित है, एमपीएलएयर से फ्रेम। नेक्सस 4, सैमसंग गैलेक्सी एस 3, एस 4 इत्यादि पर एक ही पूर्ण कोड ठीक काम करता है (सभी डिवाइस एड्रेनो जीपीयस या आर्म माली 400 का उपयोग करते हैं) हार्डवेयर में अंतर यह है कि नेक्सस 7 नेविडिया टेग्रा 3 बोर्ड का उपयोग करता है।


संपादित(कैसे मेरे पक्ष में हल किया गया था):

Nvidia Tegra 3 की आवश्यकता है कि बाहरी बनावट नमूना samplers में सबसे कम वर्णमाला आदेश के साथ एक नाम के साथ कहा जाता है, जबकि Adreno 220 करने लगते हैं रिवर्स की आवश्यकता है। इसके अलावा, टी 3 की आवश्यकता है कि बाहरी बनावट आखिरी नमूना है। एंड्रॉइड 4.3 और नए का उपयोग कर उपकरणों के साथ, इन बग को हल किया जा सकता है। एनवीडिया पक्ष पर, यह एक बग था, जिसे बहुत पहले हल किया गया था लेकिन नेक्सस ड्राइवर केवल बाद में अपडेट किए गए थे। इसलिए मुझे यह जांचना पड़ा कि कौन सी जीपीयू मौजूद थी, और तदनुसार कोड अनुकूलित करें।

+0

मुझे लगता है कि 4.3 ने इसे हल नहीं किया। वह पागल है। क्या यह एनवीडिया टेग्रा 3 बनाम है - कोई अन्य -? –

3

उपर्युक्त विधि मेरे बहुत सारे समय को बचाती है। आप गुरु धन्यवाद:

GLES20.glUniform1i(sTextureHandle, 1); 
GLES20.glActiveTexture(GLES20.GL_TEXTURE1); 
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 
    sTextureId); 

अपने 2 डी बनावट के लिए:

GLES20.glUniform1i(filterTextureHandle, 0); 
GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, filterTextureID); 

बदलें बनावट सूचकांक इस हल करने के लिए एक अच्छा तरीका है।

+0

क्या यह ओईएस बनावट के लिए उच्चतम इंटेंट का उपयोग करने के बारे में है? "ऊपर से" से आपका क्या मतलब है? ओह, caplocks के लिए खेद है। "ऊपर से" पढ़ने पर यह स्वचालित रूप से सक्रिय हो गया। :) –

3

यह ओपनजीएल कार्यान्वयन में एक बग प्रतीत होता है। उसी कोड ने सैमसंग नोट पर ठीक काम किया था, न कि नेक्सस 4 पर। ऐसा प्रतीत होता है कि कुछ नमूने के लिए कुछ उपकरणों पर यूनिफॉर्मेशन ब्रेक होता है जो सैंपलर एक्सटेरियोओएस में स्थित हैं।

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

+0

समाधान इसे कुछ उपकरणों (एक्स: मोटोरोला रेजर) और ज़ज़ पर अन्य उपकरणों पर एक्सएटेक्चर पर सेट करना है (एक्स: एक्सपीरिया) –

1

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

सबसे पहले, समस्या कथन। Lukas Jezný की तरह, मेरे पास एक पूर्वावलोकन बनावट और एक ओवरले बनावट है। यह नेक्सस 4/5 और अन्य प्रकार के अधिकांश के लिए ठीक काम करता है, लेकिन ओपीपीओ पर कुछ भी नहीं दिखाता है, लेनोवो ए 820, लेनोवो ए 720।

समाधान:

(1) सिर्फ Lukáš Jezný, उपयोग YUV डेटा की तरह और शेडर में आरजीबी करने के लिए उन्हें बदलने।

(2) मल्टीपास ड्राइंग, पूर्वावलोकन बनावट को फ्रेमबफर में एक बार खींचें, और इसे पढ़ें, फिर स्क्रीन पर फिर से खींचें।

(3) अन्य प्रोग्राम का उपयोग करने से पहले आप अपने खुद के प्रोग्राम का उपयोग,

GLES20.glUseProgram(another one); 
    GLES20.glUseProgram(your "real" program); 

और यह सिर्फ OPPO के लिए काम करता है 5, लेनोवो A820, लेनोवो A720 और अन्य। कोई भी नहीं जानता कि क्यों ......

1

उपयोगकर्ता 1 9 24406 की पोस्ट (https://stackoverflow.com/a/14050597/3250829) का जिक्र करते हुए एक नमूना 2 डी बनावट और नमूना एक्स्ट्राइनओईएस बनावट तक पहुंचने के लिए, यह वही है जो मुझे करना था क्योंकि मैं जो अनुप्रयोग विकसित कर रहा हूं वह पढ़ रहा है डिवाइस पर मौजूद कैमरे का उपयोग करने के बजाय सर्वर से फ़ाइल या स्ट्रीमिंग। एक ही शेडर में दोनों बनावटों का उपयोग करने के परिणामस्वरूप बहुत अजीब रंगीन कलाकृतियों (गैलेक्सी एस 3 पर मामला) या संतृप्ति और विपरीत मुद्दों (नेक्सस 4 पर मामला) हुआ।

इस तरह, सैंपलरएक्सनेटओईएस बनावट बग (जो मैंने अब तक देखा है) के आसपास काम करने का एकमात्र तरीका दो शेडर प्रोग्राम करना है: एक जो नमूना एक्सप्लोरोईएस बनावट में एफबीओ में निहित सामग्री लिखता है और अन्य जो एफबीओ से सामग्री लेता है और इसे सीधे सतह पर लिखता है।

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

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

+0

लगभग दस लाख वर्षों के दौरान खोज करने के बारे में आप इसे कैसे प्राप्त कर रहे हैं, मुझे बस इसे छोड़ दें संपर्क। https://github.com/harism/android_instacam/blob/master/src/fi/harism/instacam/InstaCamRenderer.java –

+1

@ लेओनलेटियर - आप मुझे एक टिप्पणी छोड़ सकते थे और मुझे कोड के लिए कहा :) बीटीडब्ल्यू, धन्यवाद उस लिंक के लिए। इसे वहां देखना अच्छा लगा। – rayryeng

+0

मैं इसे घर पर आज़माउंगा।मुझे आश्चर्य है कि वीडियो प्रवाह पर लागू होने पर यह एफपीएस की अवधि में कैसा दिखाई देगा। मैं एंड्रॉइड मीडियाप्लेयर और आईओएस एवीएफउंडेशन को एक सामान्य ओपनटीके पोर्टेबल एप्लिकेशन में वाईयूवी फ्रेम भेज रहा हूं, और शेडर्स को लागू करने के लिए उपरोक्त उल्लिखित प्रवाह (बनावट के लिए एफबीओ) का उपयोग करता हूं। इससे क्रॉस-प्लेटफ़ॉर्म वीडियो प्रभाव बहुत आसान हो जाएंगे। –

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

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