ကြန္ပ်ဴတာ ကို သံုးၿပီး 2D animation ပဲ ျဖစ္ျဖစ္ 3D animation ပဲျဖစ္ျဖစ္ လုပ္တဲ့ ဆိုတာ frame ေတြကို တစ္စကၠန္႔မွာ ဘယ္ေလာက္ ရယ္လု႔ိ သတ္မွတ္ၿပီးေတာ့ screen ေပၚကို တင္ေပးတာ ျဖစ္ပါတယ္။ ရုပ္ရွင္ film ေတြ တစ္ကြက္ခ်င္းကို အျမန္ ပံုေဖၚသလိုေပါ့။ Game အတြက္ပဲ ျဖစ္ျဖစ္၊ တစ္ျခား movie တစ္ခု အတြက္ပဲ ျဖစ္ျဖစ္ animation တစ္ခုကို လုပ္ေတာ့မယ္ ဆိုရင္ ေနာက္ကြယ္က လုပ္သြားတဲ့ programmer ေတြ သိထားသင့္တဲ့ အရာေတြ ရိွပါတယ္။
ပထမဆံုး အခ်က္ ကၽြန္ေတာ္တို႔ လုပ္ေနတဲ့ animation frame တစ္ခု ခ်င္းအတြက္ frame buffer လို႔ ေခၚတဲ့ graphic/video memory ေနရာရိွပါတယ္။ ကၽြန္ေတာ္တို႔က ဖန္တီးထားတဲ့ frame တစ္ခုစာ graphic ေတြကို monitor screen ေပၚကို
တိုက္ရိုက္ ပို႔ခြင့္ မရိွပါဘူး။ ကၽြန္ေတာ္တို႔ လုပ္လို႔ရတာက programmer တစ္ေယာက္ အေနနဲ႔ အဲဒီ monitor screen ကို တိုက္ရိုက္ ကိုယ္စားျပဳထားတဲ့ memory area ေတြကို ပဲ ထိန္းခ်ဳပ္လို႔ ရပါတယ္။ အဲဒီိလို screen ကို တိုက္ရိုက္ ကိုယ္စားျပဳထားတဲ့ memory ေတြကို frame buffer ဒါမွဟုတ္ graphic memory ေတြလုိ႔ ေခၚပါတယ္။ ေအာက္က ပံုေလးမွာ ၾကည့္ၾကည့္ပါ။
Programmer ေတြ အေနနဲ႔က render (ပံုေဖၚ) ခ်င္တဲ့ 2D/3D ပံုေတြကို အဲဒီ frame buffer memory ေတြ ေပၚမွာပဲ programming codes ေတြသံုးၿပီး ဖန္တီးရပါတယ္။ အဲဒီ frame buffer (graphic memory) ေတြ ေပၚမွာ ဖန္တီးထားတဲ့ ပံုရိပ္ေတြကို graphic hardware (GPU) ေတြက ရယူၿပီး screen ေတြေပၚကို ပို႔ေပး တာ ျဖစ္ပါတယ္။ ဒါက အရိုးရွင္းဆံုး process ပံုစံပါ။
ပံုမွန္အတိုင္း ဆိုရင္ screen ေပၚမွာ ပံုေဖၚမယ့္ ပံုရိပ္တစ္ခု အတြက္ အဲဒီ screen ကို ကိုယ္စားျပဳ ထားတဲ့ frame buffer တစ္ခု ရိွရင္ လံုေလာက္ပါတယ္။ Programmer ေတြက အဲဒီ frame buffer ကို ထိန္းခ်ဳပ္ၿပီး graphic data ေတြ ထည့္လိုက္တာနဲ႔ graphic hardware ေတြက သူ႔ဘာသာ ရယူၿပီး screen ေပၚကို ပို႔ေပး ပါလိမ့္မယ္။ (Frame buffer ေတြကို ဘယ္လို ထိန္းခ်ဳပ္တယ္ ဆိုတာ ေနာက္မွ သီးသန္႔ ေရးပါဦးမယ္)
ဒါေပမယ့္ တစ္ကယ္တမ္း animation တစ္ခုကိုု ဖန္တီးေတာ့မယ္ ဆိုရင္ screen တစ္ခု အတြက္ frame buffer တစ္ခု ထဲရိွတာ မလံုေလာက္ပါဘူး။ ဘာလို႔လည္း ဆိုေတာ့ animation တစ္ခု ကို ဖန္တီးတယ္ ဆိုရင္ ဆက္တိုက္ ေျပာင္းလဲေနတဲ့ frame ေတြကို screen ေပၚကို တစ္စကၠန္႔ကို ဘယ္ေလာက္ ႏႈန္းဆိုၿပီး ပို႔ေပးရမွာပါ။ ဥပမာ- အေနနဲ႔ ေအာက္မွာ ျပထားတဲ့ ကိစၥေလးကို စဥ္းစားၾကည့္ပါ..။
လူတစ္ေယာက္ ေျပးေနတဲ့ animation တစ္ခုကို ဖန္တီးမယ္ ဆိုပါေတာ့။ အဲဒီ animation မွာ Frame ေပါင္း အမ်ားႀကီးပါတယ္ ဆိုပါေတာ့။ ဒါဆိုရင္ ပထမဆံုး frame ကို render လုပ္ဖို႔အတြက္ ကၽြန္ေတာ္တို႔က အရင္ ဆံုး processing ေတြလုပ္ရတယ္၊ တြက္ခ်က္မႈေတြ လုပ္ရတယ္ေလ။ အဲဒီအတြက္ အခ်ိန္ေပးရပါတယ္။ ၿပီးရင္ Frame 1 ကို buffer ေပၚကို ပို႔ေပးလိုက္တယ္။ ဒါဆို screen ေပၚမွာ ေပၚလာၿပီေပါ့။ ၿပီးရင္ ဒုတိယ frame 2 အတြက္ processing ေတြလုပ္မယ္။ ၿပီးရင္ frame buffer ေပၚက ပထမ frame 1 ကို ဖ်က္ရမယ္။ ၿပီးရင္ frame 2 အတြက္ data ေတြကို frame buffer ေပၚကို တင္ရပါမယ္။ ဒါမွ frame 2 က screen ေပၚမွာ ေပၚလာမွာပါ။ ဒါေပမယ့္ အေပၚမွာ ကၽြန္ေတာ္ ေျပာတဲ့ process ေတြကို စဥ္းစားၾကည့္ပါ။ အခ်ိန္ အမ်ားႀကီး ယူပါတယ္။ ၿပီးေတာ့ အဲဒီလို frame ေတြ အမ်ားႀကီး ပါတဲ့ animation လုပ္ဖို႔ အတြက္ frame buffer တစ္ခုထဲကိုပဲ သံုးမယ္ ဆိုရင္ ဖ်က္လိုက္၊ ေရးလိုက္၊ တင္လုိက္ နဲ႔ လုပ္ေနတဲ့ အခ်ိန္မွာ screen မွာ ေပၚေနတဲ့ ပံုရိပ္ဟာ flick ျဖစ္တာကို ျမင္ေနရပါလိမ့္မယ္။ ဒါမွမဟုတ္ ဖ်က္လိုက္၊ ေရးလိုက္၊ data ေတြ တင္လုိက္ လုပ္ေနတဲ့ အခ်ိန္မွာ ၾကည့္ရတာ ဘယ္လုိမွ မေကာင္းႏိုင္ပါဘူး။ ဒါကို နားလည္မယ္ ထင္ပါတယ္။ ၾကားထဲမွာ process လုပ္ေနတဲ့ အခ်ိန္မွာ blank ျဖစ္ေနႏိုင္ပါတယ္။ ဒါကို screen flick ျဖစ္တယ္လို႔ ေျပာႏိုင္ ပါတယ္။
အဲဒါကို ေျဖရွင္းဖို႔အတြက္ ေနာက္ပိုင္း animation ေတြမွာ Double Buffering ဆ
ိုတဲ့ နည္းပညာကို အသံုးျပဳ ၾကပါတယ္။ Double buffering ဆိုတာ screen ကို ကုိယ္စားျပဳမယ့္ frame buffer ေတြကို တစ္ခုထက္ ပိုၿပီး ႏွစ္ခု အသံုးျပဳတာကို ေခၚတာပါ။ ေအာက္က ပံုမွာ ၾကည့္ပါ။ Screen ကို တိုက္ရိုက္ ဆက္သြယ္ထားတဲ့ frame buffer ကို primary buffer/primary surface လို႔ ေခၚပါတယ္။ သူ႔အေပၚမွာ ရိွေနတဲ့ graphic data ေတြက screen ေပၚမွာ တိုက္ရိုက္ ေပၚမယ့္ graphic ေတြေပါ့။ ေနာက္တစ္ခုက back buffer/back buffer surface လု႔ိ ေခၚပါတယ္။ Back buffer ေပၚမွာ ရိွေနတဲ့ graphic data ေတြက screen ေပၚမွာ ျမင္ရမွာ မဟုတ္ပါဘူး။ သူက screen ေပၚကို မပို႔ခင္ ႀကိဳၿပီး ဆြဲထားတဲ့ သေဘာပါ။
ပထမဆံုး အခ်က္ ကၽြန္ေတာ္တို႔ လုပ္ေနတဲ့ animation frame တစ္ခု ခ်င္းအတြက္ frame buffer လို႔ ေခၚတဲ့ graphic/video memory ေနရာရိွပါတယ္။ ကၽြန္ေတာ္တို႔က ဖန္တီးထားတဲ့ frame တစ္ခုစာ graphic ေတြကို monitor screen ေပၚကို
Programmer ေတြ အေနနဲ႔က render (ပံုေဖၚ) ခ်င္တဲ့ 2D/3D ပံုေတြကို အဲဒီ frame buffer memory ေတြ ေပၚမွာပဲ programming codes ေတြသံုးၿပီး ဖန္တီးရပါတယ္။ အဲဒီ frame buffer (graphic memory) ေတြ ေပၚမွာ ဖန္တီးထားတဲ့ ပံုရိပ္ေတြကို graphic hardware (GPU) ေတြက ရယူၿပီး screen ေတြေပၚကို ပို႔ေပး တာ ျဖစ္ပါတယ္။ ဒါက အရိုးရွင္းဆံုး process ပံုစံပါ။
ပံုမွန္အတိုင္း ဆိုရင္ screen ေပၚမွာ ပံုေဖၚမယ့္ ပံုရိပ္တစ္ခု အတြက္ အဲဒီ screen ကို ကိုယ္စားျပဳ ထားတဲ့ frame buffer တစ္ခု ရိွရင္ လံုေလာက္ပါတယ္။ Programmer ေတြက အဲဒီ frame buffer ကို ထိန္းခ်ဳပ္ၿပီး graphic data ေတြ ထည့္လိုက္တာနဲ႔ graphic hardware ေတြက သူ႔ဘာသာ ရယူၿပီး screen ေပၚကို ပို႔ေပး ပါလိမ့္မယ္။ (Frame buffer ေတြကို ဘယ္လို ထိန္းခ်ဳပ္တယ္ ဆိုတာ ေနာက္မွ သီးသန္႔ ေရးပါဦးမယ္)
ဒါေပမယ့္ တစ္ကယ္တမ္း animation တစ္ခုကိုု ဖန္တီးေတာ့မယ္ ဆိုရင္ screen တစ္ခု အတြက္ frame buffer တစ္ခု ထဲရိွတာ မလံုေလာက္ပါဘူး။ ဘာလို႔လည္း ဆိုေတာ့ animation တစ္ခု ကို ဖန္တီးတယ္ ဆိုရင္ ဆက္တိုက္ ေျပာင္းလဲေနတဲ့ frame ေတြကို screen ေပၚကို တစ္စကၠန္႔ကို ဘယ္ေလာက္ ႏႈန္းဆိုၿပီး ပို႔ေပးရမွာပါ။ ဥပမာ- အေနနဲ႔ ေအာက္မွာ ျပထားတဲ့ ကိစၥေလးကို စဥ္းစားၾကည့္ပါ..။
လူတစ္ေယာက္ ေျပးေနတဲ့ animation တစ္ခုကို ဖန္တီးမယ္ ဆိုပါေတာ့။ အဲဒီ animation မွာ Frame ေပါင္း အမ်ားႀကီးပါတယ္ ဆိုပါေတာ့။ ဒါဆိုရင္ ပထမဆံုး frame ကို render လုပ္ဖို႔အတြက္ ကၽြန္ေတာ္တို႔က အရင္ ဆံုး processing ေတြလုပ္ရတယ္၊ တြက္ခ်က္မႈေတြ လုပ္ရတယ္ေလ။ အဲဒီအတြက္ အခ်ိန္ေပးရပါတယ္။ ၿပီးရင္ Frame 1 ကို buffer ေပၚကို ပို႔ေပးလိုက္တယ္။ ဒါဆို screen ေပၚမွာ ေပၚလာၿပီေပါ့။ ၿပီးရင္ ဒုတိယ frame 2 အတြက္ processing ေတြလုပ္မယ္။ ၿပီးရင္ frame buffer ေပၚက ပထမ frame 1 ကို ဖ်က္ရမယ္။ ၿပီးရင္ frame 2 အတြက္ data ေတြကို frame buffer ေပၚကို တင္ရပါမယ္။ ဒါမွ frame 2 က screen ေပၚမွာ ေပၚလာမွာပါ။ ဒါေပမယ့္ အေပၚမွာ ကၽြန္ေတာ္ ေျပာတဲ့ process ေတြကို စဥ္းစားၾကည့္ပါ။ အခ်ိန္ အမ်ားႀကီး ယူပါတယ္။ ၿပီးေတာ့ အဲဒီလို frame ေတြ အမ်ားႀကီး ပါတဲ့ animation လုပ္ဖို႔ အတြက္ frame buffer တစ္ခုထဲကိုပဲ သံုးမယ္ ဆိုရင္ ဖ်က္လိုက္၊ ေရးလိုက္၊ တင္လုိက္ နဲ႔ လုပ္ေနတဲ့ အခ်ိန္မွာ screen မွာ ေပၚေနတဲ့ ပံုရိပ္ဟာ flick ျဖစ္တာကို ျမင္ေနရပါလိမ့္မယ္။ ဒါမွမဟုတ္ ဖ်က္လိုက္၊ ေရးလိုက္၊ data ေတြ တင္လုိက္ လုပ္ေနတဲ့ အခ်ိန္မွာ ၾကည့္ရတာ ဘယ္လုိမွ မေကာင္းႏိုင္ပါဘူး။ ဒါကို နားလည္မယ္ ထင္ပါတယ္။ ၾကားထဲမွာ process လုပ္ေနတဲ့ အခ်ိန္မွာ blank ျဖစ္ေနႏိုင္ပါတယ္။ ဒါကို screen flick ျဖစ္တယ္လို႔ ေျပာႏိုင္ ပါတယ္။
အဲဒါကို ေျဖရွင္းဖို႔အတြက္ ေနာက္ပိုင္း animation ေတြမွာ Double Buffering ဆ
ဒီေတာ့ process က ဘယ္လို ျဖစ္သြားမလည္း။ Animation တစ္ခုကို ဖန္တီးေတာ့မယ္ ဆိုရင္ ပထမဆံုး frame 1 ကို အရင္ ဖန္တီးမယ္၊ သူ႔ကို primary buffer ေပၚကို တင္လိုက္မယ္ ဆိုရင္ screen မွာ ေပၚလာမယ္။ Primary buffer ေပၚက graphic data ေတြကို graphic hardware က ယူၿပီးေတာ့ screen ေပၚကို ပို႔ေပးေနတဲ့ အခ်ိန္မွာ programmer ေတြက ဒုတိယ frame 2 ကို back buffer ေပၚမွာ ၾကိဳဖန္တီး ထားလုိ႔ရပါတယ္။ အဲဒီလို back buffer ေပၚမွာ ဆြဲမယ့္ graphics ေတြအတြက္ တြက္ခ်က္မႈေတြ လုပ္ရတာ ၾကာေကာင္း ၾကာႏိုင္တယ္ေလ။ သတ္မွတ္ထားတဲ့ အခ်ိန္ကို ေရာက္လာရင္ back buffer ေပၚမွာ ဖန္တီး ထားတဲ့ data ေတြကို primary surface ေပၚကို copy ကူးေပးလိုက္ရံု ပဲေပါ့။ ဒါဆို process က အရမ္း ျမန္လာမွာ ေသခ်ာပါတယ္။ အဲဒီ frame 2 ကို primary surface ေပၚကေန ယူၿပီး screen ကို ပို႔ေနတုန္း frame 3 ကို back buffer ေပၚမွာ ၾကိဳဆြဲပါ့။ ဒီလိုနဲ႔ အလုပ္လုပ္တာကို double buffering လို႔ ေခၚပါတယ္။ Double buffering ေၾကာင့္ animation frame ေတြ ၾကားမွာ အရမ္းကို smooth ျဖစ္တဲ့ animation ကို ရႏိုင္ပါတယ္။ တစ္ခ်ိဳ႕ ပိုေကာင္းေအာင္ လုပ္ခ်င္ရင္ Triple Buffering ဆိုၿပီး frame buffer (၃) ခုေတာင္ သံုးႏိုင္ပါတယ္။ ဒါေပမယ့္ သတိထားရမွာက frame buffer မ်ားလာရင္ graphic memory လုိအပ္ခ်က္ မ်ားလာပါလိမ့္မယ္။ အထူးသျဖင့္ resolution နဲ႔ color depth အေပၚ အမ်ားႀကီး မူတည္ပါတယ္။ (Resolution နဲ႔ color depth အေၾကာင္းကို ကၽြန္ေတာ္ ေရးၿပီးသားပါ)
http://thiha-ucsm.blogspot.com/2008/03/resolutions-and-color-depths.html
အခု ေနာက္ဆံုး DirectX လုိ graphic API ေတြမွာဆိုရင္ double buffering ကို ပိုေ
အာင္းေအာင္ မြမ္းမံ ထားတဲ့ Page Flipping လို နည္းပညာကို အသံုးျပဳပါတယ္။ Page Flipping က double buffering နဲ႔ ပံုစံ တူပါတယ္။ ဒါေပမယ့္သူက ပိုေကာင္းတာက back buffer မွာဆြဲထားတဲ့ ပံုေတြကို primary buffer ေပၚကို copy ကို ကူးမေနေတာ့ ပါဘူး။ Primary buffer နဲ႔ back buffer ကို ေျပာင္းယူလိုက္ရံုပါပဲ။ ရႈပ္သြားတယ္ ဆိုရင္ ေအာက္မွာ နဲနဲ ရွင္းျပ ထားပါတယ္။
ပထမ frame 1 ကို primary buffer မွာ ဆြဲမယ္။ ၿပီးရင္ screen ေပၚကို ပို႔ေနတုန္းမွာ back buffer ေပၚမွာ frame 2 ကို ဆြဲမယ္။ ၿပီးရင္ frame 2 ကို screen ေပၚကို ပို႔ဖို႔ အတြက္ back buffer ေပၚကေန primary buffer ေပၚကို copy မကူးေတာ့ ပဲနဲ႔ primary buffer ကို ညႊန္ထားတဲ့ pointer ကို back buffer ကို ေျပာင္း လိုက္ပါတယ္။ ဒါဆို Back buffer က primary ျဖစ္သြားၿပီး၊ Primary buffer က back buffer ျဖစ္သြားတာ ကို နားလည္မယ္ ထင္ပါတယ္။ ၿပီးရင္ ဟုိဘက္က ေျပာငး္သြားတဲ့ back buffer ေပၚမွာ ေနာက္ပံုရိပ္ကို ဖန္တီးမယ္။ ၿပီးရင္ ခုနကလိုပဲ back buffer နဲ႔ primary buffer ၾကားမွာ switch လုပ္မယ္။ ဒါပဲေပါ့။ အဲဒီလို လုပ္တာကို Page Flipping လုပ္တယ္လို႔ ေခၚပါတယ္။ Double buffering ထက္ ပိုျမန္ၿပီး ပိုေကာင္းတဲ့ animation smoothness ကို ရႏိုင္ပါတယ္။
ဒါက Page Flipping နဲ႔ Double Buffering နဲ႔ animation လုပ္တာကို ကၽြန္ေတာ္ သိထားသေလာက္ ျပန္ၿပီး ေျပာျပတာပါ။ တစ္ကယ္တမ္း အတြင္းက်က် animation နဲ႔ graphic rendering ကို နားလည္ဖို႔အတြက္ အဲဒီလို နည္းစနစ္ေတြကိုလည္း နားလည္ထားသင့္ပါတယ္။
အခု ေနာက္ဆံုး DirectX လုိ graphic API ေတြမွာဆိုရင္ double buffering ကို ပိုေ
ပထမ frame 1 ကို primary buffer မွာ ဆြဲမယ္။ ၿပီးရင္ screen ေပၚကို ပို႔ေနတုန္းမွာ back buffer ေပၚမွာ frame 2 ကို ဆြဲမယ္။ ၿပီးရင္ frame 2 ကို screen ေပၚကို ပို႔ဖို႔ အတြက္ back buffer ေပၚကေန primary buffer ေပၚကို copy မကူးေတာ့ ပဲနဲ႔ primary buffer ကို ညႊန္ထားတဲ့ pointer ကို back buffer ကို ေျပာင္း လိုက္ပါတယ္။ ဒါဆို Back buffer က primary ျဖစ္သြားၿပီး၊ Primary buffer က back buffer ျဖစ္သြားတာ ကို နားလည္မယ္ ထင္ပါတယ္။ ၿပီးရင္ ဟုိဘက္က ေျပာငး္သြားတဲ့ back buffer ေပၚမွာ ေနာက္ပံုရိပ္ကို ဖန္တီးမယ္။ ၿပီးရင္ ခုနကလိုပဲ back buffer နဲ႔ primary buffer ၾကားမွာ switch လုပ္မယ္။ ဒါပဲေပါ့။ အဲဒီလို လုပ္တာကို Page Flipping လုပ္တယ္လို႔ ေခၚပါတယ္။ Double buffering ထက္ ပိုျမန္ၿပီး ပိုေကာင္းတဲ့ animation smoothness ကို ရႏိုင္ပါတယ္။
ဒါက Page Flipping နဲ႔ Double Buffering နဲ႔ animation လုပ္တာကို ကၽြန္ေတာ္ သိထားသေလာက္ ျပန္ၿပီး ေျပာျပတာပါ။ တစ္ကယ္တမ္း အတြင္းက်က် animation နဲ႔ graphic rendering ကို နားလည္ဖို႔အတြက္ အဲဒီလို နည္းစနစ္ေတြကိုလည္း နားလည္ထားသင့္ပါတယ္။

0 comments:
Post a Comment