2012-06-11 7 views
5

मैं एक ऐसे प्रोजेक्ट पर काम कर रहा हूं जिसमें एक स्क्रीन पर आकार खींचने के लिए उपयोगकर्ता GLSurfaceView से बातचीत कर सकता है। यह सब ठीक और बेवकूफ काम करता है, लेकिन अब मैं दो चीजों को करने का प्रयास कर रहा हूं: 1) उनके चित्र का एक थंबनेल बनाएं, और 2) अपनी ड्राइंग को सहेजें। यह ध्यान रखना महत्वपूर्ण है कि उपयोगकर्ता एक छवि खींच सकता है जो स्क्रीन से बड़ा है।जीएल 1.0 या 1.1 का उपयोग करने के लिए ओपनजीएल बफर को मजबूर करना?

जहां तक ​​मेरा शोध दिखाता है, यह Bitmap (जो 1 हो सकता है)पर थंबनेल के लिए प्रदान किया जाता है, और 2) फ़ाइल सिस्टम में सहेजा जा सकता है, जो मेरे दोनों लक्ष्यों को प्राप्त करता है)।

प्रारंभ में, मैंने Renderer को GLSurfaceView से glReadPixels के माध्यम से पढ़ने की कोशिश की, लेकिन यह पता चला कि मुझे इससे ऑफ-स्क्रीन डेटा नहीं मिल सका। इसके बजाय, मैंने छवि के प्रस्तुत करने के लिए ऑफ़-स्क्रीन बफर करने का विकल्प चुना, जिसे Bitmap में परिवर्तित किया जा सकता था।

मुझे lovely post मिला जो PixelBuffer नामक कक्षा के लिए एक कोड प्रदान करता है, जिसे मैं अब उपयोग कर रहा हूं। (मैंने कुछ बदलाव किए हैं, लेकिन मेरे द्वारा किए गए सभी मुद्दों के साथ या बिना ट्विकिंग के किए गए हैं।)

अब कोड के getBitmap() का उपयोग करते समय (जिसे मैं PixelBuffer फ़ोरम थ्रेड में नीचे पोस्ट करूंगा अपठनीय है), मुझे called unimplemented OpenGL ES API का गुच्छा मिलता है। इसने मुझे पहले अजीब के रूप में मारा, इसलिए मैंने कुछ जांच की। यह पता चला है कि, किसी कारण से, PixelBuffer कक्षा OpenGL ES 2.0 का उपयोग कर रही है, जबकि GLSurfaceView OpenGL ES 1.1 का उपयोग कर रहा है। मैं जिस डिवाइस का उपयोग कर रहा हूं (गैलेक्सी नेक्सस) 2.0 का समर्थन नहीं करता है। (और इसके अलावा, मैं संभव उपकरणों की सबसे बड़ी श्रृंखला का समर्थन करना चाहते हैं।)

तो, यहाँ है मेरे सवाल: मैं OpenGL ES 1.1 एपीआई का उपयोग करने के लिए अपने PixelBuffer वर्ग कैसे मजबूर कर सकते हैं? ,

<uses-feature android:glEsVersion="0x00010001" /> 

साथ ही, मैं int[] version = new int[] { 1, 1 }; का उपयोग कर संस्करण स्थापित करने के लिए प्रयास किया है कोई लाभ नहीं हुआ: मैं पहले से ही मेरे प्रकट में निम्नलिखित शामिल किया है।

PixelBuffer कोड मैं उपयोग कर रहा हूं: Link। प्रश्न में पंक्ति जो Renderer को कॉल करती है, वह लाइन 91 पर है। संस्करण कोड लाइन 39-आइस ऑनवर्ड पर है।

इस कोड मैं PixelBuffer, GLSurfaceView वस्तु से कहा जाता है बनाने के लिए उपयोग है: सबसे अच्छा तरीका है कन्वर्ट करने के लिए

setEGLConfigChooser(8, 8, 8, 8, 0, 0); 
    mRenderer = new MyRenderer(this); 
    setRenderer(mRenderer); 
    mPixelBuffer = new CPPixelBuffer(1440, 1280); // TODO Temporary hardcode for Galaxy Nexus wallpaper size 
    mPixelBuffer.setRenderer(mRenderer); 

यदि यह संभव एक गुप्त के लिए संस्करण 1.1 उपयोग करने के लिए प्रस्तुत करना नहीं है, क्या है मेरी संस्करण 1.1 या उससे कम का उपयोग कर Bitmap पर जीएल सतह?

संपादित:

