250 likes | 409 Views
Building a Demo Framework. David Notario XPLSV. Contents. What is a demo framework? (5 minutes) Why do you need a demo framework? (5 minutes) Case study: threepixels demo framework (35 minutes) Future (5 minutes) Questions (5 minutes). What is a demo framework.
E N D
Building a Demo Framework David Notario XPLSV
Contents • What is a demo framework? (5 minutes) • Why do you need a demo framework? (5 minutes) • Case study: threepixels demo framework (35 minutes) • Future (5 minutes) • Questions (5 minutes)
What is a demo framework • Infrastructure to build a demo. • Ideally, should provide everything you need for your demo except the actual content and effects • Graphics subsystem • I/O • File packing • Sound • Synchronization • Misc stuff (File loaders) • Preferably data driven (as opposed to code driven) • Examples: • Moppi’s DemoPaja • FarbRausch’s Demo System, • Catalyst Design’s Caos GL, • threepixels’ Studio
Why do you need a demo framework • Allows you to integrate effects in an easy manner • Tweak easily (data driven) • Test out new effects quickly • Allow artists to work in parallel with the programmers. • Reduces development time. Share your code across different demos without pain.
Some tips • Start it simple. Extend as you need. • The important thing are the demos. Don’t get lost trying to create THE demo system or THE demo. • If you spend more time writing the framework than the actual demo, you are doing something wrong. • Don’t over engineer or reinvent the wheel. Designing another language as your script language is silly if you want non programmers to use it. • You don’t need to code everything yourself. There’s a bunch of code out there you can use (Read their license first ;) • Zlib, Bass, D3DX, Flexporter, etc…
threepixels demo framework • Started working on it on 2000 • More than 20 demos have used it. • First released demo with it: Dawn/Chanka (2001) http://www.pouet.net/prod.php?which=2194 • Last released demo with it: Pilgrimage Invitation Demo/XPLSV (2003) http://www.pouet.net/prod.php?which=10460
Other productions • Black Matters/threepixels (2001) http://www.pouet.net/prod.php?which=3235 • Nature v2.0/threepixels (2001) http://www.pouet.net/prod.php?which=3859 • MDMA/threepixels (2002) http://www.pouet.net/prod.php?which=7083 • R08028/threepixels & Stravaganza (2003) http://www.pouet.net/prod.php?which=9460
Demo System components • File Subsystem • Graphics Subsystem • 3D Max Exporter • Sound Subsystem • Effects • Scripting Engine • Studio • Other auxiliar tools
File Subsystem • Wraps standard STDIO functions (old school C I/O) • Can wrap Windows’ file system or fetch files transparently from a ZIP file (useful if you want to ship all your data in a single file). • Package system (to add patches) • Example of code: MVFSFILE* f; int iReturn; f=MVFS::fopen(pcFileName, "rb"); if (!f) { return (-1); } iReturn=ReadInitializedRaw(f); MVFS::fclose(f); return (iReturn);
Graphics Subsystem • 3 Layers • D3D Wrapper: Encapsulates all low level D3D code. Also manages resources (VBs, IBs, textures, etc) • Shader Library: Receives mesh elements (a data structure describing geometry) and renders it using the shaders declared in text files (to allow artist control) • 3D Engine: Uses scenes exported from 3D Studio. Not a very complex engine for what can be done nowadays. • Some Effects bypass layer 3 and even layer 2
3DS Max Exporter • Exporter is a plugin to Pierre Terdiman’s Flexporter • Exports to a human readable XML file. This is handy as you can do a lot of editing on a text file instead of starting MAX every time you want to try something out. • Once loaded, the text file is ‘compiled’ and saved in a compact binary form. • Flexporter is good: use it, much less painful than dealing with MAX SDK
Sound Subsystem • Uses BASS library • Functionality exposed to script engine via MUSIC effect.
Effects • You provide new functionality by deriving from the Effect class and overriding the virtual functions. • Configuration of effects is done via the Command() method. Effect owns parsing. • Scripting engine drives the effects • Base Effect interface (simplified): class DemoEffect { public: DemoEffect (); virtual ~DemoEffect (); virtual int Init (const char* pcInstanceName, const char* pcCommand); virtual int Shutdown (); virtual int Start (float fTime); // Tiempo en segundos virtual int Stop (); virtual int Run (float fTime); virtual int Command (float fTime, const char* pcCommand); };
Effects (II) • Some of the effects available in the demosytem: • 3D Scene replayer • Video player • Still Images • Post Render Effects • Music • A lot of custom effects made for the different demos
Scripting Engine • Drives demo • Has the concept of layers (decides running order of effects) • Owns instantiating, loading, running and synchronizing effects. • Simple concept/code: • Has a list of active effects. Effects become active/inactive when script reads an FXSTART/FXSTOP • Synchronization. FXSYNC command. Semantics are ‘Execute active effects until time x is reached’ • Script::Run() pseudocode • Process script commands starting with Current Command until a SYNCTIME command with a time greater than the current time. Current Command is updated with last executed command • For each layer • Run currently active effects in layer • Goto step 1 if the script didn’t complete
Scripting Engine (II) • Example: // Instantiate music FXINSTANCE DEMOMUSIC MUSIC MP3 MUSIC.MP3 // Creates a 3DSCENE effect, loads FLYBY.TXT and names instance FLYBY FXINSTANCE FLYBY 3DSCENE FLYBY.TXT FXLAYER FLYBY 0 // Set FLYBY to be in LAYER 0 // Creates an IMAGE effect, loads LOGO.JPG and names instance LOGO FXINSTANCE LOGO IMAGE LOGO.JPG FXLAYER LOGO 1 // Set LOGO to be in LAYER 1 // Start both effects SYNCTIME 0.0 FXSTART LOGO FXSTART FLYBY // Change the way LOGO displays SYNCTIME 5.0 FXCOMMAND LOGO BLEND INVERT // Turn off logo SYNCTIME 10.0 FXSTOP LOGO // Our short demo ends here! SYNCTIME 15.0
Scripting Engine (III) • Watch it in action!
Studio • We were spending a lot of time synchronizing/tweaking our demos. We needed something that allowed us to do that more efficiently • Editor is basically just a frontend for the text based script. • Written with plain Win 32 APIs • WYSIWYG editor. Synchronization is easy. No more modify script/test demo/repeat cycle. • Helps user showing commands available for each effect. • Can accommodate custom UIs for any command (this feature was never used, though)
Studio (II) • Watch it in action!
What went well • Programmer/Artist isolation worked • There was a number of prods released without programmer intervention • Worked with artists with 9 hour time difference and only using MSN Messenger to communicate • Synchronization of demos was easy. • WYSIWYG allowed a lot of experimentation. • A number of times I had to look at the script to see how artist had achieved x effect. • Number of released productions increased
What went wrong • GUI is not the most usable. • Missing important features, such as undo/redo or multiple item copy paste. This was due to a initial bad design on my side of the GUI editor. • Building a GUI in plain Win 32 is insane • Doing simple things takes a lot of code compared to environments like Delphi or Windows.Forms. • No automated testing. • Functionality keeps breaking. • Communication between effects is clumsy • Using effect outputs as inputs for others was difficult. • As number of productions increased, quality went down. • Instead of making better prods in less time, a lot of small and poor quality productions were made (joke prods, etc)
Future • New UI/demo system is being built with a mix of C#/Windows Forms and C++. • GUI/High level and effects are written in C#. • Windows.Forms is great for writing UI code and custom UI controls. • Effects that require every extra bit of (non video card) performance can be written in x86 and C++ if C# isn’t good enough • Supports plugins
Future (II) • Communication between effects is now easy • Effects have typed Input/Output pins. • You can change connections dynamically • Code Example (C#) // Construct video effects video = new VideoEffect(); video.Filename = "video.avi"; video.Load(); video2 = new VideoEffect(); video2.Filename ="video2.avi";video2.Load(); // Construct Mixer and set mixer properties mixer = new MainMixer(); mixer.Load(); mixer.BlendType = Blend.Additive; mixer.Blend = 0.5f; // Connect mixer to videos mixer.InputA.Connect(video.Output); mixer.InputB.Connect(video2.Output); // Connect final layer to mixer layer.Input.Connect(mixer.Output);
Other info • Contact • mac@xplsv.com • www.xplsv.com • Source snapshot (from 2002) • http://www.threepixels.org/prods/code/3px_src2.rar • More recent snapshot available under request.