खोज…


बनावट की मूल बातें

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

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

बनावट निर्देशांक

इस त्रिभुज की बनावट निर्देशांक इस तरह दिखेगा:

GLfloat texCoords[] = {
    0.0f, 0.0f,  // Lower-left corner  
    1.0f, 0.0f,  // Lower-right corner
    0.5f, 1.0f   // Top-center corner
};

उन निर्देशांक को VBO (वर्टेक्स बफर ऑब्जेक्ट) में डालें और शेडर के लिए एक नई विशेषता बनाएं। आपको पहले से ही शीर्ष पदों के लिए कम से कम एक विशेषता होनी चाहिए ताकि बनावट निर्देशांक के लिए एक और बनाएं।


बनावट उत्पन्न करना

एक बनावट वस्तु उत्पन्न करने के लिए पहली बात यह है कि एक आईडी द्वारा संदर्भित किया जाएगा जो एक अहस्ताक्षरित आंतरिक बनावट में संग्रहीत किया जाएगा:

GLuint texture;
glGenTextures(1, &texture); 

उसके बाद इसे बाध्य होना पड़ता है ताकि बाद की सभी बनावट कमांड इस बनावट को कॉन्फ़िगर करें:

glBindTexture(GL_TEXTURE_2D, texture); 

चित्र लोड हो रहा है

एक छवि लोड करने के लिए आप अपनी स्वयं की छवि लोडर बना सकते हैं या आप इस तरह के रूप में एक छवि लोडिंग पुस्तकालय का उपयोग कर सकते मिट्टी ग में (सरल ओपन छवि पुस्तकालय) ++ या TWL के PNGDecoder जावा में।

SOIL के साथ लोडिंग छवि का एक उदाहरण होगा:

int width, height;
unsigned char* image = SOIL_load_image("image.png", &width, &height, 0, SOIL_LOAD_RGB); 

अब आप इस चित्र को बनावट वस्तु पर नियत कर सकते हैं:

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

उसके बाद आपको बनावट वस्तु को खोलना चाहिए:

glBindTexture(GL_TEXTURE_2D, 0); 

बनावट निर्देशांक के लिए लपेटें पैरामीटर

जैसा कि ऊपर देखा गया है, बनावट के निचले बाएं कोने में UV (st) निर्देशांक (0, 0) है और बनावट के ऊपरी दाएं कोने में निर्देशांक (1, 1) है, लेकिन एक जाल की बनावट निर्देशांक में हो सकती है कोई भी सीमा। इसे संभालने के लिए, यह परिभाषित करना होगा कि बनावट कैसे बनावट से लिपटी है।

बनावट समन्वय के लिए रैप पैरामीटर glTextureParameter के साथ GL_TEXTURE_WRAP_S , GL_TEXTURE_WRAP_T और GL_TEXTURE_WRAP_R का उपयोग करके सेट किया जा सकता है।

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

संभव पैरामीटर हैं:

  • GL_CLAMP_TO_EDGE कारण बनावट निर्देशांक को [1 / 2N, 1 - 1 / 2N] सीमा तक ले जाया जाता है, जहां N दिशा में बनावट का आकार है।

  • GL_CLAMP_TO_BORDER के समान है, लेकिन ऐसे मामलों में जहां क्लैम्पिंग किया GL_CLAMP_TO_EDGE , GL_CLAMP_TO_EDGE डेटा को GL_TEXTURE_BORDER_COLOR द्वारा निर्दिष्ट रंग के साथ प्रतिस्थापित किया GL_TEXTURE_BORDER_COLOR

  • GL_REPEAT बनावट के पूर्णांक भाग को अनदेखा करने का कारण बनता है। बनावट टाइल की गई है

बार-बार बनावट

  • GL_MIRRORED_REPEAT : यदि बनावट का पूर्णांक भाग सम है, तो इसे अनदेखा कर दिया जाता है। इसके विपरीत, यदि बनावट का पूर्णांक भाग विषम है, तो बनावट समन्वय 1 - frac (s) पर सेट है। fract (s) बनावट समन्वय का भिन्नात्मक भाग है। इसके कारण बनावट हर 2 वें समय में प्रतिबिंबित होती है।

दर्पण बनावट

  • GL_MIRROR_CLAMP_TO_EDGE बनावट को एक बार फिर बनावट के एक पुनरावृत्ति के लिए GL_MIRRORED_REPEAT रूप में दोहराए GL_MIRROR_CLAMP_TO_EDGE कारण बनता है, जिस बिंदु पर निर्देशांक GL_CLAMP_TO_EDGE रूप में GL_CLAMP_TO_EDGE किया जा सकता है।

के लिए डिफ़ॉल्ट मान नोट GL_TEXTURE_WRAP_S , GL_TEXTURE_WRAP_T और GL_TEXTURE_WRAP_R है GL_REPEAT


बनावट लागू करना

ड्रॉ कॉल से पहले बनावट को बांधने के लिए आखिरी चीज है:

glBindTexture(GL_TEXTURE_2D, texture);

बनावट और फ़्रेमबफ़र

आप एक बनावट में एक फ़्रेमबफ़र के लिए एक छवि संलग्न कर सकते हैं, ताकि आप उस बनावट को सीधे प्रस्तुत कर सकें।

glGenFramebuffers (1, &framebuffer);
glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER,
                       GL_COLOR_ATTACHMENT0,
                       GL_TEXTURE_2D,
                       texture,
                       0);

नोट: आप एक ही रेंडर कार्य में एक ही बनावट से पढ़ और लिख नहीं सकते, क्योंकि यह अपरिभाषित व्यवहार कहता है। लेकिन आप इसके लिए रेंडर कॉल के बीच glTextureBarrier() उपयोग कर सकते हैं।

बनावट डेटा पढ़ें

आप फ़ंक्शन glGetTexImage साथ बनावट डेटा पढ़ सकते हैं:

char *outBuffer = malloc(buf_size);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);

glGetTexImage(GL_TEXTURE_2D,
              0,
              GL_RGBA,
              GL_UNSIGNED_BYTE,
              outBuffer);

नोट: बनावट प्रकार और प्रारूप केवल उदाहरण के लिए हैं और भिन्न हो सकते हैं।

PBO का उपयोग करना

आप के लिए एक बफर के लिए बाध्य हैं GL_PIXEL_UNPACK_BUFFER तो data में पैरामीटर glTexImage2D एक है कि बफर में ऑफसेट है।

इसका मतलब है कि glTexImage2D को मुख्य थ्रेड में ओवरहेड को कम करने से पहले सभी डेटा को एप्लिकेशन की मेमोरी से कॉपी किए जाने की प्रतीक्षा करने की आवश्यकता नहीं है।

glGenBuffers(1, &pbo);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
glBufferData(GL_PIXEL_UNPACK_BUFFER, width*height*3, NULL, GL_STREAM_DRAW);
void* mappedBuffer = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);

//write data into the mapped buffer, possibly in another thread.
int width, height;
unsigned char* image = SOIL_load_image("image.png", &width, &height, 0, SOIL_LOAD_RGB);
memcpy(mappedBuffer, image, width*height*3);
SOIL_free_image(image);

// after reading is complete back on the main thread
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);

लेकिन जहां पीबीओ वास्तव में चमकता है, जब आपको एप्लिकेशन मेमोरी में एक रेंडर का परिणाम पढ़ने की आवश्यकता होती है। एक बफर में पिक्सेल डेटा को पढ़ने के लिए करने के लिए यह बाँध GL_PIXEL_PACK_BUFFER तो की डाटा पैरामीटर glGetTexImage एक है कि बफर में ऑफसेट किया जाएगा:

glGenBuffers(1, &pbo);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
glBufferData(GL_PIXEL_PACK_BUFFER, buf_size, NULL, GL_STREAM_COPY);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);

glGetTexImage(GL_TEXTURE_2D,
              0,
              GL_RGBA,
              GL_UNSIGNED_BYTE,
              null);
//ensure we don't try and read data before the transfer is complete
GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);

// then regularly check for completion
GLint result;
glGetSynciv(sync, GL_SYNC_STATUS, sizeof(result), NULL, &result);
if(result == GL_SIGNALED){
    glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
    void* mappedBuffer = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);

    //now mapped buffer contains the pixel data

    glUnmapBuffer(GL_PIXEL_PACK_BUFFER);

}

GLSL शेड्स में टेक्सचर का उपयोग करना

वर्टेक्स शेडर केवल टेक्सचर कोऑर्डिनेट्स को वर्टेक्स एट्रिब्यूट के रूप में स्वीकार करता है और फ़ॉरवर्ड को फ्रैक्चर शैडर के लिए समन्वयित करता है। डिफ़ॉल्ट रूप से, यह भी गारंटी देगा कि टुकड़ा एक त्रिकोण में अपनी स्थिति के आधार पर ठीक से प्रक्षेपित समन्वय प्राप्त करेगा:

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoordIn;

out vec2 texCoordOut;

void main()
{
    gl_Position = vec4(position, 1.0f);
    texCoordOut = texCoordIn;
}

टुकड़ा shader तब texCoord आउटपुट चर को इनपुट चर के रूप में स्वीकार करता है। फिर आप एक uniform sampler2D घोषित करके टुकड़े टुकड़े करने के लिए एक बनावट जोड़ सकते हैं। बनावट के एक टुकड़े का नमूना लेने के लिए हम एक अंतर्निहित फ़ंक्शन texture उपयोग texture जिसमें दो पैरामीटर हैं। पहली बनावट है जिसे हम नमूना बनाना चाहते हैं और दूसरा इस बनावट का समन्वय है:

in vec2 texCoordOut;

out vec4 color;

uniform sampler2D image;

void main()
{
    color = texture(image, texCoordOut);
}

ध्यान दें कि image यहाँ प्रत्यक्ष बनावट आईडी नहीं है। यह बनावट इकाई की आईडी है जिसे नमूना लिया जाएगा। बदले में, बनावट सीधे कार्यक्रमों के लिए बाध्य नहीं हैं; वे बनावट इकाइयों के लिए बाध्य हैं। यह पहली बार बनावट इकाई को glActiveTexture साथ सक्रिय करके प्राप्त किया गया है, और फिर glBindTexture को कॉल glBindTexture से इस विशेष बनावट इकाई पर असर पड़ेगा। हालाँकि, चूंकि डिफॉल्ट टेक्सचर यूनिट टेक्सचर यूनिट 0 , इसलिए एक कॉल का उपयोग करके एक टेक्सचर का उपयोग करने वाले प्रोग्राम को सरल बनाया जा सकता है।



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