2012-05-23 35 views
6

मैं opengl es 2.0 का उपयोग कर एक एंड्रॉइड 2 डी गेम प्रोग्रामिंग कर रहा हूं। बैकबफर में अपने स्प्राइट्स खींचने के बाद मैं रोशनी को एफबीओ में खींचता हूं और इसे फिर से बैफर बफर में मिश्रित करने का प्रयास करता हूं। जब मैं फ्रेमबफर पर एफबीओ खींचता हूं, बिना किसी रंग के ट्रांस्पैरेंट, फ़्रेमेट्स सैमसंग गैलेक्सी डब्ल्यू पर 60 से 30 तक गिर जाता है (इसमें एक एड्रेनो 205 जीपीयू है)। मैंने हर जगह खोज की और सब कुछ करने की कोशिश की, भले ही मैं दृश्य पर एक स्प्राइट खींचना चाहूं और फ्रेमरेट बूंदों को स्क्रीन पर एक पारदर्शी एफबीओ बनावट को मिश्रित कर दूं। मैंने उस फोन पर प्रकाश प्रभाव के साथ अन्य खेलों की कोशिश की और वे ठीक चलते हैं, लगभग हर गेम उस फोन पर ठीक है, मुझे विश्वास है कि वे फ्रेमबफर का भी उपयोग करते हैं। गैलेक्सी एसआईआई (माली 400 जीपीयू) पर ठीक चल रहा है, मैं ओपनगल के लिए काफी नया हूं इसलिए मुझे विश्वास है कि मैं कहीं गलती कर रहा हूं, मैं अपना कोड साझा करता हूं।एंड्रॉइड पर ओपनजीएल ईएस 2.0 का उपयोग करते हुए फ़्रेमबफर एफबीओ बनावट को प्रस्तुत करना बहुत धीमा है, क्यों?

// Create a framebuffer and renderbuffer 
GLES20.glGenFramebuffers(1, fb, offset); 
GLES20.glGenRenderbuffers(1, depthRb, offset); 

// Create a texture to hold the frame buffer 
GLES20.glGenTextures(1, renderTex, offset); 
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTex[offset]); 

GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 
        screenWidth, screenHeight, 0, 
        GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, 
        null); 


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); 
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, 
         GLES20.GL_LINEAR); 
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, 
         GLES20.GL_LINEAR); 

//bind renderbuffer 
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depthRb[offset]); 

GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, 
          screenWidth, screenHeight); 

// bind the framebuffer 
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb[offset]); 

// specify texture as color attachment 
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, 
           GLES20.GL_TEXTURE_2D, renderTex[offset], 0); 

// specify depth_renderbufer as depth attachment 
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, 
           GLES20.GL_RENDERBUFFER, depthRb[0]); 

// Check FBO status. 
int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER); 

if (status == GLES20.GL_FRAMEBUFFER_COMPLETE) 
{ 
    Log.d("GLGame framebuffer creation", "Framebuffer complete"); 
} 


// set default framebuffer 
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); 

मैं इसे सतह निर्माण पर एक बार करता हूं। सुनिश्चित नहीं है कि सही है या नहीं। जब मुझे आवश्यकता हो तो मैं उन्हें स्विच करने के लिए बनावट और फ्रेमबफर आईडी रखता हूं। मेरे ड्राइंग कोड:

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId); 
ShaderProgram program = glgame.getProgram(); 

//put vertices in the floatbuffer 
mTriangleVertices.put(vertices, 0, len); 
mTriangleVertices.flip(); 

GLES20.glVertexAttribPointer(program.POSITION_LOCATION, 2, GLES20.GL_FLOAT, false, 
          TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices); 

//preparing parameter for texture position 
mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); 
GLES20.glEnableVertexAttribArray(program.POSITION_LOCATION); 

//preparing parameter for texture coords 
GLES20.glVertexAttribPointer(program.TEXTURECOORD_LOCATION, 2, GLES20.GL_FLOAT, 
          false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, 
          mTriangleVertices); 

//set projection matrix 
GLES20.glEnableVertexAttribArray(program.TEXTURECOORD_LOCATION); 
GLES20.glUniformMatrix4fv(program.MATRIX_LOCATION, 1, false, matrix, 0); 

//draw triangle with indices to form a rectangle 
GLES20.glDrawElements(GLES20.GL_TRIANGLES, numSprites * 6, GLES20.GL_UNSIGNED_SHORT, 
         indicesbuf); 

//clear buffers 
mTriangleVertices.clear(); 
mVertexColors.clear(); 

सब कुछ स्क्रीन पर सही ढंग से प्रदान की गई है, लेकिन प्रदर्शन को बर्बाद कर दिया जाता है तो बस जब मैं FBO बनावट आकर्षित। आपकी मदद के लिए बहुत बहुत धन्यवाद। मैंने इस पर बहुत मेहनत की और समाधान नहीं मिला।

+0

देर से जवाब, लेकिन मैं आईसीएस के तहत एचडी 2 पर कुछ ऐसा कर रहा हूं और यह काफी समान है। मैं 60 एफपीएस पर कोई समस्या नहीं दे सकता, लेकिन जब मैं एफबीओ का उपयोग करता हूं, फ्रेम दर 45 हो जाती है, और यदि मैं एक और एफबीओ का उपयोग करता हूं तो यह 30 हो जाता है। –

+0

हम्म ... मैंने सैमसंग पर कुछ गेम देखे हैं गैलेक्सी डब्ल्यू समस्याओं के बिना चल रहा है और वे 2 डी रोशनी के लिए फ्रेमबफर का उपयोग करना प्रतीत होता है, मेरा कोड धीरे-धीरे चलता है। मुझे आश्चर्य है कि मैं गलती कर रहा हूं। – mao

+0

गैलेक्सी एसजीएक्स चिपसेट का उपयोग करता है। जैसा कि मैंने छोटे जीएमएम और टाइल आर्किटेक्चर से संबंधित कहा था, हर बार जब आप फ्रेमबफर को बदलते हैं तो आपको सामान्य मेम पर कॉपी करने की आवश्यकता होती है, अगर आप इसे बांधने के बाद पहले कॉल के रूप में साफ़ कर देंगे तो इसे सामान्य से वापस कॉपी करने की आवश्यकता नहीं है gmem को याद रखें, यही कारण है कि फ़्रेमबफर विशेष रूप से एड्रेनो 200 पर धीमे होते हैं :) यदि आप एड्रेनो डिवाइस हैं, तो आप एड्रेनो प्रोफाइलर के साथ फ्रेमबफर का उपयोग करके ऐप देख सकते हैं, बस इसे प्लग करें और वर्तमान फ्रेम डाउनलोड करें, फिर बनावट में एफबी की जांच करें। यदि आप एक पाएंगे, तो आप सुनिश्चित होंगे कि – ZZZ

उत्तर

12

क्वालकॉम दस्तावेज़ों के मुताबिक, आपको प्रत्येक ग्लिबिंडफ्रेमबफर के बाद ग्लक्लर करने की आवश्यकता है, यह फ़ाइलबफर स्विच कर रहे हैं, तो टाइल किए गए आर्किटेक्चर से संबंधित एक समस्या है, डेटा को फास्टमेम से सामान्य मेमोरी में कॉपी करने की आवश्यकता है ताकि मौजूदा फ्रेमबफर और धीमी गति से बचाया जा सके। नए बाध्य फ्रेम की सामग्री प्राप्त करने के लिए तेज़ मेम, यदि आप ग्लिबिंड के बाद ही साफ़ कर रहे हैं तो धीमी गति से फास्टमेम तक कोई डेटा कॉपी नहीं किया गया है और आप समय बचा रहे हैं, लेकिन आपको अक्सर अपनी रेंडर पाइपलाइन को फिर से डिजाइन करना होगा, इसलिए यह डेटा को वापस पढ़ने से बच जाएगा और धीमी और तेज स्मृति के बीच आगे, इसलिए प्रत्येक बाइंड के बाद ग्लैक्लर करने का प्रयास करें और इसे मदद करनी चाहिए, आप समस्याग्रस्त कॉल के बारे में अतिरिक्त जानकारी प्राप्त करने के लिए एड्रेनो प्रोफाइलर का भी उपयोग कर सकते हैं, लेकिन मुझे संदेह है कि यह एड्रेनो 200 के साथ मदद करेगा मैं दो बफर पाने की कोशिश कर रहा हूं धुंधला और मैं 10fps के साथ समाप्त कर रहा हूँ, bindframebuffer कॉल 20msec तक ले सकता है अगर इसे साफ़ नहीं किया जाता है, अगर यह शू है 2 एमएम पर uld अंत।

+0

जैसे ही मैं एड्रेनो 205 पर अपने हाथ फिर से प्राप्त कर सकता हूं, मैं इसे आजमाउंगा। मुझे क्वालकॉम प्रलेखन मिला और मैं इसका अनुसरण करूंगा। मदद के लिए आपका बहुत बहुत धन्यवाद! – mao

+0

[यहां] (https://www.google.sk/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&ved=0CDEQFjAA&url=https%3A%2F%2Fdeveloper.qualcomm.com%2Fdownload%2Fadreno200performanceoptimizationopenglestipsandtricksmarch10 .pdf और ei = DT6IUcaTMYXV4ASEwYHYAQ और usg = AFQjCNFbU3Vf2mT2sf7LTAJQ3xqijdyUAA और sig2 = JMoeTn8G1MQgor9ZGDdFQg और bvm = bv.45960087, d.bGE) क्वालकॉम दस्तावेज़ है। –

+1

यदि आप फ्रेमबफर की सामग्री को संरक्षित करना चाहते हैं, तो बस 'glClear (0);', जो समस्या को ठीक करने के लिए प्रतीत होता है। – Thomas