2012-05-11 18 views
5

के माध्यम से संपूर्ण वीडियो मेमोरी एक्सेस करें ओपनजीएल प्रोग्रामिंग के माध्यम से विशेष रूप से, वीडियो मेमोरी की सभी सामग्री प्राप्त करने के लिए, ग्राफिक्स कार्ड की वीडियो मेमोरी तक कैसे पहुंचे?ओपनजीएल प्रोग्रामिंग

मैंने निम्नलिखित दो विधियों का प्रयास किया है, लेकिन असफल रहा है। उन्हें नीचे जोड़ने के साथ, मुझे उम्मीद है कि आप मेरे कार्यक्रम में या वीडियो मेमोरी की संरचना की मेरी समझ में त्रुटि को इंगित कर सकते हैं। अग्रिम में धन्यवाद!

मेरा मूल विचार वीडियो मेमोरी की सभी सामग्री की खोज तक वीडियो स्मृति में एक अनियमित क्षेत्र आवंटित करना जारी रखना है।

(1) मुख्य समारोह में, मैं डबल बफर वाले एक विंडो बनाता हूं (निम्नलिखित कोड देखें)।

int main(int argc,char ** argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); // double buffers 
    glutInitWindowPosition(0,0); 
    glutInitWindowSize(windowWidth, windowHeight); 
    glutCreateWindow("Hope to be successful!"); 
    glutDisplayFunc(myDisplay); // call back function "myDisplay" 
    glutKeyboardFunc(keyboard); 
    glutMainLoop(); 

    free(PixelData); 
    return 0; 
} 

फिर, "myDisplay" समारोह में सबसे पहले मैं glReadPixels() फ़ंक्शन को कॉल करें, वापस फ्रेमबफर से बाहर पिक्सल के एक दिया आकार आयत को पढ़ने के लिए एक सरणी "PixelData" में इन पिक्सल जानकारी बचाने के लिए, और अंत में gldrawPixels() फ़ंक्शन को कॉल करके स्क्रीन पर उन पिक्सेल जानकारी को प्रदर्शित करें। इस कार्यक्रम को निष्पादित करने के बाद, केवल एक काला खिड़की दिखाई देती है। काला डिफ़ॉल्ट रंग है। तो इसका मतलब है कि खिड़की में कुछ भी नहीं है। फिर मैंने बैक फ्रेमबफर के बाहर अन्य क्षेत्रों को पढ़ने की कोशिश की है, और उनमें से सभी में कुछ भी नहीं है।

उपर्युक्त से निष्कर्ष यह है कि बैक फ्रेमबफर में कुछ भी शामिल नहीं है। हालांकि, यह अनुचित है क्योंकि फ्रंट बफर में केवल वर्तमान स्क्रीन सामग्री/खिड़की होनी चाहिए, और इस प्रकार स्क्रीन के निचले हिस्से में खोले गए और कम से कम अन्य खिड़कियां बैक फ्रेमबफर में अपनी सामग्री होनी चाहिए, लेकिन बैक फ्रेमबफर खाली है। तो उन खिड़कियां कहाँ हैं (नीचे से मेरे द्वारा खोला और छोटा) संग्रहित?

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

कुछ समय बाद, मैंने ओपनजीएल फ्रेमबफर ऑब्जेक्ट (एफबीओ) के लिए एक परिचय पढ़ा, और एक वाक्य है: डिफ़ॉल्ट रूप से, ओपनजीएल फ्रेमबफर को एक प्रतिपादन गंतव्य के रूप में उपयोग करता है जो पूरी तरह से विंडो सिस्टम द्वारा बनाया और प्रबंधित किया जाता है। इस डिफ़ॉल्ट फ्रेमबफर को विंडो-सिस्टम-प्रदत्त फ्रेमबफर कहा जाता है। यह प्रतीत होता है कि मेरे उपरोक्त अनुमान को सत्यापित करता है।

(2) फिर मैं उम्मीद के साथ एफबीओ पर काम करना शुरू कर देता हूं कि एफबीओ मुझे पूरी वीडियो मेमोरी सामग्री का पता लगाने में मदद कर सकता है।

नीचे दिए गए मुख्य समारोह में, मैं एक एफबीओ और 7 रेंडरबफर ऑब्जेक्ट्स (आरबीओ) बनाता हूं, और फिर इन 7 आरबीओ को इस संलग्नक बिंदुओं के माध्यम से इस एफबीओ में संलग्न करता हूं।

const int RBO_COUNT = 7; //how many renderBuffer objects are created to attach to the frameBuffer object 

