2011-08-25 10 views
20

मुझे शून्य के साथ एक ओपनजीएल 2 डी बनावट शुरू करने की आवश्यकता है।शून्य से बनावट को कुशलतापूर्वक कैसे प्रारंभ करें?

क्यों? मैं ओपनसीएल के साथ इस बनावट को प्रस्तुत करता हूं। मोटे तौर पर, प्रतिपादन चरण हैं:

  1. RGBA बनावट बनाएँ, शून्य से प्रारंभ
  2. OpenCL (इसलिए यह पारदर्शी काला पिक्सल शामिल हैं): पिक्सल जहां कुछ वस्तुओं दिखाई दे रहे हैं और उन्हें इस बनावट को लिखने की गणना रंग
  3. ओपनजीएल: पारदर्शी पिक्सेल में पर्यावरण मैपिंग जोड़ें और अंतिम छवि

इसलिए मुझे किसी वास्तविक बनावट डेटा को glTexImage2d पर पास करने की आवश्यकता नहीं है। लेकिन कल्पना के अनुसार, जब मैं डेटा = NULL पास करता हूं, बनावट स्मृति आवंटित की जाती है लेकिन प्रारंभ नहीं होती है।

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

संपादित करें: मैं वास्तव में केवल अल्फा घटक (आरजीबी को ओवरडिन प्राप्त कर दूंगा) में प्रवेश करना चाहता हूं, लेकिन मुझे संदेह है कि इससे स्थिति आसान हो जाएगी।

उत्तर

32

ऐसा करने के कई तरीके हैं:

1:

std::vector<GLubyte> emptyData(width * height * 4, 0); 
glBindTexture(GL_TEXTURE_2D, texture); 
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, &emptyData[0]); 

अधिकतम क्षमता के लिए, आप के बीच जब आप इस फोन और कुछ समय छोड़ देना चाहिए: एक बनावट की चौड़ाई और ऊंचाई को देखते हुए जब ओपनसीएल अपना काम शुरू करता है।

2: इसे एफबीओ से संलग्न करें और glClearBuffer का उपयोग करें।

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); 
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0); //Only need to do this once. 
glDrawBuffer(GL_COLOR_ATTACHMENT0); //Only need to do this once. 
GLuint clearColor[4] = {0, 0, 0, 0}; 
glClearBufferuiv(GL_COLOR, 0, clearColor); 

ऐसा लगता है कि यह तेज होना चाहिए, क्योंकि कोई CPU-GPU DMA चालू नहीं है। लेकिन एफबीओ के बाध्यकारी और बाध्यकारी अक्षमता पेश कर सकते हैं। फिर फिर, यह नहीं हो सकता है। यह सुनिश्चित करने के लिए प्रोफाइल करें।

ध्यान दें कि यह केवल छवि प्रारूपों के लिए काम करता है जिसे लक्ष्य प्रस्तुत करने के रूप में उपयोग किया जा सकता है। तो संपीड़ित बनावट नहीं।

3: पर्याप्त ड्राइवरों को देखते हुए, आप नए ARB_clear_texture एक्सटेंशन का उपयोग कर सकते हैं:

glClearTexImage(texture, 0, GL_BGRA, GL_UNSIGNED_BYTE, &clearColor); 

ध्यान दें कि छवि प्रारूप जिसका डेटा standard pixel transfers द्वारा प्रदान की जा सकती है, के लिए यह केवल काम करता है। तो संपीड़ित प्रारूप नहीं।

+0

'glClearBuffer' के बारे में कभी नहीं सुना। क्या यह एक बहुत ही नए संस्करण से है? क्या इसका 'ग्लक्लेयर' पर कोई लाभ है (या बाद वाला भी बहिष्कृत है)? –

+1

@ क्रिस्टियन: क्लियरबफर का मुख्य लाभ यह है कि आप विशिष्ट बफर साफ़ कर सकते हैं। यदि आपके पास फ्रेमबफर में एकाधिक बफर हैं, तो एकाधिक लक्ष्य प्रदान करते हैं, तो आप अलग-अलग रंगों को अलग-अलग साफ़ करना चाह सकते हैं। या कुछ बिल्कुल स्पष्ट नहीं है। आप 'glcllear' के साथ ऐसा नहीं कर सकते; यह सभी बफर को एक ही स्पष्ट रंग में साफ़ करता है। 'glClear' को बहिष्कृत नहीं किया गया है, और' glClearBuffer' जीएल 3.0 से आता है (इसके लिए कोई विस्तार नहीं है)। –

