230 likes | 346 Views
GraphGame gg0 14 - Script. Lua script Szécsi László. Egg / Script. ScriptedApp Scene:: ManagedApp -b ól származik Game-et ebből származtathatjuk scriptből hívható metódusokat tartalmaz egyelőre színtérépítéshez leszármaztatott osztályok ezekhez hozzátehetnek LuaTable
E N D
GraphGamegg014-Script Lua script SzécsiLászló
Egg/Script • ScriptedApp • Scene::ManagedApp-ból származik • Game-et ebből származtathatjuk • scriptből hívható metódusokat tartalmaz • egyelőre színtérépítéshez • leszármaztatott osztályok ezekhez hozzátehetnek • LuaTable • Lua táblázat formájában adott paraméterek feldolgozásához • EnumReflectionMapenum típusú paraméterekhez
Lua script • www.lua.org • teljes programnyelv • nincs main – majd a C++ programból hívunk bele • nem erősen típusos x = 3 x = "valami szöveg"
Lua táblázat tablazat= { [1]=2, ["kulcs"]=4, [5]="ertek" } • {} között,-vel elválasztott mezők, minden mező [kulcs]=ertektípusú, a kulcsés az érték is bármilyen típusú lehet • ["valami"] helyett írható: valami • így fogjuk haszálni (pl. anyag attirbútumai): {name='spotted', technique='textured', pass='textured'}
Lua táblázat tablazat= { [1]=2, ["kulcs"]=4, [5]="ertek" } • elem elérése: mivanbenne = tablazat[5] mivanitt = tablazat["kulcs"] • utóbbi így is írható: mivanitt = tablazat.kulcs
Lua függvény • a függvény is egy típus valtozoaminekfggverteketadok= function(elsoparam, masodikparam) csinaldezt(elsoparam) megezt(masodikparam) end • ezután a fggvmeghívása valtozoaminekfggverteketadok(1, 2)
Lua és OO • nincs objektum-orientáltság • de szerephetnektablázatban értékként függvények, a kulcsuk meg a nevük objektum = {metodus=function(self, masikparam) dosmthg() end } • a metódus meghívása objektum.metodus(objektum, 2) • de ugyanez rövidebben is írható: objektum:metodus(2)
LuaBind • C++ objektum -> Lua táblázat • Lua fggv meghívása -> C++ metódus hívódjon • + C++-ból tudjunk Lua metódust hívni, Lua táblázatból elemeket kivenni
C++ metódusok regisztrálása module(luaState) [ class_<ScriptedApp>("ScriptedApp") .def("Material", &ScriptedApp::addMeshMaterial) ]; a lua „virtuális gép” C++ class neve lua-ban metódus neve lua-ban metódusra mutató pointer (pointer-to-member)
Ezután a meghívása Lua-ban ehhez a tojás alakú lua változóhoz már hozzá van kötve a ScriptedApp példány O:IndexedMesh(_, {name='giraffe', file='giraffe.obj'}) ennek a paraméternek itt még nincs funkciója (az _ azegy változó neve) metódus scriptbeli neve attribútumok egy táblázatban
Hogyan csináljunk hierarchiát? • legyen a paraméter egy függvény, ami _ nevű paraméterként kapja a szülőt O:Material( _, {name='spotted', technique='textured', pass='textured'}, function(_) O:setSrv(_, {effectVariable='kdTexture', file='giraffe.jpg'}) end ) • addMeshMaterial meghívja ezt a függvényt, ami inicializálja a létrehozott Mesh::Material-t
Olvashatóbb verzió: _ mindig a szülő O:IndexedMesh(_, {name='giraffe', file='giraffe.obj'}) O:Material(_, {name='spotted', technique='textured', pass='textured'}, function(_) O:setSrv(_, {effectVariable='kdTexture', file='giraffe.jpg'}) end ) O:MultiMesh(_, {name='giraffe'}, function(_) O:FlipMesh(_, {}, function(_) O:ShadedMesh(_, {mien='basic', indexedMesh='giraffe', material='spotted'}) end ) end )
Hogy néz ki a C++ metódus? • Lua táblázatot, Lua függvényt kap, mint paramétert • luabind::object a – bármilyen Lua érték lehet • luabind::type(a) – típus lekérése • a() – lua függvény meghívása C++-ból • LuaTable segédosztály: táblázatelemek elérése
Így néz ki a C++ metódus void Script::ScriptedApp::addFlipMeshToMultiMesh( Egg::Mesh::Multi::P multiMesh, //< szülő a hierarchiában, _ a scriptben luabind::object attributes, //< lua táblázat az attributumokkal luabind::object initializer//< eztkellmeghívni a feltöltéshez ){ LuaTableattributeTable(attributes, "FlipMesh");// táblázatkezelő Egg::Mesh::Flip::P flipMesh = Egg::Mesh::Flip::create();// új objektum initializer(flipMesh);// visszahívás a scriptbe multiMesh->add(flipMesh);// kész objektumot hozzáadjuk a szülőhöz }
C++ metódus hibakezeléssel void Script::ScriptedApp::addFlipMeshToMultiMesh( Egg::Mesh::Multi::P multiMesh, //< szülő a hierarchiában, _ a scriptben luabind::object attributes, //< lua táblázat az attributumokkal luabind::object initializer//< eztkellmeghívni a feltöltéshez ){ try{ LuaTableattributeTable(attributes, "FlipMesh");// táblázatkezelő Egg::Mesh::Flip::P flipMesh = Egg::Mesh::Flip::create();// új objektum initializer(flipMesh);// visszahívás a scriptbe multiMesh->add(flipMesh);// kész objektumot hozzáadjuk a szülőhöz } catch(Egg::HrException exception){ exitWithErrorMessage(exception); } }
ScriptedApp.h /// Lua scripting state. lua_State* luaState; /// Runs a Lua script from a file. /// @paramluaFilename the Lua script file to be executed. void runScript(const std::string& luaFilename);
ScriptedApp::createResources using namespace luabind; luaState = lua_open(); open(luaState); luaL_openlibs(luaState); // ide jön a binding int s = luaL_dostring(luaState, "O = nil; _ = nil; function setEgg(egg) O = egg end"); if(s != 0){ std::string errs = lua_tostring(luaState, -1); MessageBoxA( NULL, errs.c_str(), "Lua error!", MB_OK); } call_function<Script::ScriptedApp*>(luaState, "setEgg", this);
Binding module(luaState) [ class_<Mesh::Indexed>("IndexedMesh"), class_<Mesh::Flip>("FlipMesh"), class_<Mesh::Multi>("MultiMesh"), class_<Mesh::Material>("Material"), class_<Script::ScriptedApp>("ScriptedApp") .def("IndexedMesh", &Script::ScriptedApp::addIndexedMesh) .def("Material", &Script::ScriptedApp::addMeshMaterial) .def("setSrv", &Script::ScriptedApp::addSrvToMaterial) .def("MultiMesh", &Script::ScriptedApp::addMultiMesh) .def("FlipMesh", &Script::ScriptedApp::addFlipMeshToMultiMesh) .def("ShadedMesh", &Script::ScriptedApp::addShadedMeshToFlipMesh) .def("MultiMeshFromFile", &Script::ScriptedApp::addMultiMeshFromFile) .def("StaticEntity", &Script::ScriptedApp::addStaticEntity) .def("FirstPersonCam", &Script::ScriptedApp::addFirstPersonCam) ];
Scriptből hívható metódusok legyártása • addIndexedMesh • addMeshMaterial • addSrvToMaterial • addMultiMesh • addFlipMeshToMultiMesh • addMultiMeshFromFile • addStaticEntity • addFirstPersonCam
Feladatok • új project: gg014-Script • ScriptedApp-ból származó Game • createResources • runScript("podScene.lua");
#9.0 podScene.lua O:IndexedMesh(_, {name='giraffe', file='giraffe.obj'}) O:Material(_, {name='spotted', technique='textured', pass='textured'}, function(_) O:setSrv(_, {effectVariable='kdTexture', file='giraffe.jpg'}) end ) O:MultiMesh(_, {name='giraffe'}, function(_) O:FlipMesh(_, {}, function(_) O:ShadedMesh(_, {mien='basic', indexedMesh='giraffe', material='spotted'}) end ) end )
#9.0 podScene.lua O:StaticEntity(_, {name='giraffe0', multiMesh='giraffe', position = { x=2, y=0, z=0} } ) O:FirstPersonCam(_, {name='default', position={x=20, y=20, z=20} } )
Feladatok • csináljuk meg scriptből a hátteret • fullscreenquad geometria a ‘quad.x’ betöltésével is legyártható • geopod betöltés, példányok létrehozása • geopodenvmappelt ablakokkal • 33 geopodlua ciklussal • for var=kezdo,veg,lepes do something end • neve: 'ship' .. iShip • .. a string konkatenáció operátor