मैंने प्रोग्रामिंग पहलू के बारे में थोड़ा लिखने का फैसला किया और कैसे घटक एक दूसरे से बात करते हैं। शायद यह कुछ क्षेत्रों पर कुछ प्रकाश डाला जाएगा।
प्रदर्शन
स्क्रीन पर खींची गई उस एकल छवि में भी क्या होता है, जिसे आपने अपने प्रश्न में पोस्ट किया है?
स्क्रीन पर एक त्रिकोण खींचने के कई तरीके हैं। सरलता के लिए, मान लें कि कोई शीर्ष बफ़र उपयोग नहीं किया गया था। (एक शीर्ष बफ़र मेमोरी का एक क्षेत्र है जहां आप निर्देशांक संग्रहीत करते हैं।) मान लें कि प्रोग्राम ने ग्राफिक्स प्रोसेसिंग पाइपलाइन को हर एक शीर्ष के बारे में बताया (एक शीर्ष केवल एक अंतरिक्ष में एक समन्वय है)।
लेकिन , इससे पहले कि हम कुछ भी आकर्षित कर सकें, हमें पहले कुछ मचान चलाना होगा। हम देखेंगे क्यों बाद में:
// Clear The Screen And The Depth Buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Reset The Current Modelview Matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Drawing Using Triangles
glBegin(GL_TRIANGLES);
// Red
glColor3f(1.0f,0.0f,0.0f);
// Top Of Triangle (Front)
glVertex3f( 0.0f, 1.0f, 0.0f);
// Green
glColor3f(0.0f,1.0f,0.0f);
// Left Of Triangle (Front)
glVertex3f(-1.0f,-1.0f, 1.0f);
// Blue
glColor3f(0.0f,0.0f,1.0f);
// Right Of Triangle (Front)
glVertex3f( 1.0f,-1.0f, 1.0f);
// Done Drawing
glEnd();
तो उसने क्या किया?
जब आप एक प्रोग्राम लिखते हैं जो ग्राफिक्स कार्ड का उपयोग करना चाहते हैं, तो आप आमतौर पर ड्राइवर को किसी प्रकार का इंटरफ़ेस चुनेंगे। ड्राइवर के लिए कुछ प्रसिद्ध इंटरफेस हैं:
इस उदाहरण के लिए हम OpenGL से चिपके रहेंगे। अब, अपने ड्राइवर के लिए इंटरफ़ेस क्या आप सभी उपकरण आप अपने कार्यक्रम बनाने की जरूरत है देता है बात ग्राफिक्स कार्ड के लिए (या ड्राइवर है, जो तब वार्ता कार्ड के लिए)।
यह इंटरफ़ेस आपको कुछ उपकरण देने के लिए बाध्य है । ये उपकरण एक एपीआई का आकार लेते हैं जिसे आप अपने प्रोग्राम से कॉल कर सकते हैं।
वह एपीआई जो हम ऊपर उदाहरण में उपयोग किया जा रहा है देखते हैं। आओ हम इसे नज़दीक से देखें।
मचान
इससे पहले कि आप वास्तव में कोई वास्तविक ड्राइंग कर सकें, आपको एक सेटअप करना होगा । आपको अपना व्यूपोर्ट (वह क्षेत्र जो वास्तव में प्रदान किया जाएगा), आपके दृष्टिकोण ( आपकी दुनिया में कैमरा ) को परिभाषित करना होगा , आप किस विरोधी-विचलन का उपयोग कर रहे हैं (अपने त्रिकोण के किनारे को सुचारू करने के लिए) ...
लेकिन हम उसमें से किसी पर भी गौर नहीं करेंगे। हम आपके द्वारा हर फ्रेम में किए गए सामान पर एक नज़र डालेंगे । पसंद:
स्क्रीन को साफ करना
ग्राफिक्स पाइपलाइन आपके लिए हर फ्रेम में स्क्रीन को साफ करने वाला नहीं है। आपको बताना पड़ेगा। क्यों? इसलिए:
यदि आप स्क्रीन को साफ नहीं करते हैं, तो आप बस इसे हर फ्रेम पर खींच लेंगे । यही कारण है कि हम फोन है glClear
के साथ GL_COLOR_BUFFER_BIT
सेट। अन्य बिट ( GL_DEPTH_BUFFER_BIT
) ओपन बफर को गहराई बफर को साफ करने के लिए कहता है । इस बफ़र का उपयोग यह निर्धारित करने के लिए किया जाता है कि कौन से पिक्सेल अन्य पिक्सेल के सामने (या पीछे) हैं।
परिवर्तन
छवि स्रोत
परिवर्तन वह हिस्सा है जहां हम सभी इनपुट निर्देशांक (हमारे त्रिकोण के कोने) लेते हैं और हमारे मॉडल व्यू मैट्रिक्स को लागू करते हैं। यह वह मैट्रिक्स है जो बताता है कि हमारे मॉडल (कोने) को कैसे घुमाया, बढ़ाया और अनुवादित किया गया (स्थानांतरित)।
अगला, हम अपने प्रोजेक्शन मैट्रिक्स को लागू करते हैं। यह सभी निर्देशांक को स्थानांतरित करता है ताकि वे हमारे कैमरे का सही ढंग से सामना करें।
अब हम अपने व्यूपोर्ट मैट्रिक्स के साथ एक बार फिर रूपांतरण करते हैं। हम अपने मॉडल को अपने मॉनिटर के आकार के पैमाने पर करने के लिए ऐसा करते हैं । अब हमारे पास वर्टिकल का एक सेट है जो रेंडर करने के लिए तैयार है!
हम थोड़ी देर बाद परिवर्तन पर लौट आएंगे।
चित्रकारी
एक त्रिकोण आकर्षित करने के लिए, हम बस एक नया शुरू करने के लिए ओपन बता सकते हैं त्रिकोण की सूची को फोन करके glBegin
साथ GL_TRIANGLES
निरंतर।
ऐसे अन्य रूप भी हैं जिन्हें आप आकर्षित कर सकते हैं। एक त्रिकोण पट्टी या एक त्रिकोण प्रशंसक की तरह । ये मुख्य रूप से अनुकूलन हैं, क्योंकि उन्हें एक ही राशि के त्रिभुजों को खींचने के लिए सीपीयू और जीपीयू के बीच कम संचार की आवश्यकता होती है।
उसके बाद, हम 3 कोने के सेट की एक सूची प्रदान कर सकते हैं जो प्रत्येक त्रिकोण को बनाना चाहिए। प्रत्येक त्रिभुज 3 निर्देशांक का उपयोग करता है (जैसा कि हम 3 डी-स्पेस में हैं)। इसके अतिरिक्त, मैं कॉल करने से पहले कॉल करके प्रत्येक शीर्ष के लिए एक रंग भी प्रदान करता हूं ।glColor3f
glVertex3f
3 कोने (त्रिकोण के 3 कोनों) के बीच की छाया की गणना ओपनजीएल द्वारा स्वचालित रूप से की जाती है । यह बहुभुज के पूरे चेहरे पर रंग को प्रक्षेपित करेगा।
इंटरेक्शन
अब, जब आप विंडो पर क्लिक करते हैं। एप्लिकेशन को केवल उस विंडो संदेश को कैप्चर करना होगा जो क्लिक को इंगित करता है। तब आप अपने कार्यक्रम में कोई भी कार्रवाई कर सकते हैं जिसे आप चाहते हैं।
यह एक बहुत अधिक कठिन हो जाता है एक बार जब आप अपने 3 डी दृश्य के साथ बातचीत शुरू करना चाहते हैं।
आपको पहले यह स्पष्ट रूप से जानना होगा कि उपयोगकर्ता ने किस पिक्सेल पर विंडो क्लिक की है। फिर, अपने दृष्टिकोण को ध्यान में रखते हुए, आप किरण की दिशा की गणना कर सकते हैं, माउस के बिंदु से अपने दृश्य में क्लिक करें। फिर आप गणना कर सकते हैं यदि आपके दृश्य में किसी भी वस्तु काटती है कि किरण के साथ । अब आप जानते हैं कि क्या उपयोगकर्ता ने किसी ऑब्जेक्ट पर क्लिक किया है।
तो, आप इसे कैसे घुमाते हैं?
परिवर्तन
मुझे दो प्रकार के परिवर्तनों के बारे में पता है जो आमतौर पर लागू होते हैं:
- मैट्रिक्स-आधारित परिवर्तन
- अस्थि-आधारित परिवर्तन
अंतर यह है कि हड्डियां एकल कोने को प्रभावित करती हैं । मैट्रिसेस हमेशा एक ही तरह से सभी खींचे गए को प्रभावित करते हैं। आइए एक उदाहरण देखें।
उदाहरण
इससे पहले, हमने अपने त्रिकोण को खींचने से पहले अपनी पहचान मैट्रिक्स को लोड किया था । पहचान मैट्रिक्स वह है जो बस कोई परिवर्तन नहीं प्रदान करता है । इसलिए, जो भी मैं आकर्षित करता हूं, वह केवल मेरे दृष्टिकोण से प्रभावित होता है। तो, त्रिकोण को बिल्कुल भी घुमाया नहीं जाएगा।
अगर मैं इसे अब घुमाना चाहता हूं, तो मैं या तो स्वयं गणित (सीपीयू पर) कर सकता हूं और बस अन्य निर्देशांक (जो सड़ रहे हैं) के glVertex3f
साथ कॉल कर सकते हैं। या मैं glRotatef
ड्राइंग से पहले कॉल करके GPU को सभी काम करने दे सकता हूं :
// Rotate The Triangle On The Y axis
glRotatef(amount,0.0f,1.0f,0.0f);
amount
बेशक, सिर्फ एक निश्चित मूल्य है। यदि आप चेतन करना चाहते हैं , तो आपको amount
हर फ्रेम पर नज़र रखनी होगी और उसे बढ़ाना होगा।
तो, रुकिए, पहले हुई सभी मैट्रिक्स की बातों का क्या हुआ?
इस सरल उदाहरण में, हमें मैट्रीस की परवाह नहीं करनी है। हम बस फोन करते हैं glRotatef
और यह हमारे लिए सभी का ख्याल रखता है।
glRotate
angle
वेक्टर xyz के आसपास डिग्री का एक रोटेशन पैदा करता है । वर्तमान मैट्रिक्स ( glMatrixMode देखें ) को वर्तमान मैट्रिक्स की जगह उत्पाद के साथ एक रोटेशन मैट्रिक्स द्वारा गुणा किया जाता है, जैसे कि glMultMatrix को निम्न मैट्रिक्स के साथ इसके तर्क के रूप में कहा जाता है:
x 2 1 - c + cx y c 1 - c - z sx z y 1 - c + y 0 s 0 y x - 1 - c + z 2 sy 2 - 1 - c + cy z - 1 - c - x 0 s 0 x z c 1 - c - y - sy z x 1 - c + x z sz 2 - 1 - c + c 0 0 0 0 0 1
खैर, इसके लिए धन्यवाद!
निष्कर्ष
क्या स्पष्ट हो जाता है, ओपेनग्ल के लिए बहुत सारी बात है । लेकिन यह हमें कुछ नहीं बता रहा है । संचार कहाँ है?
केवल एक चीज जो ओपनजीएल हमें इस उदाहरण में बता रही है वह है जब यह किया जाता है । हर ऑपरेशन में एक निश्चित समय लगेगा। कुछ ऑपरेशन अविश्वसनीय रूप से लंबे होते हैं, अन्य अविश्वसनीय रूप से जल्दी होते हैं।
GPU के लिए एक शीर्ष भेजना इतना तेज़ होगा, मुझे यह भी नहीं पता होगा कि इसे कैसे व्यक्त किया जाए। सीपीयू से GPU तक हर एक फ्रेम में हजारों वर्टिकल भेजना, सबसे अधिक संभावना है, कोई समस्या नहीं है।
स्क्रीन साफ़ करना एक मिलीसेकंड या इससे भी बदतर हो सकता है (ध्यान रखें, आपके पास आमतौर पर प्रत्येक फ्रेम को खींचने के लिए लगभग 16 मिलीसेकंड का समय होता है), यह इस बात पर निर्भर करता है कि आपका व्यूपोर्ट कितना बड़ा है। इसे साफ़ करने के लिए, OpenGL को हर एक पिक्सेल को उस रंग में खींचना होगा जिसे आप साफ़ करना चाहते हैं, जो लाखों पिक्सेल हो सकते हैं।
इसके अलावा, हम अपने ग्राफिक्स एडॉप्टर की क्षमताओं (अधिकतम रिज़ॉल्यूशन, अधिकतम एंटी-अलियासिंग, अधिकतम रंग गहराई, ...) के बारे में बहुत कुछ ओपनग्लाल से पूछ सकते हैं।
लेकिन हम पिक्सेल के साथ एक बनावट भी भर सकते हैं जिसमें प्रत्येक का एक विशिष्ट रंग होता है। प्रत्येक पिक्सेल इस प्रकार एक मान रखता है और बनावट डेटा से भरी एक विशाल "फ़ाइल" है। हम उस ग्राफिक्स कार्ड में लोड कर सकते हैं (एक बनावट बफर बनाकर), फिर एक shader लोड करें , उस shader को हमारी बनावट को इनपुट के रूप में उपयोग करने के लिए और हमारी "फाइल" पर कुछ बेहद भारी गणनाओं को चलाने के लिए कहें।
फिर हम अपनी गणना (नए रंगों के रूप में) को एक नई बनावट में "प्रस्तुत" कर सकते हैं।
इसी तरह आप दूसरे तरीकों से अपने लिए जीपीयू काम कर सकते हैं। मुझे लगता है कि CUDA उस पहलू के समान प्रदर्शन करता है, लेकिन मुझे इसके साथ काम करने का अवसर कभी नहीं मिला।
हमने वास्तव में केवल पूरे विषय को थोड़ा छुआ था। 3 डी ग्राफिक्स प्रोग्रामिंग एक जानवर का एक नरक है।
छवि स्रोत