int main(int argc, char **argv) 
{ 
    .... 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_ALPHA); // display mode 
    ... 

    // create a framebuffer object 
    glGenFramebuffers(1, &fboId); 
    glBindFramebuffer(GL_FRAMEBUFFER, fboId); 

    //Create several 7 render buffer objects and attach all of them to the FBO. 
    glGenRenderbuffers(RBO_COUNT, rbo); 
    for (int i = 0; i < RBO_COUNT; i++) 
    { 
     glBindRenderbuffer(GL_RENDERBUFFER, rbo[i]); 
     glRenderbufferStorage(GL_RENDERBUFFER, PIXEL_FORMAT, SCREEN_WIDTH, SCREEN_HEIGHT); 
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, colorAttach[i], GL_RENDERBUFFER, rbo[i]); 
    } 

    // check FBO status 
    bool status = checkFramebufferStatus(); 
    if(!status) fboUsed = false; 

    glBindFramebuffer(GL_FRAMEBUFFER, 0); 
    ... 

    glutMainLoop(); /* Start GLUT event-processing loop */ 
    return 0; 
} 

नीचे मेरे प्रदर्शन कॉलबैक फ़ंक्शन का मुख्य हिस्सा है। इसका फ़ंक्शन स्पेस कुंजी का उपयोग करने के लिए है जो कि रेंडरबफर ऑब्जेक्ट को पढ़ने के लिए नियंत्रित करता है, और उसके बाद स्क्रीन पर अपनी सामग्री प्रदर्शित करता है।

void displayCB() 
{ 
glBindFramebuffer(GL_FRAMEBUFFER, fboId); 

//read this FBO attached RBO, save its content to fboContent 
//"count" is a global variable, and is incremented by 1 (mod)every time pressing the space key of the keyboard. 
glReadBuffer(colorAttach[count]); 
glReadPixels(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, PIXEL_FORMAT, GL_UNSIGNED_BYTE, fboContent); 

// back to normal window-system-provided framebuffer 
glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind 

// render to the default framebuffer ////////////////////////// 
glClear(GL_COLOR_BUFFER_BIT); // clear buffer 
glClearColor(1, 0, 0, 1); 
glDrawBuffer(GL_BACK); 
glRasterPos2i(-1, -1); 
glDrawPixels(SCREEN_WIDTH, SCREEN_HEIGHT, PIXEL_FORMAT, GL_UNSIGNED_BYTE, fboContent); 
glutSwapBuffers(); 
} 

अंतिम परिणाम निराशाजनक है। सभी रेंडरबफर ऑब्जेक्ट्स की सामग्री खाली है। मुझे इसका कारण पता नहीं है, क्योंकि मैंने सोचा था कि इन सभी आरबीओ को कभी शुरू नहीं किया गया था और इसमें कुछ शेष सामग्री होनी चाहिए।

+0

"मैंने सोचा था कि इन सभी आरबीओ को कभी शुरू नहीं किया गया था और इसमें कुछ शेष सामग्री होनी चाहिए।" फिर आपको कल्पना को फिर से पढ़ना चाहिए। यह कहता है कि उनकी सामग्री * अनिर्धारित * हैं। अपरिभाषित "शेष सामग्री" का मतलब हो सकता है। इसका मतलब "शून्य स्मृति" भी हो सकता है। इसका मतलब यह हो सकता है कि "स्मृति कुछ मनमानी रंगों को सेट करती है ताकि बग को पकड़ना आसान हो।" अपरिभाषित साधन * अपरिभाषित *। –

+0

