सभी OpenGL ऑब्जेक्ट्स के बारे में
OpenGL ऑब्जेक्ट के लिए मानक मॉडल निम्नानुसार है।
वस्तुओं की अवस्था होती है। उन्हें एक के रूप में सोचो struct
। तो आपके पास इस तरह परिभाषित एक वस्तु हो सकती है:
struct Object
{
int count;
float opacity;
char *name;
};
ऑब्जेक्ट में कुछ निश्चित मान होते हैं और उसमें स्थिति होती है । OpenGL ऑब्जेक्ट्स में स्थिति भी होती है।
बदलती अवस्था
C / C ++ में, यदि आपके पास प्रकार है Object
, तो आप इसकी स्थिति निम्नानुसार बदल देंगे: obj.count = 5;
आप सीधे ऑब्जेक्ट की एक आवृत्ति का संदर्भ लेंगे, उस विशेष टुकड़े को प्राप्त करें, जिसे आप बदलना चाहते हैं, और इसमें एक मान निकाल दें।
ओपनजीएल में, आप ऐसा नहीं करते हैं।
विरासत के कारणों के लिए बेहतर अस्पष्टता छोड़ दी गई है, एक ओपन ऑब्जेक्ट की स्थिति को बदलने के लिए, आपको पहले इसे संदर्भ में बाँधना होगा। यह glBind*
कॉल से कुछ के साथ किया जाता है ।
इस के बराबर C / C ++ इस प्रकार है:
Object *g_objs[MAX_LOCATIONS] = {NULL};
void BindObject(int loc, Object *obj)
{
g_objs[loc] = obj;
}
बनावट दिलचस्प है; वे बंधन के एक विशेष मामले का प्रतिनिधित्व करते हैं। कई glBind*
कॉल में "लक्ष्य" पैरामीटर होता है। यह ओपनजीएल संदर्भ में विभिन्न स्थानों का प्रतिनिधित्व करता है जहां उस प्रकार की वस्तुओं को बाध्य किया जा सकता है। उदाहरण के लिए, आप पढ़ने ( GL_READ_FRAMEBUFFER
) या लिखने के लिए ( ) के लिए एक फ़्रेमबफ़र ऑब्जेक्ट को बांध सकते हैं GL_DRAW_FRAMEBUFFER
। यह प्रभावित करता है कि OpenGL बफर का उपयोग कैसे करता है। यह वही है जो loc
ऊपर पैरामीटर का प्रतिनिधित्व करता है।
बनावट विशेष है क्योंकि जब आप पहली बार उन्हें किसी लक्ष्य से बांधते हैं, तो उन्हें विशेष जानकारी मिलती है। जब आप पहली बार एक बनावट को एक के रूप में बांधते GL_TEXTURE_2D
हैं, तो आप वास्तव में बनावट में विशेष राज्य स्थापित कर रहे हैं। आप कह रहे हैं कि यह बनावट 2 डी बनावट है। और यह हमेशा एक 2 डी बनावट होगी; इस अवस्था को कभी नहीं बदला जा सकता है । यदि आपके पास एक बनावट है जो पहले एक के रूप में बंधी हुई थी GL_TEXTURE_2D
, तो आपको हमेशा इसे एक के रूप में बांधना चाहिए GL_TEXTURE_2D
; इसे बांधने का प्रयास GL_TEXTURE_1D
एक त्रुटि को जन्म देगा (जबकि रन-टाइम)।
एक बार जब वस्तु बाध्य होती है, तो इसकी स्थिति को बदला जा सकता है। यह उस वस्तु के लिए विशिष्ट सामान्य कार्यों के माध्यम से किया जाता है। वे एक स्थान भी लेते हैं जो संशोधित करने के लिए किस वस्तु का प्रतिनिधित्व करता है।
C / C ++ में, ऐसा दिखता है:
void ObjectParameteri(int loc, ObjectParameters eParam, int value)
{
if(g_objs[loc] == NULL)
return;
switch(eParam)
{
case OBJECT_COUNT:
g_objs[loc]->count = value;
break;
case OBJECT_OPACITY:
g_objs[loc]->opacity = (float)value;
break;
default:
//INVALID_ENUM error
break;
}
}
ध्यान दें कि यह फ़ंक्शन वर्तमान में बाध्य loc
मान में जो कुछ भी होता है वह कैसे सेट करता है ।
बनावट वस्तुओं के लिए, मुख्य बनावट राज्य बदलते कार्य हैं glTexParameter
। बनावट की स्थिति को बदलने वाले केवल अन्य कार्य ही glTexImage
कार्य और उनकी विविधताएँ हैं ( glCompressedTexImage
, glCopyTexImage
हाल ही में glTexStorage
)। विभिन्न SubImage
संस्करण बनावट की सामग्री को बदलते हैं, लेकिन वे तकनीकी रूप से इसकी स्थिति को नहीं बदलते हैं । Image
कार्यों बनावट भंडारण आवंटन और बनावट के प्रारूप सेट; SubImage
कार्यों सिर्फ पिक्सल के आसपास नकल। इसे बनावट की स्थिति नहीं माना जाता है।
मुझे दोहराने की अनुमति दें: ये एकमात्र कार्य हैं जो बनावट स्थिति को संशोधित करते हैं। glTexEnv
पर्यावरण राज्य को संशोधित करता है; यह बनावट की वस्तुओं में संग्रहीत कुछ भी प्रभावित नहीं करता है।
सक्रिय बनावट
बनावट के लिए स्थिति अधिक जटिल है, फिर से विरासत के कारणों के लिए सबसे अच्छा अज्ञात है। यह वह जगह है जहाँ glActiveTexture
अंदर आता है
बनावट के लिए, वहाँ सिर्फ लक्ष्य (नहीं कर रहे हैं GL_TEXTURE_1D
, GL_TEXTURE_CUBE_MAP
, आदि)। बनावट इकाइयाँ भी हैं । हमारे C / C ++ उदाहरण के संदर्भ में, हमारे पास यह क्या है:
Object *g_objs[MAX_OBJECTS][MAX_LOCATIONS] = {NULL};
int g_currObject = 0;
void BindObject(int loc, Object *obj)
{
g_objs[g_currObject][loc] = obj;
}
void ActiveObject(int currObject)
{
g_currObject = currObject;
}
ध्यान दें कि अब, हमारे पास न केवल 2 डी की सूची है Object
, बल्कि हमारे पास एक वर्तमान वस्तु की अवधारणा भी है। हमारे पास वर्तमान ऑब्जेक्ट को सेट करने के लिए एक फ़ंक्शन है, हमारे पास वर्तमान ऑब्जेक्ट की अधिकतम संख्या की अवधारणा है, और हमारे सभी ऑब्जेक्ट हेरफेर फ़ंक्शन को वर्तमान ऑब्जेक्ट से चयन करने के लिए समायोजित किया गया है।
जब आप वर्तमान में सक्रिय ऑब्जेक्ट को बदलते हैं, तो आप लक्ष्य स्थानों के पूरे सेट को बदलते हैं। तो आप ऐसी चीज़ को बाँध सकते हैं जो वर्तमान ऑब्जेक्ट 0 में जाती है, वर्तमान ऑब्जेक्ट 4 पर स्विच करें, और पूरी तरह से अलग ऑब्जेक्ट को संशोधित करेगा।
बनावट की वस्तुओं के साथ यह समानता बिल्कुल सही है ... लगभग।
देखें, glActiveTexture
पूर्णांक नहीं लेता है; यह एक प्रगणक लेता है । जिसका सिद्धांत में अर्थ है कि यह कुछ भी से ले सकता GL_TEXTURE0
है GL_TEXTURE31
। लेकिन एक बात आपको समझनी चाहिए:
यह गलत है!
वास्तविक सीमा जो glActiveTexture
ले जा सकती है वह नियंत्रित होती है GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
। यह एक साथ बहुपक्षीय अधिकतम संख्या है जो एक कार्यान्वयन की अनुमति देता है। ये प्रत्येक अलग-अलग shader चरणों के लिए अलग-अलग समूहों में विभाजित हैं। उदाहरण के लिए, जीएल 3.x वर्ग के हार्डवेयर पर, आपको 16 वर्टेक्स शेडर टेक्सचर, 16 फ्रैगर शैडर टेक्सचर, और 16 ज्यामिति शेडर टेक्सचर मिलते हैं। इसलिए, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
48 होगा।
लेकिन वहाँ 48 enumerators नहीं हैं। यही कारण glActiveTexture
है कि वास्तव में enumerators नहीं ले करता है। कॉल करने का सही तरीका glActiveTexture
इस प्रकार है:
glActiveTexture(GL_TEXTURE0 + i);
जहाँ i
0 और के बीच एक संख्या है GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
।
प्रतिपादन
तो यह सब प्रतिपादन के साथ क्या करना है?
शेड्स का उपयोग करते समय, आप अपनी नमूना वर्दी को एक बनावट छवि इकाई ( glUniform1i(samplerLoc, i)
, जहां i
छवि इकाई है) में सेट करते हैं। यह आपके द्वारा उपयोग की गई संख्या का प्रतिनिधित्व करता है glActiveTexture
। सैंपलर प्रकार के आधार पर लक्ष्यक चुन लेगा। तो एक लक्ष्य sampler2D
से ले जाएगा GL_TEXTURE_2D
। यह एक कारण है कि नमूने के विभिन्न प्रकार होते हैं।
अब यह संदिग्ध रूप से लगता है जैसे आपके पास दो जीएलएसएल नमूने हो सकते हैं, विभिन्न प्रकार के साथ जो एक ही बनावट छवि इकाई का उपयोग करते हैं। लेकिन आप नहीं कर सकते; OpenGL इसे मना करता है और रेंडर करने का प्रयास करने पर आपको एक त्रुटि देगा।
GL_TEXTURE0 + i
- मैं यह मानने के लिए कि क्या वैध था या नहीं, यह देखने के लिए अर्थ का निरीक्षण करना था। और आखिरी पैराग्राफ - पता नहीं था कि कानूनी था या नहीं। अति उत्कृष्ट! मैं आपके सभी उत्तरों को बुकमार्क कर रहा हूं ताकि मैं उन्हें फिर से संदर्भित कर सकूं।