+1

ध्यान दें कि GlClearTexImage केवल तभी काम करता है जब बनावट भंडारण पहले आवंटित किया गया हो, या तो glTexImage * या glTexStorage * पर कॉल का उपयोग कर। बस glbindTexture का उपयोग कर बनावट बनाना पर्याप्त नहीं है। लेकिन यह निश्चित रूप से glTexSubImage2D पर भी लागू होता है। – rdb

1

शायद आप बनावट को पहले पास के लिए प्रतिपादन लक्ष्य के रूप में सेट कर सकते हैं और एक काला आदिम आकर्षित कर सकते हैं। यह तेजी से हो सकता है क्योंकि राम और ग्राफिक कार्ड के बीच कोई मेमोरी ट्रांसफर्ट नहीं है।

+0

अच्छा बिंदु। लेकिन क्या मैं इस दृष्टिकोण के साथ अल्फा = 0 सेट करने का प्रबंधन कर सकता हूं? मैं वास्तव में केवल अल्फा में प्रवेश करना चाहता हूं, मैं आरजीबी घटकों से परेशान नहीं हूं। – jirkamat

+3

glClearColor और glClear का उपयोग करना बेहतर हो सकता है। GlClearColor अल्फा स्वीकार करता है। – neodelphi

5

बस एक सिर ऊपर: नया GL_ARB_clear_texture (4.4 में कोर) एक्सटेंशन विशेष रूप से इस समस्या को संबोधित करता है।

+0

यह सच है, लेकिन चेतावनी का एक शब्द: आप निश्चित रूप से इसे प्रोफाइल करना चाहते हैं। मेरे सिस्टम पर, ग्लक्लेयरटेक्चर एक फ्रेमबफर और ग्लक्लेयर/ग्लक्लेयर बफर का उपयोग करने से बहुत धीमी है। – Jagoly

+0

@Jagoly क्या आपने GPU टाइमर क्वेरी का उपयोग करके ठीक से प्रोफ़ाइल बनाई है? – Ancurio

+0

नहीं, बस फ्रैमटाइम का उपयोग कर। यह थोड़ा धीमा नहीं है, यद्यपि; स्पष्टता (दो कॉल, आरजीबी 8 + 24 बिट गहराई) स्पष्ट से तीन गुना अधिक समय ले लिया। मेरे पास पहले से ही फ्रेमबफर स्थापित है। अंतर केवल गहराई के लिए भी बड़ा था (5x)। – Jagoly

0
  1. glTexSubImage पूरी छवि से भर जाता है:

    GLfloat* pData = new GLfloat[1024*768*4]; 
    memset(pData, 0x00, 1024*768*4*sizeof(GLfloat)); 
    glBindTexture(GL_TEXTURE_2D, m_ImageTex); 
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1024, 768, GL_RGBA, GL_FLOAT, pData); 
    glBindTexture(GL_TEXTURE_2D, 0); 
    delete pData; 
    
  2. उपयोग पिक्सेल बफर GPU से डेटा कॉपी करने के लिए, इस विधि तेजी से और बेहतर

    मैं है। init पीबीओ

    glGenBuffers(1, &m_PixelBuffer); 
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_PixelBuffer); 
    glBufferData(GL_PIXEL_UNPACK_BUFFER, SCREEN_WIDTH*SCREEN_HEIGHT*4*sizeof(GLfloat), NULL, GL_STATIC_DRAW); 
    GLfloat* pData = nullptr; 
    pData = (GLfloat*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); 
    memset(pData, 0x00, 1024*768*4*sizeof(GLfloat)); 
    glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); 
    

    ii।

    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_PixelBuffer); 
    glBindTexture(GL_TEXTURE_2D, m_ImageTex); 
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_RGBA, GL_FLOAT, NULL); 
    glBindTexture(GL_TEXTURE_2D, 0); 
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); 
    
संबंधित मुद्दे