2012-09-03 17 views
5

मेरे पास ओपनजीएल का उपयोग करने का एक बहुत ही बुनियादी ज्ञान है, खासकर एंड्रॉइड पर। मैं एक ऐप विकसित कर रहा हूं जो पूर्ण स्क्रीन छवियों के बीच एक तेज़ तरीके से स्विच करने के लिए ओपनजीएल का उपयोग करता है (क्योंकि यह सामान्य एंड्रॉइड फ्रेमवर्क का उपयोग करके बहुत धीमा है)।ओपनजीएल ES में बनावट को लोड करने के लिए कुशलतापूर्वक

क्या मैं पाया है कि आदेश बनावट लोड करने के लिए, मैं की तरह कुछ करने की ज़रूरत है:

ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4); 
byteBuffer.order(ByteOrder.nativeOrder()); 
vertexBuffer = byteBuffer.asFloatBuffer(); 
vertexBuffer.put(vertices); 
vertexBuffer.position(0); 
byteBuffer = ByteBuffer.allocateDirect(texture.length * 4); 
byteBuffer.order(ByteOrder.nativeOrder()); 
textureBuffer = byteBuffer.asFloatBuffer(); 
textureBuffer.put(texture); 
textureBuffer.position(0); 
_gl = gl; 
final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), _imageResourceId); 
gl.glGenTextures(1, textures, 0); 
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); 
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); 
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); 
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); 
bitmap.recycle(); 

अब, के बाद से छवियों (पूर्ण स्क्रीन के लिए हैं और वे काफी बड़े हैं - 1024x1024), इसमें कुछ समय लगता है, खासकर जब से मुझे एक ही समय में उनमें से 5 लोड करना होगा।

तो मैं, कोड में सुधार के सुझाव दिए गए के बारे में कुछ सवाल पूछना विशेष रूप से कुशल लोड हो रहा है के बारे में की जरूरत है (लेकिन यह भी कम स्मृति का उपयोग कर यदि संभव हो तो):

  1. अगर मैं बिटमैप डिकोड पारदर्शिता पिक्सल की जरूरत नहीं करने के लिए, RGB_565 प्रारूप का उपयोग करके, क्या यह छवियों को OpenGL (या डिकोडिंग चरण) में लोड करने की गति को बढ़ावा देगा?

  2. क्या इनपुट बिटमैप में चौड़ाई और ऊंचाई होना चाहिए जो 2 की शक्तियां हैं या क्या मैं ओपनजीएल को केवल वह हिस्सा ले सकता हूं जो यह चाहता है, जिसमें यह नियम होगा? मेरा मतलब है, शायद मैं बिटमैप का केवल एक हिस्सा लेने के लिए texImage2D कमांड कर सकता हूं?

  3. शायद मैं केवल शुरुआत से ही इस भाग को डीकोड कर सकता हूं (इसलिए यदि मेरे पास 10000x10000 की एक बड़ी छवि है, तो मैं केवल 1024x1024 भाग को डीकोड कर सकता हूं और इसे ओपनजीएल को दे सकता हूं)?

  4. क्या यह केवल पहली छवि लोड करना और दिखाया जा सकता है, और पृष्ठभूमि में शेष लोड? मैंने सुना है कि आप थ्रेडमैप को ओपनजीएल को थ्रेड में नहीं भेज सकते हैं जो कि इसे संभालने वाला नहीं है। क्या की विधि पर उन्हें लोड करने का अर्थ है, दूसरी बार इसे कॉल करने के लिए कहें?

  5. मुझे याद है कि मैंने एक छवि में कई छवियों को विलय करने के बारे में एक टिप के बारे में सुना है (एक दूसरे के बाद, बाएं से दाएं), ताकि डीकोडिंग चरण के लिए कुछ गति वृद्धि हो। सुनिश्चित नहीं है कि इस तकनीक का नाम क्या है। क्या एंड्रॉइड पर ओपनजीएल ईएस के लिए अभी भी संभव है?

  6. क्या बिटमैप उदाहरण बनाने से बचने और डीकोडिंग को अधिक देशी तरीके से (एनडीके, शायद) में करना संभव है? मेरे परीक्षणों के अनुसार, एक एमुलेटर पर आकार 1024x1024 की पीएनजी फ़ाइल को डीकोड करने से लगभग 400ms-700ms लगते हैं, फिर भी इसे ओपनजीएल में भेजकर लगभग 50ms-70ms लगता है।

  7. प्रोक्रैंक का उपयोग करके, मुझे पता चला है कि ओपनजीएल बहुत मेमोरी ले सकता है। क्या इसे कम स्मृति का उपयोग करना संभव है? शायद बेहतर बनावट प्रकार का उपयोग करें?

  8. चूंकि एंड्रॉइड कई प्रकार के उपकरणों पर काम कर सकता है, क्या मैनिफेस्ट में यह आवश्यक है कि ऐप चलाने के लिए कितनी मेमोरी की आवश्यकता हो, ताकि बहुत कम स्मृति वाले लोग सक्षम न हों इसे स्थापित करो?


