खोज…


फ्रेमबफर्स की मूल बातें

फ़्रेमबफ़र एक प्रकार का बफर है जो मेमोरी में पिक्सेल के रंग मूल्यों, गहराई और स्टैंसिल जानकारी संग्रहीत करता है। जब आप ओपनजीएल में कुछ आकर्षित करते हैं तो आउटपुट डिफ़ॉल्ट फ्रेमबफ़र में संग्रहीत होता है और फिर आप वास्तव में स्क्रीन पर इस बफर के रंग मूल्यों को देखते हैं। आप अपना स्वयं का फ्रेमबफ़र भी बना सकते हैं, जो कि ग्रे-स्केल, कलंक, क्षेत्र की गहराई, विकृतियों, प्रतिबिंबों जैसे कई शांत पोस्ट-प्रोसेसिंग प्रभावों के लिए उपयोग किया जा सकता है ...

शुरू करने के लिए आपको एक फ्रेम बफ़र ऑब्जेक्ट ( FBO ) बनाने और इसे OpenGL में किसी अन्य ऑब्जेक्ट की तरह बाँधने की आवश्यकता है:

unsigned int FBO;
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);  

अब आपको कम से कम एक अनुलग्नक (रंग, गहराई या स्टैंसिल) को फ्रेमबफ़र में जोड़ना होगा। अनुलग्नक एक मेमोरी लोकेशन है जो फ्रेमबफ़र के लिए बफर के रूप में कार्य करता है। यह या तो एक बनावट , या एक रेंडरबफ़र ऑब्जेक्ट हो सकता है । बनावट का उपयोग करने का लाभ यह है कि आप इस बनावट का उपयोग प्रसंस्करण के बाद के शेड में आसानी से कर सकते हैं। बनावट का निर्माण एक सामान्य बनावट के समान है:

unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

width और height आपके रेंडरिंग विंडो के आकार के समान होनी चाहिए। बनावट डेटा सूचक है NULL क्योंकि आप केवल स्मृति को आबंटित करने और किसी भी डेटा के साथ बनावट भर नहीं चाहते हैं। बनावट तैयार है ताकि आप वास्तव में इसे फ्रेमबफ़र से जोड़ सकें:

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);  

आपका फ़्रेमबफ़र अब उपयोग करने के लिए तैयार होना चाहिए, लेकिन आप गहराई से लगाव या दोनों गहराई और स्टैंसिल संलग्नक भी जोड़ना चाह सकते हैं। यदि आप उन्हें बनावट संलग्नक के रूप में जोड़ना चाहते हैं (और उन्हें कुछ प्रसंस्करण के लिए उपयोग करते हैं) तो आप ऊपर की तरह एक और बनावट बना सकते हैं। इन पंक्तियों में एकमात्र अंतर होगा:

glTexImage2D(
    GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, 
    GL_DEPTH_COMPONENT, GL_FLOAT, NULL
);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture, 0);

या यदि आप एक ही बनावट में गहराई और स्टेंसिल लगाव का उपयोग करना चाहते हैं:

glTexImage2D(
    GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, width, height, 0, 
    GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL
);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture, 0);

यदि आप बाद में मूल्यों को संसाधित नहीं करना चाहते हैं, तो आप गहराई और स्टेंसिल बफ़र्स के लिए अनुलग्नक के रूप में बनावट के बजाय रेंडरबफ़र का उपयोग कर सकते हैं। (इसे एक अन्य उदाहरण में समझाया जाएगा ...)

आप जाँच सकते हैं कि क्या फ्रेमबफ़र सफलतापूर्वक बनाया गया है और बिना किसी त्रुटि के पूरा हुआ है:

if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
    // do something...

और आखिरकार फ्रेमबफ़र को अनबाइंड करना न भूलें ताकि आप गलती से इसे प्रस्तुत न करें:

glBindFramebuffer(GL_FRAMEBUFFER, 0);  

सीमाएं

रंग बफ़र की अधिकतम संख्या जो एकल फ्रेम बफर से जुड़ी हो सकती है, वह पैरामीटर GL_MAX_COLOR_ATTACHMENTS का उपयोग करके OGL फ़ंक्शन glGetIntegerv द्वारा निर्धारित किया जा सकता है:

