আমার পূর্বের আর্টিকেলে Perl 5-এর ডিজাইন এবং এর উপযোগিতা "glue language" হিসেবে বর্ণনা করার সময়, আমি উল্লেখ করেছিলাম যে আমি পূর্বে Bash-এ OpenGL বাইন্ডিং লিখেছিলাম। এটি হয়তো প্রুফ ছাড়া বলার জন্য খুব অবিশ্বাসযোগ্য একটি স্টেটমেন্ট, তাই আমি আমার হার্ড ড্রাইভের ধুলোকোনায় ফিরে গিয়ে, সেটি বের করলাম, একটু ফ্রেশ করলাম, ফন্ট সাপোর্ট উন্নত করলাম, ডকুমেন্টেশন লিখলাম, এবং আমার সাইটে এবং GitHub-এ পাবলিশ করলাম। (আপনাকে Bash এবং OpenGL সাপোর্ট সহ একটি সিস্টেম দরকার এটিকে ফার্স্টহ্যান্ড এক্সপেরিয়েন্স করার জন্য, কিন্তু এখানে একটি ভিডিও।)
তাহলে আমার স্বীকারোক্তি: My DeLorean runs Perl-এ বর্ণিত DeLorean ড্যাশবোর্ডের Perl গ্রাফিক্স আমার OpenGL for Bash প্রজেক্টের সাথে একটি ইতিহাস শেয়ার করে। একটি মজাদার এবং আইরনিক টুইস্টে, আমি 본래 প্রজেক্টটি ১৩ বছর আগে শুরু করেছিলাম Frozen Bubble দেখার পর এবং আমার টেকনিক্যাল সেন্সিবিলিটিজ আহত হয়েছিল যে কেউ একটি রিয়েল-টাইম ভিডিও গেম Perl-এ লিখেছে। তখন, আমার প্রাইমারি ল্যাঙ্গুয়েজ ছিল C++, এবং আমি ভিডিও গেমের জন্য OpenGL স্টাডি করছিলাম। আমি আমার বন্ধুদের ঘোষণা করলাম যে একমাত্র জিনিস যেটি আরও খারাপ হতো সেটি হতো যদি সেটি ৩D হতো এবং Bash-এ লেখা হতো। এই আইডিয়া ভয়েস আউট বলার পর, সেটি আমাকে ধাক্কা দিয়ে চলল, এবং আমি অবশেষে সেটি ট্রাই করার সিদ্ধান্ত নিলাম Perl-এ রিয়েল-টাইম গ্রাফিক্স ব্যবহারের "নischtনাকত্ব" কে one-up করার জন্য।
Bash এক্সটেন্ড করা
OpenGL সাপোর্ট Bash-এ যোগ করার সবচেয়ে ডায়রেক্ট পদ্ধতি হতো সোর্স কোড পরিবর্তন করা এবং প্রতিটি OpenGL ফাংশন শেল "বিল্টইন" হিসেবে যোগ করা; যাহোক, যেস लौকে যারা কাস্টম ভার্সন Bash ইনস্টল করতে ইচ্ছুক সেগুলোই এক্সপেরিয়েন্স করতে পারত, এবং প্রোবাবলি কেউ সেটি করতে চাইত না। এটিও "the Bash way"-এ জিনিস করার স্পিরিটে মনে হয়তো নয়।
আমি তখন একটি ক্লায়েন্ট-সার্ভার আইডিয়া ভাবলাম, যেখানে প্রতিটি OpenGL ফাংশন পাথ-এ ইনস্টল করা থাকবে এবং একটি ক্লায়েন্ট ইনভোক করবে যা একটি OpenGL সার্ভারে কানেক্ট হয়ে সেই ফাংশন এক্সিকিউট করার মেসেজ ডেলিভার করবে। সেটি একটি দightfully "awful" সলিউশন হতো, কিন্তু কতটুকু অপ্টিমাইজ করলাম না কেন, এটি আমার জন্য এখনও টু স্লো ছিল ওভারঅল গোল সফলভাবে অর্জন করার দাবি করার জন্য।
শেষে, আমি একটি ডিজাইন সেটেল করলাম যেখানে আমার থাকবে একটি "OpenGL Interpreter" প্রসেস যা OpenGL কমান্ড স্ট্যান্ডার্ড-ইন-এ পড়বে এবং যেকোনো ইউজার ইনপুট ইভেন্ট স্ট্যান্ডার্ড-আউট-এ লিখবে। তারপর একটি Bash স্ক্রিপ্ট এই ইন্টারপ্রেটারকে পাইপের সাথে কানেক্টেড স্টার্ট করতে পারবে, এবং প্রতিটি OpenGL কমান্ড একটি Bash ফাংশন হতে পারে যা পাইপে লিখে। সেটি করার সময়, আমি আমার পুরো ইফিশিয়েন্সি ট্রিকের ব্যাগ ফেললাম এবং ইন্টারপ্রেটারটি প্লেইন C-এ লিখলাম কিছু স্ট্যাটিক্যালি কম্পাইল্ড হ্যাশ টেবিল এবং রেড-ব্ল্যাক ট্রি দিয়ে।
OpenGL ইমিডিয়েট মোড
OpenGL ডিটেইলস হলো যেখানে এই প্রজেক্টটি DeLorean ড্যাশবোর্ড প্রজেক্টের সাথে ইন্টারসেক্ট করা শুরু করে। প্রথমে, আমি একটু পেছনে যাব এবং OpenGL API রিক্যাপ করব।
OpenGL সেটি সব কmän একটি প্রোগ্রাম লিখা যেটি তার গ্রাফিক্স ৩D কোঅর্ডিনেট এবং টেক্সচার দিয়ে প্ল্যান করে, তারপর সেই ডেটা গ্রাফিক্স কার্ডে শিপ করে ২D স্ক্রিনে রেন্ডার করার জন্য। খুব সিম্পলিস্টিকলি বললে, স্ক্রিনের যে অঞ্চলটি পেইন্ট হচ্ছে সেটি বর্ণনা করার জন্য একটি ম্যাথ সেট আছে, এবং সেই অঞ্চলে প্রতিটি পিক্সেলের কালার বর্ণনা করার জন্য আর একটি ম্যাথ সেট।
সबচেয়ে সাধারণ অপারেশন হলো একটি ভার্চুয়াল ৩D স্পেসে একটি ট্রায়্যাঙ্গলের তিনটি কর্নার বর্ণনা করা, OpenGL-কে বুঝতে দেওয়া সেটি ২D স্ক্রিনে কোথায় ল্যান্ড করে, তারপর এটিকে বলা একটি ২D ইমেজ সেটি স্ট্রেচ করার জন্য সেটি এলাকার ওপর, হয়তো আরেকটি ইমেজের সাথে কম্বাইনড বা কিছু ব্রাইটনেস ক্যালকুলেশন দিয়ে অ্যাল্টারড। প্রোগ্রামের মেইন লুপ এক ফ্রেম ভিডিও জেনারেট করে বাফার ওইপ করে, প্রতিটি পলিগন যা দেখা যাচ্ছে সেটি প্লট করে, এবং স্ক্রিনে পাঠায়। আপনি যদি এই পুরো स्टান্ট ১৬ মিলিসেকেন্ড বা কমে পুল অফ করতে পারেন, আপনি ৬০ ফ্রেম পার সেকেন্ড মেইনটেইন করতে পারেন এবং নাইস ফ্লুইড গ্রাফিক্স পেতে পারেন।
আমি OpenGL API-এর উত্পত্তি সম্পর্কে আথরিটিয়ারিটি সাথে কথা বলতে পারি না, কিন্তু এটা প্রিয়া ক্লিয়ার যে এটি স্ট্রিমিং এর আইডিয়া চারপাশে বিল্ট, প্রোবাবলি X11 ডিসপ্লে প্রোটোকলের সাথে কম্প্যাটিবল হতে, কিন্তু আপনি যেহেতু এটা একটি ভালো আইডিয়া। তাই, অধিকাংশ OpenGL ফাংশনের রিটার্ন ভ্যালু নেই, অন্য API-এর বিপরীতে যেখানে প্রতিটি ফাংশন কল একটি স্ট্যাটাস রিটার্ন করে যা আপনাকে আপারেশনটির আউটকাম বলে। আপনি যদি একটি OpenGL ফাংশন কল্পনা করেন যেমন glVertex3f(1,2,3) একটি প্রিন্ট স্টেটমেন্ট হিসেবে যা তিনটি নাম্বার একটি পাইপের ওভার লিখে, আপনি পেছনের সিনে কীভাবে কাজ করে সেটির একটি ভালো আইডিয়া পাবেন। ফ্যাক্ট, Bash বাইন্ডিং-এর জন্য, আমি শুধু glVertex 1 2 3 পাইপের ওভার লিখি যখন glVertex 1 2 3 এক্সিকিউট হয়। Bash স্ক্রিপ্ট ব্লাইন্ডলি রান করে, কোনো আইডিয়া নেই এর গ্রাফিক্স কমান্ডগুলো ইচ্ছামতো কিছু করছে কিনা।
OpenGL API-এ বছর들 ধরে কিছু বড় রিভিশন হয়েছে, এবং লোকেরা পুরো চ্যাপ্টার লিখেছে "রিটেইনড" vs "ইমিডিয়েট" মোড সম্পর্কে, কিন্তু এটা সব দুটি কনসেপ্টে সিম্পলিফাই হয়:
- প্রতিটি ফ্রেমে সাব ডেটা পাইপের ওভার রিসেন্ড করা স্লো, তাই রিমোট এন্ডে কিছু ক্যাশ করা যাক।
- বিল্ট-ইন ম্যাথ দিয়ে সবার প্রয়োজন পূরণ করা সম্ভব নয়, তাই লোকেদের কাস্টম ম্যাথ বর্ণনার একটি ল্যাঙ্গুয়েজ দেয়া যাক।
সেটাও সত্ত্বেও, নিউ OpenGL API-এর দ্বারা অফার করা ক্যাশিং এবং কাস্টম ম্যাট অনেক বেশি ইফিশিয়েন্ট এবং টপ-টিয়ার ভিডিও গেমের জন্য অবশ্যই দরকার, সেগুলো আরো সেটআপ এবং ওয়ার্ক করার জন্য Effort নেয় (এবং শিখতে) এবং হবিয়িস্টদের জন্য احتمالত:zono harm than good করে। সেগুলো অর avenida unnecessarily অ্যান্ড্যান্স বা হাই-ডিটেইল মডেল না হলে।
তাই, যদিও Bash OpenGL বাইন্ডিং শুধু "ডিপ্রিকেইটেড" API-র সাথে ডিল করে, আমি এখনও লোকেদের এটিকে এডুকেশন এবং টিনকারিং উদ্দেশ্যে দেখার জন্য আহ্বান করি।
ডিসপ্লে লিস্ট
খুশির কথা, আসল OpenGL API-তে কিছু ক্যাশিং মেকানিজম রয়েছে, এবং সেগুলো ব্যবহার করা সহজ। সেগুলো রফলি এই সিকোয়েন্স অনুযায়ী কাজ করে:
"Hey OpenGL, আমি চাই তুমি রিমোট এন্ডে অবজেক্ট ৩৭ তৈরি করো"
"এখানে অবজেক্ট ৩৭ বর্ণনা করা কিছু ডেটা"
"নেক্সট রেন্ডারিং স্টেপে অবজেক্ট ৩৭ ব্যবহার করো"
এটিকে আরও সহজ করতে, Bash বাইন্ডিং আপনাকে নাম্বার বদলে নাম ব্যবহার করতে দেয়।
প্রথম মূল অবজেক্ট টাইপ হলো টেক্সচার, যেখানে আপনি একটি ২D ইমেজ গ্রাফিক্স কার্ডে লোড করুন এবং তারপর "পেইন্ট" করুন পলিগনগুলোকে সেটির সাথে। দ্বিতীয়টি হলো "ডিসপ্লে লিস্ট," যেখানে আপনি OpenGL কমান্ডের একটি সিকোয়েন্স রেকর্ড করুন, তারপর সেগুলো প্লে ব্যাক করুন যেন সেগুলো একটি একক OpenGL কমান্ড।
ডিসপ্লে লিস্ট অ্যাড-হক প্রোটোটাইপিং-এ খুব ভালো কাজ করে। আপনি আপনার ৩D (বা ২D) মডেল বর্ণনা করতে পারেন কিছু সিম্পল ভার্টেক্স কমান্ড ব্যবহার করে পয়েন্ট প্লট করে, তারপর সেই পয়েন্টের সিকোয়েন্স ডিসপ্লে লিস্ট হিসেবে রেকর্ড করুন, এবং এখন আপনি সেই মডেলটিকে একটি একক কমান্ড দিয়ে রেন্ডার করতে পারেন।
এই পাওয়ার উদাহরণের জন্য, Examples ডিরেক্টরিতে Robot.sh চেক আউট করুন। এটি স্টার্টআপে রোবটের বডির প্রতিটি সেগমেন্টের জন্য একটি ডিসপ্লে লিস্ট তৈরি করে, এবং রান করার সময়, এটি কেবল ৫৮ লাইন টেক্সট প্রতি ফ্রেম ইমিট করে রোবট রেন্ডার করার জন্য। Bash খুব সহজে ১৬ মিলিসেকেন্ডে ৫৮ লাইন টেক্সট জেনারেট করতে পারে (১২ বছর আগেও পারত), তাই ডেমোটি কমন হার্ডওয়ারে ফুল স্পিডে রান করতে পারত।
ডিসপ্লে লিস্ট হলো প্রাইমারি ট্রিক যা আমি DeLorean ড্যাশবোর্ড সফ্টওয়্যারে ব্যবহার করছি Perl গ্রাফিক্সে ক্যারি ওভার করেছি। Perl ফাংশন কল C-র চেয়ে একটু এক্সপেনসিভ, স্পেশালি OpenGL 1.4-এর মত একটি ফাংশন-হেভি API-এর জন্য, কিন্তু জিনিসগুলো ডিসপ্লে লিস্টে কম্বাইন করলে, Perl-কে প্রতিটি ভিডিও ফ্রেমে বেশি কাজ করতে হয় না। আমি যদি এই ট্রিকটি Bash প্রজেক্টের জন্য না শিখতাম, Perl প্রজেক্টটি তার মত সফল হতো না।
আমি কেন ১২ বছর আগে এটি পাবলিশ করিনি?
যদিও আমি Bash-এ কিছু ফ্যান্সি অ্যানিমেশন ডেমো তৈরি করতে পারলাম, আমার আসল লক্ষ্য ছিল এটিতে একটি কমপ্লিট গেম তৈরি করা। আমি পুরনো ফ্লাইট-সিম গেম Terminal Velocity-এর একটি ক্লোন লক্ষ্য করছিলাম, এবং আমি এতটুকু পেরেছিলাম একটি স্পেসশিপ যা কিউবের একটি ফিল্ড দিয়ে উড়তে পারে (Examples-এ Flight.sh দেখুন), কিন্তু এক্সটently সমস্যা ছিল কলিশন ডিটেকশন। Bash-এ উপলব্ধ প্রিমিটিভগুলো হলো গ্লোবাল "অ্যাসোসিয়েটিভ অ্যারে" ভেরিয়েবল নামের এবং অ্যারে ভেরিয়েবল (যদিও ভার্সন ৪ এখন অ্যাসোসিয়েটিভ-অ্যারে ভেরিয়েবল দিয়ে আসে), এবং সকল ম্যাথ ইন্টিজার। যাহোক আমি ৩D ম্যাট্রিক্স রোটেশন ফিক্সড-পয়েন্ট ইন্টিজার ম্যাথ-এ পারফর্ম করতে পারলাম, কলিশন ডিটেকশন ইমপ্লিমেন্ট করা খুব বড় একটি বাধা দেখাচ্ছিল। আমি আমার ফন্ট API-র সাথেও স্যাটিসফাইড ছিলাম না। এই সমস্যা সমাধানের জন্য চিন্তা করার সময়, প্রজেক্টটি ধীরে ধীরে আমার লিস্ট থেকে বাদ পড়ে গেল।
এখানেই আমি কনক্লুড করলাম (যেমন আমি লিখেছিলাম), "Bash is a horrible glue language." যেহেতু এই প্রজেক্ট শুরু এবং শেষ হয়েছিল একটি জোক (বা এডুকেশন টুল, হয়তো) হিসেবে, একই প্রোগ্রাম স্টাইল Perl-এ আসল অ্যাপ্লিকেশনের জন্য কাফি উপযোগী সাবিত হলো। আমি যদি Frozen Bubble-কে ১৩ বছর আগে বেশি সিরিয়াসলি নিতাম, আমি Perl-এ, আমার বর্তমান ফেভারিট ল্যাঙ্গুয়েজ, একটি হেড স্টার্ট পেতাম।
আমার এই প্রজেক্টে বাগ ফিক্স ছাড়া অন্য কোনো এনহান্সমেন্টের প্ল্যান নেই, কিন্তু আমি মনে করি এটি কমপক্ষে তাদের জন্য উপযোগী হতে পারে যারা OpenGL কনসেপ্ট শিখতে চান বা কেউ যারা ফ্রি টাইম এবং M4-এ Doom ক্লোন লিখতে একটি স্ট্রং ইচ্ছা রাখেন।
এনজয়! এবং এই লিঙ্ক ফরওয়ার্ড করতে মजा করুন, অন্যথায় কেউ আপনার কথা বিশ্বাস করবে না।