@Majid मैक्स:

  1. तो यह इस तरह से डिकोड और ओपन को भेजने के लिए काफी है, या मैं भी कुछ खास स्थापित करना चाहिए जब OpenGL पर भेजने?

  2. बिटमैप का आंशिक हिस्सा लेने के लिए ऐसा कोई आदेश नहीं है?

  3. मेरा मतलब है, क्या मैं बिटमैप के बजाय बिटमैप में संग्रहीत करने के लिए फ़ाइल का केवल आंशिक हिस्सा डीकोड कर सकता हूं?

  4. तो एकमात्र चीज मैं शुरुआत में सब कुछ लोड करने के लिए कर सकता हूं, और फिर इसका उपयोग कर सकता हूं? ऐसा कैसे हो सकता है? गेम इसे कैसे संभालते हैं? मेरा मतलब है, वे एक के बाद एक मंच दिखाते हैं, यहां तक ​​कि ओपनजीएल उत्पन्न प्रगति पट्टी की तरह दिखने वाला कुछ भी। यह बहुत ही समस्याग्रस्त है।

  5. जो मैं वर्णन कर रहा हूं वह वेब पर भी उपलब्ध है। उदाहरण के लिए, एकाधिक छोटी छवियों को लोड करने के बजाय, वेबपृष्ठ में एक ही छवि होती है और नक्शा दिखाता है कि इसका किस भाग को दिखाया जाना चाहिए। इसके लिए एक और नाम sprites है। उदाहरण here

  6. मुझे लगता है। मुझे लगता है कि मुझे glDeleteTextures भी कॉल करना चाहिए जब मुझे लगता है कि अब और उपयोग नहीं किया गया है, है ना?

  7. मैं यह कैसे कर सकता हूं? कोड में मुझे क्या बदलना चाहिए?

  8. जब मैं बहुत मेमोरी का उपयोग करता हूं तो क्या होता है? क्या कोई फ्री रैम नहीं होने पर वर्चुअल रैम (शायद आंतरिक स्टोरेज का उपयोग करता है) जैसी कोई चीज है? मैंने Google आईओ वीडियो पर इसके बारे में सुना है, लेकिन ऐसा लगता है कि वे उत्तर के बारे में भी निश्चित नहीं थे। लिंक here। जब उन्होंने ऐसी चीज होती है तो उन्होंने केवल अधिक दुर्घटनाओं की अपेक्षा की।


@Majid मैक्स:

1 + 2 + 3। ?

  1. यह काम कर सकता है। आपका मतलब है कि मैं एक नया धागा बनाता हूं जो बिटमैप्स लोड करेगा, और फिर परिणाम को ओपनजीएल थ्रेड पर वापस भेज देगा जो बनावट को बिटमैप में बांध देगा? शायद मैं asyncTask के समान दृष्टिकोण का उपयोग कर सकता हूं, और प्रकाशन प्रगति का उपयोग कर सकता हूं।

  2. यह भी एक अच्छी बात है। क्या आपके पास कोई लिंक है जिसके बारे में मुझे पढ़ना चाहिए? या शायद मेरे कोड में बदलने के लिए एक स्निपेट?

  3. धन्यवाद।

  4. इसलिए मुझे लगता है कि यह ईटीसी 1 का उपयोग करने की सबसे आसान बात है। हालांकि यह पारदर्शिता का समर्थन नहीं करता है, इसलिए this link के अनुसार, मुझे इसके लिए एक और बनावट का उपयोग करने की आवश्यकता है, लेकिन मुझे इसके लिए नमूना नहीं मिल रहा है।

  5. मैं उपलब्ध स्मृति के बारे में क्या सोच सकता हूं जिसका मैं उपयोग कर सकता हूं? क्या मैं मान सकता हूं, उदाहरण के लिए, कि सभी एंड्रॉइड डिवाइस मुझे 200 एमबी वीडियो मेमोरी की पेशकश कर सकते हैं जिसे मैं ओपनजीएल के लिए उपयोग कर सकता हूं?

उत्तर

-1

मुझे लगता है कि आप http://www.andengine.org/ की जांच करनी चाहिए यह आपको समय और काम का एक बहुत बचत होगी ...

+0

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

5
  1. हाँ, यदि आप पारदर्शिता (अल्फा) की जरूरत नहीं है एक प्रारूप का उपयोग करें बिना अल्फा के, और छोटे प्रारूप जैसे (आरजीबी 565) का अर्थ है छोटे आकार के बनावट जो निश्चित रूप से डीकोडिंग को गति देते हैं और ओपनएल को लोड करते हैं।

  2. निश्चित रूप से हाँ, यदि आप 2 चौड़ाई/ऊंचाई की गैर शक्ति के साथ बनावट लोड करते हैं, तो ओपनएल 2 की अगली शक्ति (513/513 बनावट 1024/1024 बन जाएगी) के साथ एक बनावट आवंटित करेगा, और इसका मतलब है कि आप हैं बर्बाद स्मृति बर्बाद कर रहा है। और आप छवि का एक हिस्सा लेने के लिए opengl आदेश नहीं दे सकते क्योंकि "teximage2d" लोड की गई छवि की चौड़ाई/ऊंचाई लेता है, और कोई अन्य मान निर्दिष्ट करने से आपको दूषित छवि मिल जाएगी (यदि ऐप को कुचलने नहीं है)।

  3. कोई टिप्पणी नहीं।

  4. मुझे यकीन नहीं है कि ओपनगल पर आधारित एक बहु थ्रेडेड रेंडरिंग इंजन पहले से ही है। और आप एक प्रतिपादन आदेश जारी करते समय एक बनावट (अन्य धागे से) लोड कर सकते हैं (कम से कम देशी सी/सी ++ में, जावा के बारे में निश्चित नहीं)। और नहीं, कभी भी लूप प्रतिपादन में एक बनावट लोड करने का प्रयास न करें, यह बुरा अभ्यास है।

  5. नहीं सुनिश्चित करें कि आप यहाँ

  6. इस सबसे अच्छा तरीका है, मूल कोड (C/C++) है क्या मतलब हमेशा बेहतर

  7. हाँ, एक बनावट संपीड़न का उपयोग कर (आप यहाँ VRAM मतलब अगर) ईटीसी 1, पीवीआरटीसी, एटीसी जैसे प्रारूप हमेशा एक अच्छा विचार है, यह कम व्रम मेमोरी लेता है और बेहतर प्रदर्शन करता है।

  8. फ़ॉलबैक समाधान (यहां तक ​​कि छोटे छोटे बनावट) पर स्विच करने पर विचार करें, बल्कि निचले अंत उपकरणों को बंद करना।

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

4 .. आप सामग्री लोड हो रहा है एक अलग थ्रेड जो प्रतिपादन करने के लिए संकेत मिलता है में (चित्र) प्रक्रिया लदान का प्रतिशत थ्रेड शुरू करते हैं, इस के लिए एक प्रगति बार आकर्षित करने के लिए इस्तेमाल किया जा सकता लोडिंग प्रक्रिया।

