कैसे पता लगाएं कि ओपनग्ल टेक्सचर फॉर्मेट का मूल रूप से समर्थन किया जाता है?


10

उदाहरण के लिए, कैसे पता लगाया जाए कि मेरा वीडियोकार्ड "bgr8" का समर्थन नहीं करता है और इसे किसी अन्य प्रारूप में परिवर्तित करता है, जैसे सॉफ्टवेयर मोड में "rgba8"।

अद्यतन: भ्रम के लिए क्षमा करें। यह सवाल स्थिति के बारे में अधिक है जब मैं सेट internalFormat में glTexImage2D "bgra8" की तरह कुछ करने के लिए लेकिन videodriver आंतरिक रूप से किसी अन्य स्वरूप में डेटा परिवर्तित, "rgba8" की तरह।

जवाबों:


11

आपका प्रश्न कुछ अवधारणाओं को भ्रमित करने वाला प्रतीत होता है, तो आइए ऊपर से चीजों को लें। यह फ़ंक्शन की परिभाषा है glTexImage2D:

void glTexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, void *data );

दो चीजें हैं जिन्हें आप "बनावट प्रारूप" कह सकते हैं। पहला internalformatपैरामीटर है। यह छवि का वास्तविक प्रारूप है क्योंकि OpenGL इसे संग्रहीत करता है। formatपैरामीटर पिक्सेल डेटा का प्रारूप के हिस्से का वर्णन आप के साथ प्रदान कर रहे हैं dataपैरामीटर।

इसे दूसरे तरीके से रखने के लिए, formatऔर typeपरिभाषित करें कि आपका डेटा कैसा दिखता है। internalformatआप अपने डेटा को स्टोर करने के लिए OpenGL को कैसे बता रहे हैं । हमें कॉल करें formatऔर type"पिक्सेल स्थानांतरण प्रारूप", जबकि internalformat"छवि प्रारूप" होगा।

एक बनावट का छवि प्रारूप "bgr8" कभी नहीं हो सकता। कोई GL_BGR8 छवि प्रारूप एन्यूमरेटर नहीं है। वहाँ है एक GL_BGR enum, लेकिन यह है कि पिक्सेल हस्तांतरण प्रारूप, नहीं छवि प्रारूप के लिए है।

या इसे दूसरे तरीके से रखने के लिए, आपका पिक्सेल डेटा जो आप ओपनजीएल देते हैं, उसे बीजीआर क्रम में संग्रहीत किया जा सकता है। लेकिन ओपनजीएल कार्यान्वयन स्वयं तय करता है कि वास्तव में उस पिक्सेल डेटा को कैसे संग्रहीत किया जाए। शायद यह इसे छोटे-एंडियन क्रम में संग्रहीत करता है। हो सकता है कि वह इसे बड़े-एंडियन स्टोर करता हो। हो सकता है कि यह सिर्फ मनमाने ढंग से बाइट्स को फिर से व्यवस्थित करता है। आप नहीं जानते, और OpenGL पता लगाने के लिए एक तरीका प्रदान नहीं करता है।

यह बताने का कोई तरीका नहीं है कि क्या पिक्सेल स्थानांतरण प्रारूप मापदंडों का एक विशेष सेट मेल खाता है कि OpenGL कार्यान्वयन उन्हें कैसे छवि प्रारूप को संग्रहीत करेगा।

वहाँ एक तरीका है अब बताने के लिए। और "अब" से मेरा मतलब ओपनजीएल 4.3 और / या ARB_internalformat_query2 से है। आपके पास एक ग्राफिक्स कार्ड आ रहा है:

GLenum format, type;
glGetInternalformativ(texture_target, GL_RGBA8, GL_TEXTURE_IMAGE_FORMAT, 1, &format);
glGetInternalformativ(texture_target, GL_RGBA8, GL_TEXTURE_IMAGE_TYPE, 1, &type);

formatऔर typeअब कार्यान्वयन की पसंद formatऔर छवियों के लिए कॉल का typeउपयोग glTex(Sub)Imageकरने के लिए GL_RGBA8है। डाउनलोड के लिए अलग formatऔर typeक्वेरीज़ हैं glReadPixels

कर रहे हैं अन्य प्रश्नों के आप कमा सकते हैं