GLint maxColAttchments = 0;
glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS, &maxColAttchments );

फ़्रेमबफ़र का उपयोग करना

उपयोग काफी सीधा है। सबसे पहले आप अपने फ्रेम बफ़र को बांधते हैं और अपने दृश्य को उसमें प्रस्तुत करते हैं। लेकिन आप वास्तव में अभी तक कुछ भी नहीं देखेंगे क्योंकि आपका रेंडरबफ़र दिखाई नहीं दे रहा है। तो दूसरा भाग स्क्रीन पर फुलस्क्रीन क्वाड की बनावट के रूप में आपके फ्रेमबफ़र को प्रस्तुत करना है। आप इसे बस प्रस्तुत कर सकते हैं जैसा कि यह है या कुछ पोस्ट-प्रोसेसिंग प्रभाव है।

यहां पूर्णस्क्रीन क्वाड के लिए वर्टिकल हैं:

float vertices[] = {
//   positions     texture coordinates
    -1.0f,  1.0f,  0.0f, 1.0f,
    -1.0f, -1.0f,  0.0f, 0.0f,
     1.0f, -1.0f,  1.0f, 0.0f,

    -1.0f,  1.0f,  0.0f, 1.0f,
     1.0f, -1.0f,  1.0f, 0.0f,
     1.0f,  1.0f,  1.0f, 1.0f
};

आपको उन्हें एक VBO में संग्रहीत करने या विशेषता बिंदुओं का उपयोग करके प्रस्तुत करने की आवश्यकता होगी। बनावट के साथ फुलस्क्रीन क्वाड को रेंडर करने के लिए आपको कुछ बेसिक शेडर प्रोग्राम की भी आवश्यकता होगी।

वर्टेक्स शेडर:

in vec2 position;
in vec2 texCoords;

out vec2 TexCoords;

void main()
{
    gl_Position = vec4(position.x, position.y, 0.0, 1.0); 
    TexCoords = texCoords;
}  

टुकड़े टुकड़े करना:

in vec2 TexCoords;
out vec4 color;

uniform sampler2D screenTexture;

void main()
{ 
    color = texture(screenTexture, TexCoords);
}

नोट: आपको GLSL के अपने संस्करण के लिए शेड्स को समायोजित करने की आवश्यकता हो सकती है।

अब आप वास्तविक प्रतिपादन कर सकते हैं। जैसा कि ऊपर वर्णित है, पहली बात यह है कि दृश्य को आपके FBO में प्रस्तुत करना है। ऐसा करने के लिए आप बस अपने FBO को बांधें, इसे साफ़ करें और दृश्य को ड्रा करें:

glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
// draw your scene here...   

नोट: glClear फ़ंक्शन में आपको उन सभी glClear अनुलग्नकों को निर्दिष्ट करना चाहिए जो आप उपयोग कर रहे हैं (उदाहरण के रंग और गहराई के लगाव में)।

अब आप अपने FBO को फुलस्क्रीन क्वाड पर डिफॉल्ट फ्रेमबफ़र के रूप में प्रस्तुत कर सकते हैं ताकि आप इसे देख सकें। ऐसा करने के लिए आप बस अपने FBO को अनबाइंड करें और क्वाड को रेंडर करें:

glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind your FBO to set the default framebuffer
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

shader.Use(); // shader program for rendering the quad  

glBindTexture(GL_TEXTURE_2D, texture); // color attachment texture
glBindBuffer(GL_ARRAY_BUFFER, VBO); // VBO of the quad
// You can also use VAO or attribute pointers instead of only VBO...
glDrawArrays(GL_TRIANGLES, 0, 6); 
glBindBuffer(GL_ARRAY_BUFFER, 0);

और बस यही! यदि आपने सब कुछ सही ढंग से किया है तो आपको पहले जैसा ही दृश्य देखना चाहिए लेकिन फुलस्क्रीन क्वाड पर प्रस्तुत करना चाहिए। दृश्य आउटपुट पहले जैसा ही है लेकिन अब आप आसानी से टुकड़े टुकड़े करने वाले को संपादित करके पोस्ट-प्रोसेसिंग प्रभाव जोड़ सकते हैं। (मैं दूसरे उदाहरण में प्रभाव जोड़ूंगा और इसे यहां लिंक करूंगा)



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow