210 likes | 320 Vues
GAM531 DPS931 – Week 2. Into the Engine. Last Time in GAM531…. DX11 Object. DX 11 API. iEngine. Engine. Controller. Manager. Model. 1 or 1. 1 m. 1 m. 1 m. 1 . GL 4.3 Object. GL 4.3 API. 1. DX11 Device. GL 4.3 Device. iController. iModel. 1 or 1. GL 4.3 API. DX 11 API.
E N D
GAM531DPS931 – Week 2 Into the Engine
Last Time in GAM531… DX11 Object DX 11 API iEngine Engine Controller Manager Model 1 or 1 1 m 1 m 1 m 1 GL 4.3 Object GL 4.3 API 1 DX11 Device GL 4.3 Device iController iModel 1 or 1 GL 4.3 API DX 11 API
Stepping into the Engine Engine.hpp namespace Emperor { template <RenderSystem RS> class Engine : public iEngine, public Singleton<Engine<RS>> {…}; } iEngine.hpp namespace Emperor { class iEngine {…}; }
Reviewing Namespaces int main() { Foo a; Bar::Foo b; Bar::Derp::Foo c; } or using namespace Bar; int main() { ::Foo a; Bar::Foo b; Derp::Foo c; } struct Foo { int a; }; namespace Bar{ struct Foo { ::Foo a; }; namespace Derp { struct Foo { Bar::Foo a; }; } }
Reviewing Pure Virtual Classes (Interfaces) class iThing{ virtual void doStuff() = 0; }; class Thing : public iThing { virtual void doStuff() { std::cin << “Thing”; } }; int main() { Thing* a = new Thing(); a->doStuff(); }; int main() { //iThing* a = new iThing(); iThing* a = new BigThing(); a->doStuff(); }; int main() { Thing* a = new BigThing(); a->doStuff(); }; class BigThing : pulic Thing { void doStuff() { std::cin << “BigThing”; } };
The Engine Interface Create & Destroy Engine (Friends for Dynamic Linking) class iEngine { private: friend iEngine* createEngine(RenderSystem); friend void releaseEngine(iEngine*); protected: virtual ~iEngine() {} public: virtual void initialize() = 0; virtual void release() = 0; virtual void setFullScreen(bool) = 0; virtual boolisFullScreen() = 0; virtual void activateDevice(iWindow*) = 0; virtual iResourceController* getResourceController() = 0; virtual iSceneController* getSceneController() = 0; virtual void render() = 0; }; Initialize and Release Engine Assets Activates Device for rendering Render a Single Frame Retrieve Controllers
Back to the Engine Engine.hpp namespace Emperor { template <RenderSystem RS> class Engine : public iEngine, public Singleton<Engine<RS>> {…}; } iEngine.hpp namespace Emperor { class iEngine {…}; }
Template Review class Foo_of_int { int a; public: Foo() {a = 0;} void doStuff() { std::cout << “Foo”; } }; template <class T> class Foo { T a; public: Foo() {a = 0;} void doStuff(); }; int main() { Foo<int> a; Foo<float> b; Foo<char*> c; } template <class T> void Foo<T>::doStuff() { std::cout << “Foo”; }; class Foo_of_char_ptr { char* a; public: Foo() {a = 0;} void doStuff() { std::cout << “Char* Foo”; } }; class Foo_of_float { float a; public: Foo() {a = 0;} void doStuff() { std::cout << “Foo”; } }; template <> void Foo<char*>::doStuff() { std::cout << “Char* Foo”; };
Template Specialization Review… template <RenderSystem RS> class Device{}; int main() { Device<RS_DX11> a; Device<RS_GL43> b; template <> class Device<RS_DX11> { private: IDXGISwapChain* swap; ID3D11Device* dev; ID3D11DeviceContext* con; … }; Device<RS_GL43 + 1> c; } template<> class Device<RS_GL43> { private: HGLRC context; HDC hdc; … };
Template Misc. Review All three are the same! template <class T = int, int N = 4> class Foo { T a[N]; }; int main() { Foo<int, 4> a; Foo<int> b; Foo<> c; } file.hpp template <class T> class Foo { T a; public: void doStuff(); }; file.cpp template <class T> void Foo<T>::doStuff() { std::cout << “Foo”; }; Compiler does nothing! Linker can’t find function! Compiles for int and float, can only be bound to those! template class Foo<int>; template class Foo<float>;
Back to the Engine Engine.hpp namespace Emperor { template <RenderSystem RS> class Engine : public iEngine, public Singleton<Engine<RS>> {…}; } iEngine.hpp namespace Emperor { class iEngine {…}; }
The Singleton Static Variables class Engine { public: static Engine* self; Engine() {self = this;}static Engine* getPtr() { return self; } void stuff(); }; Engine<RS>* engine; x10,000 Engine::getPtr()->stuff();
Our Singleton Class (hold on…) template <class D> class Singleton { private: static D* self; protected: public: Singleton() { if(!self) self = (D*)this; else EMP_FATAL_ERROR(“…"); } virtual ~Singleton() {self = 0;} static D* getPtr() {return self;} }; template <class D> D* Singleton<D>::self = nullptr; template <RenderSystem RS> class Engine : public iEngine, public Singleton<Engine<RS>> {…}; } Engine<RS>::getPtr()->initialize();
Deeper into the Engine Engine Controller 1 m Engine.hpp namespace Emperor { template <RenderSystem RS> class Engine : public iEngine, public Singleton<Engine<RS>> { SceneController<RS> sCont; ResourceController<RS> rCont; … public: iSceneController* getSceneController() {return &sCont;} iResourceController* getResourceController() {return &rCont;} }; }
Why do we use controllers? Convenience & Separation Scene Resource Window
Scene vs. Resource Statue1.obj Summoner.obj FatDude.obj
Controller Manager Into the Controller 1 m iSceneController.hpp namespace Emperor { … class iSceneController { … public: virtual iActor* createActor() = 0; virtual iCamera* createCamera() = 0; virtual iLight* createLight() = 0; virtual iNode* createNode() = 0; }; } SceneController.hpp namespace Emperor { template <RenderSystem RS> class SceneController : public iSceneController { public: ActorManager<RS> actMan; CameraManager<RS> camMan; LightManager<RS> lgtMan; NodeManager<RS> nodMan; … }; }
What does a Manager Do? Hiring – Creating the object Firing – Destroying the object Keeping Tabs – Having a reference to all objects Organizing/Scheduling – Dealing with tasks that deal with all objects Damage Control – Releasing resources if they have not been released by shutdown
Into the Manager Manager Model 1 m BaseManager.hpp template <class T> class BaseManager { protected: ArrayList<T*> objects; ArrayList<T*> activeObjects; public: BaseManager() {} virtual ~BaseManager() {…} T* createObject() {…} void removeObject(T* o) {…} void activateObject(T* o) {…} void deactivateObject(T* o) {…} }; #define ArrayListstd::vector
Finishing Recap • Namespaces allow for the separation and grouping of classes and functions to reduce naming collisions • Interfaces expose a pure virtual class that can be used by external code control objects within another code base • Templates enable coders to write logic that can be reinterpreted by the compiler multiple times with different data types and parameters • The singleton provides a code base with global-like variable access without the issues that come with using global variables • Controllers provide client code with easy to use controls that enable them to create and retrieve specific classes and objects from inside the engine • Managers keep lists of all instances of a certain data type and are able to provide batch processing and damage control when de-allocating objects
To Do • Create zenit wiki accounts if you don’t already have one • Add your user information to the student list on the wiki • Read over Assignment 1 (will be released Friday) • Begin to look for group partners (2-3 per group) • Bookmark the GAM531 website • Make an account on Bit Bucket (sorry…)