// int[] version = new int[2]; 
int[] version = new int[] { // When using this line, as well as the other marked lines, instead of the line above, the errors are produced. 
    1, 1 // Marked 
}; // Marked 
int[] attribList = new int[] { 
    EGL_WIDTH, mWidth, 
    EGL_HEIGHT, mHeight, 
    EGL_VERSION, 1, // Marked 
    EGL_NONE 
}; 

06-11 15:41:52.316: E/libEGL(5618): eglMakeCurrent:674 error 3009 (EGL_BAD_MATCH) 
06-11 15:41:52.316: E/libEGL(5618): call to OpenGL ES API with no current context (logged once per thread) 

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

+0

अंदर बुलाया जाना चाहिए वास्तव में गैलेक्सी नेक्सस ओपन ES 2.0 ठीक समर्थन करता है। कौन सा फ़ंक्शन कॉल आपको "अनुपूरक ओपनजीएल ईएस एपीआई" देता है? यदि वह PBufferSurface निर्माण है, तो इसके लिए अलग-अलग विशेषताओं का उपयोग करने का प्रयास करें। या बेहतर बस इसे छोड़ दें, और फ्रेमबफर से glGreadPixels का उपयोग करें। –

+0

सभी विधियां ('ऑनड्राफ्रेम 'कॉल में) इसे मुझे दें। यहां तक ​​कि 'gl.glLoadIdentity() '; मेरी खिड़की सचमुच उनके द्वारा स्पैम किया गया है। यह 2.0-विशिष्ट कुछ नहीं है, यही कारण है कि यह मेरे लिए इतना अजीब है। _ (हालांकि, यह पुराने 1.1-संगत उपकरणों के लिए समस्या का समाधान नहीं करता है ...) _ – Eric

+0

क्या आपके पास थ्रेड के लिए जीएल संदर्भ बनाया गया है जहां आप gl ... फ़ंक्शन का आविष्कार कर रहे हैं? –

उत्तर

2

मुझे कुछ कारणों से कोई टिप्पणी पोस्ट करने का कोई कारण नहीं मिला, इसलिए इसे उत्तर के रूप में पोस्ट करने के बारे में खेद है।जीएल धागे के बारे में, आमतौर पर आप केवल

public void onDrawFrame(GL10 gl) 

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

इसके अलावा, इस उदाहरण पर नजर: Android OpenGL Screenshot मैं इसे इस्तेमाल किया है और यह मेरे लिए काम किया है, लेकिन मैं ऑफ स्क्रीन क्षेत्र को बचाने के लिए जरूरत नहीं थी, इसलिए मैं अगर यह काम करेगा, शायद नहीं पता नहीं है :)

विधि onDrawFrame

+0

यहां तक ​​कि वैध 'जीएल 10' ऑब्जेक्ट में भी पास किया गया है? यह केवल रेंडरर के कोडिंग पर पिग-बैक होना चाहिए (जिनमें से अधिकांश मेरे द्वारा है, 'रेंडरर क्लास से नहीं), और अपने स्वयं के जीएल ऑब्जेक्ट पर प्रस्तुत करें। – Eric

+0

क्या आपका मतलब अलग थ्रेड में एक और तरीका है? यदि ऐसा है, तो हाँ, आप वैध GL10 ऑब्जेक्ट पास करने के बावजूद भी उपयोग नहीं कर पाएंगे। आपको केवल इसका इस्तेमाल करना होगा। कल्पना करें कि सभी गेम कैसे लिखे गए हैं: कुछ समय लूप है जिसमें सबकुछ किया जाता है। उदाहरण के लिए गणित की गणना अन्य धागे में की जा सकती है, लेकिन आप परिणाम को थ्रेड में संभालते हैं जहां आप प्रस्तुत करते हैं, और जीएल ऑब्जेक्ट्स प्रतिपादन धागे में मान्य होते हैं, क्योंकि जीएल ऑब्जेक्ट भी होते हैं। एंड्रॉइड स्मार्ट है और आपको यह इंगित करता है, सी ++ में आपको केवल क्रैश मिलेगा या उल्लंघन का उपयोग होगा :) – XMight

+0

वे दोनों एक ही जीएल थ्रेड साझा करते हैं। यह मूल रूप से एक दूसरी वस्तु ('पिक्सेलबफर') है जिसमें सदस्य परिवर्तक के रूप में 'रेंडरर' है; वे एक धागा और एक संदर्भ साझा करते हैं। यह मूल रूप से 'mRenderer.onDrawFrame (<कस्टम जीएल ऑब्जेक्ट>)' कहता है। – Eric

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