5 .. इस चाल को "बनावट एटलस" कहा जाता है और यह लोडिंग को प्रतिपादित करने की गति को तेज करने के लिए है।

6 .. एक डीकोडेड छवि को ओपनग्ल बनावट में लोड करने के बाद, आप डीकोडेड छवि (सिस्टम मेमोरी से) को अगले लोड करने से मुक्त करने के लिए स्वतंत्र हैं। और ओपनग्ल बनावट का उपयोग करने के बाद आप इसे हटा सकते हैं (वीडियो मेमोरी से)।

7 .. बनावट संपीड़न हार्डवेयर-विशिष्ट ओपनजी एक्सटेंशन है, इसलिए आपको यह जांचना होगा कि बनावट संपीड़न एक्सटेंशन मौजूद है या फिर इसे "texImage2D" के बजाय "glCompressedTexImage2D" फ़ंक्शन के साथ उपयोग करें। पावरवीआर जीपीयू के लिए पीवीआरटीसी; एएमडी जीपीयू के लिए एटीसी; माली जीपीयू के लिए एएसटीसी; ईटीसी 1 एक मानक बनावट प्रारूप (एंड्रॉइड 2.2+ में समर्थित)।

8 .. जब आपने ओपनग्ल बनावट में एक छवि लोड कर ली, तो छवि की अब आवश्यकता नहीं है। तो आपको अनियंत्रित सामग्री (छवियों) से राम को मुक्त करना होगा।

EDIT2:

5 .. http://http.download.nvidia.com/developer/NVTextureSuite/Atlas_Tools/Texture_Atlas_Whitepaper.pdf

7 ..ओपनएल में "glCompressedTexImage2D" का उपयोग करके दो ईटीसी बनावट (पूर्व: पहला बनावट रंग, और लाल चैनल में दूसरा स्टोर अल्फा) लोड करने के बाद (बनावट बनाम 1, textureId2 कहें), दो बनावट इकाइयों में दो बनावट बांधें:

glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, textureId1); 

glActiveTexture(GL_TEXTURE1); 
glBindTexture(GL_TEXTURE_2D, textureId2); 

और फिर निम्न टुकड़ा शेडर के साथ एक शेडर कार्यक्रम बनाने के लिए:

uniform sampler2D  sTexture1; 
uniform sampler2D  sTexture2; 
varying mediump vec2 vTexCoord; 

void main() 
{ 
    gl_FragColor.rgb = texture2D(sTexture1, vTexCoord).rgb; 
    gl_FragColor.a = texture2D(sTexture2, vTexCoord).r; 
} 

अंत में, दो बनावट इकाइयों को दो शेडर बनावट samplers बाँध (दो आदि बनावट के लिए जो बिंदु):

GLint texture1Sampler = glGetUniformLocation(programObject, "sTexture1"); 
GLint texture2Sampler = glGetUniformLocation(programObject, "sTexture2"); 

glUniform1i(texture1Sampler, GL_TEXTURE0); 
glUniform1i(texture2Sampler, GL_TEXTURE1); 

8 .. आप किसी भी चीज को नहीं मान सकते हैं, आप अन्य अप्रयुक्त संसाधनों (बनावट, बफर, ...) को मुक्त करने के बजाय, आपको GL_OUT_OF_MEMORY प्राप्त करने तक, बनावट (बफर के रूप में) आवंटित करते रहते हैं।

+0

उत्तर के लिए धन्यवाद। कृपया अपने उत्तरों पर टिप्पणियों के लिए मेरा अद्यतन प्रश्न देखें। –

+0

मैंने अपना जवाब अपडेट किया है, मुझे आशा है कि इससे मदद मिलती है। –

+0

@ माजिद: एएसटीसी अभी तक कुछ भी उपलब्ध नहीं है। माली-आधारित प्रणालियों के लिए मुझे लगता है कि आपको ईटीसी का उपयोग करने की आवश्यकता है, जो किसी अन्य सिस्टम पर भी * खुलासा * है (विक्रेता के आधार पर) –