spec (http://www.opengl.org/wiki/Renderbuffer_Object) कहता है कि "रेंडरबफर को अनियमित बनाया गया है।" मेरे विचार से आप सही है। चाहे अनियंत्रित आरबीओ खाली हों या कुछ शेष सामग्री को तब निर्धारित किया जाए जब उन आरबीओ बनाए जाते हैं। यदि सभी वीडियो मेमोरी का एक बार उपयोग किया गया है और उनमें से कुछ अब आवंटित नहीं हैं, तो नव निर्मित आरबीओ में शायद कुछ पिछली सामग्री होगी। – loong

+0

यह कल्पना नहीं है; वह एक विकी लेख है। यह नमूना [ओपनजीएल रजिस्ट्री] (http://www.opengl.org/registry/) पर पाया जाता है।लेकिन त्रुटि को इंगित करने के लिए धन्यवाद; मैं इसे ठीक कर दूंगा। –

उत्तर

1

ओपनजीएल प्रोग्रामिंग के माध्यम से विशेष रूप से, वीडियो मेमोरी की सभी सामग्री प्राप्त करने के लिए ग्राफिक्स कार्ड की वीडियो मेमोरी तक कैसे पहुंचे?

ओपनजीएल नहीं, ऑपरेटिंग सिस्टम से बात करें।

+0

क्या आपका मतलब है कि OpenGL ऐसा कार्य नहीं कर सकता है? असल में, मैंने इस समस्या पर लगभग दो महीने तक काम किया है। अगर ओपनजीएल नहीं कर सकता है, तो मुझे अपना काम फिर से शुरू करना होगा। इसके अलावा, क्या आप "ओएस से बात करने" के बारे में और अधिक कह सकते हैं? – loong

-1

यह स्पष्ट नहीं है क्यों आप ऐसा करना चाहते हैं, और अपने अंत खेल क्या है, लेकिन यह है कि आप ग्राफिक जानकारी है कि 3 पार्टी अनुप्रयोगों द्वारा निर्मित है का उपयोग करने की कोशिश कर रहे हैं मुझे लगता है।

यदि आप what FRAPS does को पूरा करने की कोशिश कर रहे हैं, तो ध्यान रखें कि यह एक तकनीक का उपयोग करता है जो आप करने की कोशिश कर रहे हैं (एक बहुत ही सरल): यह ओपनजीएल और डायरेक्टएक्स जैसे ग्राफिक पुस्तकालयों को कॉल को अवरुद्ध करता है।

+0

मैं यह सत्यापित करने की कोशिश कर रहा हूं कि एक प्रकार का संभावित हमला वास्तव में व्यवहार्य है या नहीं। और पूरी वीडियो मेमोरी एक्सेस करना सत्यापन प्रक्रिया का हिस्सा है। उत्तर के लिए धन्यवाद। – loong

+0

आपका लिंक टूटा हुआ है। क्या आप इसे ठीक करने का प्रयास कर सकते हैं (मेरा मतलब है, क्या आप एक अद्यतन यूआरएल पा सकते हैं?) क्योंकि मैं वर्तमान में कुछ ऐसा लागू करने के लिए "कैसे FRAPS काम करता है" में रूचि रखता हूं (http://stackoverflow.com/q/13781777/592323) ... – leemes

+0

इंटरनेट खोज के 2 मिनट। :(यह तय है। – karlphillip

6

ओपनजीएल प्रोग्रामिंग के माध्यम से विशेष रूप से, वीडियो मेमोरी की सभी सामग्री प्राप्त करने के लिए ग्राफिक्स कार्ड की वीडियो मेमोरी तक कैसे पहुंचे?

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

आपको वीडीएए का समर्थन करने वाले कार्ड पर ओएलडी हार्डवेयर - चीज ईजीए/सीजीए/वीजीए पर सीधे वीडियो मेमोरी तक पहुंचने में सक्षम होना चाहिए, हालांकि आपके पास कोई हार्डवेयर त्वरण नहीं होगा, और आपको कुछ इसी तरह चलाने की आवश्यकता होगी एमएस-डॉस या कर्नेल/ड्राइवर एक्सेस विशेषाधिकार हैं। आप लिनक्स पर मेमोरी सामग्री तक पहुंचने में सक्षम हो सकते हैं, लेकिन मुझे लगता है कि यह सहायक नहीं होगा।

मैं इस विचार को भूलना चाहता हूं।

क्या आपका मतलब है कि OpenGL ऐसा कार्य नहीं कर सकता है? असल में, मैंने इस समस्या पर लगभग दो महीने तक काम किया है।

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

वर्तमान में वीडियो मेमोरी में संग्रहीत वस्तुओं का प्रबंधन ड्राइवर का काम है।

यदि आप अन्य अनुप्रयोगों द्वारा बनाई गई वस्तुओं को देखना चाहते हैं, तो प्रॉक्सी डीएलएस, डीएल-इंजेक्शन या इसी तरह की तकनीकों का उपयोग करके ओपनजीएल एपीआई को हाइजैक करना संभव होगा और प्रासंगिक कॉल को रोक देगा।

+0

आपके विस्तृत स्पष्टीकरण के लिए धन्यवाद! बहुत उपयोगी! अगर आप सभी ने कहा कि यह सच साबित हो जाता है तो यह मेरे लिए एक भयानक बात होगी। – loong

+0

पुराने हार्डवेयर होने की ज़रूरत नहीं है; बस एक बायोस एप्लीकेशन डाल सकते हैं एक सीडी/फ्लॉपी। सभी पीसी इसका समर्थन करते हैं। – Dmitry