यदि आपके पास इन तक पहुंच नहीं है, तो आप अंगूठे के कुछ सामान्य नियमों का उपयोग कर सकते हैं जो अधिकांश हार्डवेयर का पालन करेंगे:

  • बीजीआरए क्रम में 8-बिट-प्रति-चैनल डेटा के लिए पिक्सेल डेटा स्टोर करेगा। इसलिए यदि आप अपने पिक्सेल डेटा के साथ प्रारूप का मिलान करना चाहते हैं, तो अधिक तेज़ी से बनावट डेटा अपलोड करने के लिए, आप GL_BGRAके लिए format, और GL_UNSIGNED_INT_8888या के GL_UNSIGNED_BYTEलिए उपयोग करना चाहते हैं type
  • वास्तव में 24-बिट रंगों को 24-बिट्स के रूप में संग्रहीत नहीं करेगा। यह हमेशा उन्हें 32-बिट तक पैड देगा; जब यह डेटा पढ़ेगा तो अल्फा को नजरअंदाज कर दिया जाएगा। तो अगर आप, प्रारूपों से मेल हमेशा उपयोग करना चाहते हैं GL_BGRA formatके साथ GL_RGB8छवि प्रारूप, आप अल्फा घटक में डमी डेटा डाल करने के लिए है, भले ही।

4
मैं के साथ internalFormat GL_RGBA भी बेहतर इस्तेमाल प्रारूप GL_BGRA पाया http.download.nvidia.com/developer/Papers/2005/...
KindDragon

मैं इंटरफ़ॉर्मैट पैरामीटर को "छवि प्रारूप" के रूप में रीब्रांड करने से बचना चाहूंगा, क्योंकि यह समान रूप से भ्रमित है। शायद यह "आंतरिक पिक्सेल" "बनावट पिक्सेल प्रारूप" के रूप में सोचने के लिए समझ में आता है। "प्रारूप" और "प्रकार" पैरामीटर संयोजन "स्रोत पिक्सेल प्रारूप" (जो अक्सर एक छवि है, इसलिए मेरी टिप्पणी है)। और फिर निश्चित रूप से GPU प्रारूप है, जो पूर्णांक प्रकार के प्रारूपों के लिए BGRA है।
StarShine

6

आम तौर पर अधिकांश हार्डवेयर 3-घटक बनावट स्वरूपों को सुपरपोर्ट नहीं करते हैं इसलिए इस विशिष्ट उदाहरण में आप एक यथोचित सुरक्षित धारणा बना सकते हैं कि यह परिवर्तित हो गया है। एक 3-घटक OpenGL बनावट वास्तव में हार्डवेयर में 4-घटक है लेकिन अल्फा घटक को अनदेखा / सेट करने के लिए 255 / जो भी हो।

https://www.khronos.org/opengl/wiki/Common_Mistakes#Texture_upload_and_pixel_reads (यह "सामान्य गलतियाँ" पृष्ठ एक सोने की खान है - इसे अभी बुकमार्क करें!)

एक अधिक सामान्य मामले के लिए, glTexSubImage2D प्रदर्शन आपको एक अच्छा संकेत दे सकता है कि अपलोड को सॉफ़्टवेयर रूपांतरण पथ के माध्यम से जाना चाहिए या नहीं। कार्यक्रम स्टार्टअप के दौरान आप इसके बारे में जाने - बस एक खाली बनावट (NULL डेटा के साथ glTexImage2D के माध्यम से) बनाएं, फिर glTexSubImage2D कॉल का एक गुच्छा जारी करें, प्रत्येक एक glFinish द्वारा पीछा किया जाता है ताकि यह सुनिश्चित हो सके। पहले वाले को अनदेखा करें क्योंकि इसके लिए कैश / स्टेट्स / आदि सेटअप किए जा रहे हैं, और बाकी समय। कुछ अलग प्रारूपों के लिए इसे दोहराएं और सबसे तेज़ चुनें।

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

यह वास्तव में अंगूठे का एक उपयोगी नियम है कि डी 2 डी प्रलेखन के साथ ओपनजीएल में आप क्या कर रहे हैं। अगर डी 3 डी कुछ नहीं कर सकता है, तो यह एक अच्छा संकेत हो सकता है कि प्रश्न में कुछ हार्डवेयर में समर्थित नहीं है। हमेशा सच नहीं है, लेकिन एक उपयोगी शुरुआती जगह है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.