Surreal इंजन C++ को WebAssembly में पोर्ट करना

Written by

in

इस पोस्ट में मैं बताऊंगा कि कैसे मैंने Surreal इंजन गेम इंजन को WebAssembly में पोर्ट किया।
https://demensdeum.com/demos/SurrealEngine/”
अवास्तविक इंजन – एक गेम इंजन जो अवास्तविक इंजन 1 की अधिकांश कार्यक्षमता को लागू करता है, इस इंजन पर प्रसिद्ध गेम – अवास्तविक टूर्नामेंट 99, अवास्तविक, ड्यूस एक्स, अनडाइंग। यह क्लासिक इंजनों को संदर्भित करता है जो मुख्य रूप से एकल-थ्रेडेड निष्पादन वातावरण में काम करते हैं।
मूल रूप से मेरे मन में एक ऐसे प्रोजेक्ट को लेने का विचार था जिसे मैं किसी भी उचित समय सीमा में पूरा नहीं कर सका, इस प्रकार मैंने अपने ट्विच अनुयायियों को दिखाया कि ऐसे प्रोजेक्ट भी हैं जिन्हें मैं भी नहीं कर सकता। अपनी पहली स्ट्रीम के दौरान, मुझे अचानक एहसास हुआ कि Emscripten का उपयोग करके Surreal इंजन C++ को WebAssembly में पोर्ट करने का कार्य संभव था।

एक महीने बाद, मैं WebAssembly पर अपना फ़ोर्क और इंजन असेंबली प्रदर्शित कर सकता हूँ:
https://demensdeum.com/demos/SurrealEngine/
नियंत्रण, मूल की तरह, कीबोर्ड तीरों का उपयोग करके किया जाता है। इसके बाद, मैं इसे मोबाइल नियंत्रण (टैची) के लिए अनुकूलित करने की योजना बना रहा हूं, जिसमें सही प्रकाश व्यवस्था और अवास्तविक टूर्नामेंट 99 रेंडर की अन्य ग्राफिक विशेषताएं शामिल हैं।

कहां से शुरू करें?

पहली बात जो मैं कहना चाहता हूं वह यह है कि किसी भी प्रोजेक्ट को Emscripten का उपयोग करके C++ से WebAssembly में पोर्ट किया जा सकता है, एकमात्र सवाल यह है कि कार्यक्षमता कितनी पूर्ण होगी। ऐसा प्रोजेक्ट चुनें जिसके लाइब्रेरी पोर्ट एम्सस्क्रिप्टेन के लिए पहले से ही उपलब्ध हों; Surreal इंजन के मामले में, आप बहुत भाग्यशाली हैं, क्योंकि इंजन SDL 2, OpenAL – का उपयोग करता है। पुस्तकालय. वे दोनों एम्सस्क्रिप्टेन में पोर्ट किए गए हैं। हालाँकि, वल्कन का उपयोग ग्राफिक्स एपीआई के रूप में किया जाता है, जो वर्तमान में HTML5 के लिए उपलब्ध नहीं है, WebGPU को लागू करने के लिए काम चल रहा है, लेकिन यह ड्राफ्ट चरण में भी है, और यह भी अज्ञात है कि पूरी तरह से मानकीकृत होने के बाद Vulkan से WebGPU तक का पोर्ट कितना सरल होगा। इसलिए, मुझे Surreal इंजन के लिए अपना स्वयं का मूल OpenGL-ES/WebGL रेंडरर लिखना पड़ा।

परियोजना का निर्माण

Surreal इंजन में सिस्टम बनाएँ – सीएमके, जो पोर्टिंग को भी सरल बनाता है, क्योंकि एम्सस्क्रिप्टन अपने मूल बिल्डरों को प्रदान करता है – एममेक, एममेक।
Surreal इंजन पोर्ट WebGL/OpenGL ES और C++ में डेथ-मास्क नामक मेरे नवीनतम गेम के कोड पर आधारित था, इस वजह से विकास बहुत सरल था, मेरे पास सभी आवश्यक बिल्ड फ़्लैग और कोड उदाहरण थे।
CMakeLists.txt में सबसे महत्वपूर्ण बिंदुओं में से एक Emscripten के लिए बिल्ड फ़्लैग है, नीचे प्रोजेक्ट फ़ाइल से एक उदाहरण दिया गया है:

set(CMAKE_CXX_FLAGS "-s MIN_WEBGL_VERSION=2 
-s MAX_WEBGL_VERSION=2 
-s EXCEPTION_DEBUG 
-fexceptions 
--preload-file UnrealTournament/ 
--preload-file SurrealEngine.pk3 
--bind 
--use-preload-plugins 
-Wall 
-Wextra 
-Werror=return-type 
-s USE_SDL=2 
-s ASSERTIONS=1 
-w 
-g4 
-s DISABLE_EXCEPTION_CATCHING=0 
-O3 
--no-heap-copy 
-s ALLOW_MEMORY_GROWTH=1 
-s EXIT_RUNTIME=1")

बिल्ड स्क्रिप्ट स्वयं:

clear
emmake make -j 16
cp SurrealEngine.data /srv/http/SurrealEngine/SurrealEngine.data
cp SurrealEngine.js /srv/http/SurrealEngine/SurrealEngine.js
cp SurrealEngine.wasm /srv/http/SurrealEngine/SurrealEngine.wasm
cp ../buildScripts/Emscripten/index.html /srv/http/SurrealEngine/index.html

इसके बाद, आइए index.html तैयार करें, जिसमें प्रोजेक्ट फ़ाइल सिस्टम प्रीलोडर शामिल है। वेब पर अपलोड करने के लिए, मैंने अवास्तविक टूर्नामेंट डेमो संस्करण 338 का उपयोग किया। जैसा कि आप सीएमके फ़ाइल से देख सकते हैं, अनपैक्ड गेम फ़ोल्डर को बिल्ड निर्देशिका में जोड़ा गया था और एम्सस्क्रिप्टेन के लिए प्रीलोड-फ़ाइल के रूप में लिंक किया गया था।

मुख्य कोड परिवर्तन

फिर हमें गेम के गेम लूप को बदलना पड़ा, आप एक अंतहीन लूप नहीं चला सकते, इससे ब्राउज़र फ़्रीज़ हो जाता है, इसके बजाय आपको emscripten_set_main_loop का उपयोग करने की आवश्यकता है, मैंने इस सुविधा के बारे में अपने 2017 नोट में लिखा था ” target=’_blank’>SDL C++ गेम्स को HTML5 (Emscripten) में पोर्ट करना”
हम while लूप से बाहर निकलने के लिए कोड को if में बदलते हैं, फिर हम गेम इंजन के मुख्य वर्ग को प्रदर्शित करते हैं, जिसमें गेम लूप होता है, वैश्विक दायरे में, और एक वैश्विक फ़ंक्शन लिखते हैं जो वैश्विक ऑब्जेक्ट से गेम लूप चरण को कॉल करेगा:

#if __EMSCRIPTEN__
#include <emscripten.h>
Engine *EMSCRIPTEN_GLOBAL_GAME_ENGINE = nullptr;
void emscripten_game_loop_step() {
	EMSCRIPTEN_GLOBAL_GAME_ENGINE->Run();
}
#endif

इसके बाद, आपको यह सुनिश्चित करना होगा कि एप्लिकेशन में कोई पृष्ठभूमि थ्रेड नहीं हैं; यदि हैं, तो एकल-थ्रेडेड निष्पादन के लिए उन्हें फिर से लिखने के लिए तैयार हो जाएं, या एम्सस्क्रिप्टन में phtread लाइब्रेरी का उपयोग करें।
Surreal इंजन में बैकग्राउंड थ्रेड का उपयोग संगीत चलाने के लिए किया जाता है, मुख्य इंजन थ्रेड से वर्तमान ट्रैक, संगीत चलाने की आवश्यकता या उसकी अनुपस्थिति के बारे में डेटा आता है, फिर बैकग्राउंड थ्रेड म्यूटेक्स के माध्यम से एक नई स्थिति प्राप्त करता है और नया संगीत बजाना शुरू कर देता है, या रुक जाता है। प्लेबैक के दौरान संगीत को बफ़र करने के लिए बैकग्राउंड थ्रेड का भी उपयोग किया जाता है।
पाथ्रेड के साथ एम्सस्क्रिप्टेन के लिए सररियल इंजन बनाने के मेरे प्रयास असफल रहे, क्योंकि एसडीएल2 और ओपनएएल पोर्ट बिना पाथ्रेड समर्थन के बनाए गए थे, और मैं संगीत के लिए उनका पुनर्निर्माण नहीं करना चाहता था। इसलिए, मैंने लूप का उपयोग करके पृष्ठभूमि संगीत स्ट्रीम की कार्यक्षमता को एकल-थ्रेडेड निष्पादन में स्थानांतरित कर दिया। C++ कोड से pthread कॉल्स को हटाकर, मैंने बफ़रिंग और संगीत प्लेबैक को मुख्य थ्रेड में स्थानांतरित कर दिया, ताकि कोई देरी न हो, मैंने बफ़र को कुछ सेकंड तक बढ़ा दिया।
आगे, मैं ग्राफिक्स और ध्वनि के विशिष्ट कार्यान्वयन का वर्णन करूंगा।

वल्कन समर्थित नहीं है!

हाँ, Vulkan HTML5 में समर्थित नहीं है, हालाँकि सभी मार्केटिंग ब्रोशर Vulkan के मुख्य लाभ के रूप में क्रॉस-प्लेटफ़ॉर्म और व्यापक प्लेटफ़ॉर्म समर्थन प्रस्तुत करते हैं। इस कारण से, मुझे सरलीकृत OpenGL प्रकार – के लिए अपना स्वयं का मूल ग्राफ़िक्स रेंडरर लिखना पड़ा। ईएस, इसका उपयोग मोबाइल उपकरणों पर किया जाता है, कभी-कभी इसमें आधुनिक ओपनजीएल की फैशनेबल विशेषताएं शामिल नहीं होती हैं, लेकिन यह वेबजीएल को बहुत अच्छी तरह से पोर्ट करता है, जो कि एम्सस्क्रिप्टेन लागू करता है। सबसे सरल जीयूआई डिस्प्ले के लिए बुनियादी टाइल रेंडरिंग, बीएसपी रेंडरिंग लिखना और मॉडल + मैप रेंडर करना दो सप्ताह में पूरा हो गया। यह शायद परियोजना का सबसे कठिन हिस्सा था। Surreal इंजन रेंडरिंग की पूर्ण कार्यक्षमता को लागू करने के लिए अभी भी बहुत काम बाकी है, इसलिए कोड और पुल अनुरोधों के रूप में पाठकों की किसी भी मदद का स्वागत है।

OpenAL समर्थित!

बड़ी किस्मत यह है कि Surreal इंजन ऑडियो आउटपुट के लिए OpenAL का उपयोग करता है। OpenAL में एक सरल हैलो वर्ल्ड लिखने और इसे Emscripten का उपयोग करके WebAssembly में इकट्ठा करने के बाद, मुझे यह स्पष्ट हो गया कि सब कुछ कितना सरल था, और मैंने ध्वनि को पोर्ट करना शुरू कर दिया।
कई घंटों की डिबगिंग के बाद, यह स्पष्ट हो गया कि एम्सस्क्रिप्टेन के ओपनएएल कार्यान्वयन में कई बग हैं, उदाहरण के लिए, जब मोनो चैनलों की संख्या को पढ़ना शुरू किया जाता है, तो विधि एक अनंत संख्या लौटाती है, और अनंत आकार के वेक्टर को प्रारंभ करने का प्रयास करने के बाद, C++ अपवाद वेक्टर::लेंथ_एरर के साथ क्रैश हो जाता है।
हम मोनो चैनलों की संख्या को 2048 तक हार्डकोड करके इससे निजात पाने में कामयाब रहे:

		alcGetIntegerv(alDevice, ALC_MONO_SOURCES, 1, &monoSources);
		alcGetIntegerv(alDevice, ALC_STEREO_SOURCES, 1, &stereoSources);

#if __EMSCRIPTEN__
		monoSources = 2048; // for some reason Emscripten's OpenAL gives infinite monoSources count, bug?
#endif

क्या कोई नेटवर्क है?

Surreal इंजन वर्तमान में ऑनलाइन खेल का समर्थन नहीं करता है, बॉट्स के साथ खेलना समर्थित है, लेकिन हमें इन बॉट्स के लिए AI लिखने के लिए किसी की आवश्यकता है। सैद्धांतिक रूप से, आप Websockets का उपयोग करके WebAssembly/Emscripten पर एक नेटवर्क गेम लागू कर सकते हैं।

निष्कर्ष

अंत में, मैं यह कहना चाहूंगा कि पुस्तकालयों के उपयोग के कारण Surreal इंजन की पोर्टिंग काफी सुचारू हो गई, जिसके लिए Emscripten पोर्ट हैं, साथ ही Emscripten पर WebAssembly के लिए C++ में एक गेम को लागू करने का मेरा पिछला अनुभव भी है। विषय पर ज्ञान के स्रोतों और भंडारों के लिंक नीचे दिए गए हैं।
एम-एम-एम-राक्षस हत्या!
इसके अलावा, यदि आप प्रोजेक्ट में मदद करना चाहते हैं, अधिमानतः वेबजीएल/ओपनजीएल ईएस रेंडरिंग कोड के साथ, तो मुझे टेलीग्राम में लिखें:
https://t.me/demenscave

लिंक

https://demensdeum.com/demos/SurrealEngine/

https://github.com/demensdeum/SurrealEngine-Emscripten

https://github.com/dpjudas/SurrealEngine

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *