एसडीएल 2.0 पाठ 2: पाठ 2


अनुवादक से: ट्विंकलबियर ट्यूटोरियल की एक श्रृंखला का सिलसिला, यहां मूल में उपलब्ध है पिछला पाठ यहां पाया जा सकता है

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

हमेशा की तरह, हम एसडीएल को सक्षम करके कार्यक्रम शुरू करेंगे। इस ट्यूटोरियल में हम स्ट्रिंग क्लास का उपयोग करेंगे, इसलिए हम इसे शामिल करेंगे।

#include "SDL.h" #include <string> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *window = nullptr; SDL_Renderer *renderer = nullptr; 

हम वैश्विक विंडो और रेंडरर घोषणाओं के साथ स्क्रीन की चौड़ाई और ऊंचाई के लिए निरंतर मूल्यों की एक जोड़ी की भी घोषणा करेंगे ताकि वे हमारे कार्यों से सुलभ हों। फिर हम सुरक्षा के लिए नल्टर के रूप में पॉइंटर्स को इनिशियलाइज़ करते हैं। यदि आप C ++ 11 का उपयोग नहीं कर रहे हैं, तो उन्हें NULL के रूप में प्रारंभ करें।

नोट: आपको गैर-निरंतर वैश्विक मूल्यों या सामान्य रूप से वैश्विक मूल्यों का उपयोग करने से बचने की कोशिश करनी चाहिए, अर्थात आपको कभी भी वैश्विक SDL_Window या SDL_Renderer घोषित नहीं करना चाहिए। हालाँकि, इस सरल पाठ के लिए हम अभी भी उनका उपयोग करेंगे। हम कुछ पाठों में वैश्विक वस्तुओं का उपयोग करने पर ध्यान देंगे।

याद रखें कि हमने पहले पाठ में बनावट कैसे भरी थी? यह मुख्य रूप से एक बनावट को लोड करने के लिए इतना बुरा नहीं है, लेकिन कल्पना करें कि क्या उनमें से सौ जोड़े थे? हमें हर बार एक ही कोड को प्रिंट करना होगा! फ़ाइल नाम से बनावट लोड करने के लिए एक फ़ंक्शन घोषित करना बेहतर है:

 SDL_Texture* LoadImage(std::string file){ SDL_Surface *loadedImage = nullptr; SDL_Texture *texture = nullptr; loadedImage = SDL_LoadBMP(file.c_str()); if (loadedImage != nullptr){ texture = SDL_CreateTextureFromSurface(renderer, loadedImage); SDL_FreeSurface(loadedImage); } else std::cout << SDL_GetError() << std::endl; return texture; } 

यह फ़ंक्शन बहुत परिचित दिखना चाहिए, क्योंकि यह वही कोड है जो हमने पहले पाठ में लिखा था, लेकिन अब इसे एक अच्छे फ़ंक्शन में जोड़ा गया है। इसके साथ, हम फ़ाइल नाम को एक पंक्ति के रूप में पास कर सकते हैं और लोड की गई बनावट के लिए एक संकेतक प्राप्त कर सकते हैं। ध्यान दें कि यदि लोडिंग विफल हो जाता है तो पॉइंटर nullptr होगा।

अगला, हम ड्राइंग को आसान बनाने के लिए एक फ़ंक्शन लिखना चाहते हैं। यह फ़ंक्शन आपको स्क्रीन पर छवि की स्थिति निर्दिष्ट करने की भी अनुमति देता है। यह x और y निर्देशांक, बनावट और रेंडर को इंगित करेगा, और निर्दिष्ट बिंदु पर बनावट आकर्षित करेगा।

 void ApplySurface(int x, int y, SDL_Texture *tex, SDL_Renderer *rend){ SDL_Rect pos; pos.x = x; pos.y = y; SDL_QueryTexture(tex, NULL, NULL, &pos.w, &pos.h); SDL_RenderCopy(rend, tex, NULL, &pos); } 

यह इंगित करने के लिए कि बनावट कहाँ खींची जाएगी, हमें SDL_Rect बनाने की आवश्यकता है, जिसके पते को हम लक्ष्य आयत के पैरामीटर के रूप में SDL_RenderCopy को पास करेंगे।

अपनी आयत बनाने के लिए, हम उस x और y को लेते हैं जो स्थानांतरित किए गए थे और आयत के संबंधित मानों को उनके मानों में निर्दिष्ट करते हैं। हालांकि, हमें चौड़ाई और ऊंचाई भी निर्दिष्ट करने की आवश्यकता है, क्योंकि एसडीएल 2.0 हमें बनावट को स्केल करने की अनुमति देता है। चौड़ाई और ऊंचाई मानों के साथ खेलने की कोशिश करें और देखें कि क्या होता है!

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

अब जब हमारे पास SDL_Rect इनिशियलाइज़ हो गया है, तो हम इसे SDL_RenderCopy को पास कर सकते हैं, ताकि मूल ऊंचाई और चौड़ाई के साथ हमें उस बिंदु पर बनावट आ जाए। इस फ़ंक्शन को दिया गया शेष NULL पैरामीटर मूल बनावट के टुकड़े को काटने के लिए जिम्मेदार है। हम बाद में इसके उपयोग का विश्लेषण करेंगे।

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

 int main(int argc, char** argv){ if (SDL_Init(SDL_INIT_EVERYTHING) == -1){ std::cout << SDL_GetError() << std::endl; return 1; } window = SDL_CreateWindow("Lesson 2", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (window == nullptr){ std::cout << SDL_GetError() << std::endl; return 2; } renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if (renderer == nullptr){ std::cout << SDL_GetError() << std::endl; return 3; } 

चलो हमारे चित्र अपलोड करें। इस ट्यूटोरियल के लिए, हम एक बैकग्राउंड इमेज टाईल्स के साथ खींचेंगे और दूसरी इमेज बैकग्राउंड के ऊपर केंद्रित होगी।
यहाँ हमारी पृष्ठभूमि है:
छवि

और यह पृष्ठभूमि के शीर्ष पर होगा:
छवि

चलो लोड लोडमैज फ़ंक्शन का उपयोग करके उन्हें लोड करते हैं जो हमने लिखा था।

  SDL_Texture *background = nullptr, *image = nullptr; background = LoadImage("Lesson2res/background.bmp"); image = LoadImage("Lesson2res/image.bmp"); if (background == nullptr || image == nullptr) return 4; 

ध्यान दें कि आपको छवियों को पथ बदलने की आवश्यकता है ताकि वे आपके सिस्टम पर पथों से मेल खाएं।

इससे पहले कि हम चित्र बनाएँ, हमें यह जानना होगा कि हम उन्हें कहाँ रखना चाहते हैं। आरंभ करने के लिए, आपको यह समझने की आवश्यकता है कि एसडीएल समन्वय प्रणाली कैसे काम करती है, इसलिए यह मानक 2 डी कार्टेशियन समन्वय प्रणाली से थोड़ा अलग है। एसडीएल समन्वय प्रणाली इस तरह दिखती है:
छवि

बिंदु (0,0) स्क्रीन के ऊपरी बाएं कोने में स्थित है। स्क्रीन के नीचे जाने पर Y में मान बढ़ता है, और X में - दाईं ओर। यह भी ध्यान दिया जाना चाहिए कि छवि के ऊपरी बाएँ कोने में छवि को इंगित करते समय हम जिस बिंदु से गुजरते हैं, वह केंद्र के विपरीत, कुछ अन्य पुस्तकालयों की तरह है।

इससे पहले कि हम आकर्षित करें: याद रखें कि हम जो आकर्षित करते हैं वह बाद की छवियों के तहत स्थित होगा। इस प्रकार, पहली जगह में खींची गई तस्वीर सभी के नीचे होगी, और आखिरी में - सबसे ऊपर।

आपने शायद पहले ही ध्यान दिया है कि हमारी पृष्ठभूमि छवि में 320x240 का रिज़ॉल्यूशन है, जिसका अर्थ है कि हमें पूरी स्क्रीन को टाइल करने के लिए इसे चार बार खींचना होगा।

इससे पहले कि हम कुछ भी खींचते हैं, हम स्क्रीन को साफ करते हैं, फिर हम तत्वों को स्थिति देंगे। बनावट की चौड़ाई और ऊंचाई प्राप्त करने के लिए, हम फिर से QueryTexture फ़ंक्शन का उपयोग करेंगे। बेशक, आप पृष्ठभूमि को खींचने के लिए एक लूप का उपयोग कर सकते हैं, लेकिन इस मामले में हम बेवकूफ विधि का उपयोग करेंगे और सिर्फ एक ही पाठ को 4 बार लिखेंगे।

  SDL_RenderClear(renderer); int bW, bH; SDL_QueryTexture(background, NULL, NULL, &bW, &bH); ApplySurface(0, 0, background, renderer); ApplySurface(bW, 0, background, renderer); ApplySurface(0, bH, background, renderer); ApplySurface(bW, bH, background, renderer); 

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

  int iW, iH; SDL_QueryTexture(image, NULL, NULL, &iW, &iH); int x = SCREEN_WIDTH / 2 - iW / 2; int y = SCREEN_HEIGHT / 2 - iH / 2; ApplySurface(x, y, image, renderer); 

ड्राइंग को देखने के लिए, हमें रेंडरर को दिखाना होगा, और फिर परिणाम देखने के लिए कुछ सेकंड इंतजार करना होगा।

  SDL_RenderPresent(renderer); SDL_Delay(2000); 

अंत में, हम कब्जा की गई मेमोरी को मुक्त करके, एसडीएल से बाहर निकलें, और 0 वापस करके प्रोग्राम को समाप्त करते हैं।

  SDL_DestroyTexture(background); SDL_DestroyTexture(image); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 0; } 

जब आप प्रोग्राम को संकलित करते हैं और चलाते हैं, तो खिड़की को कुछ इस तरह देखना चाहिए:
छवि

पाठ का अंत

इसलिए आज का पाठ इसके अंत में आया है। आपको पाठ 3 में देखें: बाहरी एसडीएल पुस्तकालय।

Source: https://habr.com/ru/post/In200730/


All Articles