VR Juggler 1.0VR Juggler 1.0Application ProgrammingApplication Programming
Patrick HartlingPatrick Hartling
Virtual Reality Applications CenterVirtual Reality Applications Center
IEEE VR 2002IEEE VR 2002
VR Juggler — www.vrjuggler.org
ObjectivesObjectives
• Learn VR Juggler programming basicsLearn VR Juggler programming basics• Be able to write VR Juggler applicationsBe able to write VR Juggler applications
• Please: Ask questions!!! Please: Ask questions!!!
VR Juggler — www.vrjuggler.org
OverviewOverview
• Application objectsApplication objects• VR Juggler utility classesVR Juggler utility classes• Simple VR Juggler applicationSimple VR Juggler application• Advanced OGL applicationAdvanced OGL application
VR Juggler — www.vrjuggler.org
Online DocumentationOnline Documentation
• www.vrjuggler.orgwww.vrjuggler.org• ““Projects”Projects”
– VR JugglerVR Juggler DocumentationDocumentation
• Guides and Guides and referencesreferences
VR Juggler — www.vrjuggler.org
Application ObjectsApplication Objects
– All VR Juggler applications are objectsAll VR Juggler applications are objects– Override methods of a pre-defined interfaceOverride methods of a pre-defined interface
Derived class for each graphics APIDerived class for each graphics API
– No No main()main() – “Don’t call me, I’ll call you” – “Don’t call me, I’ll call you” Kernel controls application by calling methodsKernel controls application by calling methods
vjApp
+init()+apiInit()+exit()+preFrame()+intraFrame()+postFrame()
class MyApp : public vjApp{ void init(); void apiInit(); void exit(); void preFram e();
.
.
.};
VR Juggler — www.vrjuggler.org
Application ObjectsApplication Objects
• Application object is Application object is derived from graphics API derived from graphics API specific base classspecific base class
• User application methods User application methods must “fill-in-the-blank” must “fill-in-the-blank”
+init()+apiInit()+preFrame()+intraFrame()+postFrame()+...()
vjApp
+draw()+contextInit()+contextPreDraw()+...()
vjGlApp
+init()+apiInit()+preFrame()+intraFrame()+postFrame()+draw()+contextInit()+contextPreDraw()+...()
myApp
VR Juggler — www.vrjuggler.org
#include <simpleApp.h>
int main (int argc, char* argv[])
{
// Get kernel
vjKernel* kernel = vjKernel::instance();
simpleApp* app = new simpleApp(); // Create app obj
kernel->loadConfigFile(…); // Configure kernel
kernel->start(); // Start kernel thread
kernel->setApplication(app); // Give app to kernel
while ( ! exit )
{
// sleep }
}
VR Juggler VR Juggler main()main()
• How VR Juggler How VR Juggler “starts-up”“starts-up”
VR Juggler — www.vrjuggler.org
#include <simpleApp.h>
int main (int argc, char* argv[])
{
// Get kernel
vjKernel* kernel = vjKernel::instance();
simpleApp* app = new simpleApp(); // Create app obj
kernel->loadConfigFile(…); // Configure kernel
kernel->start(); // Start kernel thread
kernel->setApplication(app); // Give app to kernel
while ( ! exit )
{
// sleep }
}
VR Juggler VR Juggler main()main()
• Get handle to Get handle to kernelkernel
VR Juggler — www.vrjuggler.org
#include <simpleApp.h>
int main (int argc, char* argv[])
{
// Get kernel
vjKernel* kernel = vjKernel::instance();
simpleApp* app = new simpleApp(); // Create app obj
kernel->loadConfigFile(…); // Configure kernel
kernel->start(); // Start kernel thread
kernel->setApplication(app); // Give app to kernel
while ( ! exit )
{
// sleep }
}
VR Juggler VR Juggler main()main()
• Create the Create the applicationapplication– Instance of user’s Instance of user’s
application objectapplication object
VR Juggler — www.vrjuggler.org
#include <simpleApp.h>
int main (int argc, char* argv[])
{
// Get kernel
vjKernel* kernel = vjKernel::instance();
simpleApp* app = new simpleApp(); // Create app obj
kernel->loadConfigFile(…); // Configure kernel
kernel->start(); // Start kernel thread
kernel->setApplication(app); // Give app to kernel
while ( ! exit )
{
// sleep }
}
VR Juggler VR Juggler main()main()
• Give the kernel Give the kernel initial configuration initial configuration filesfiles
• Start the kernel Start the kernel threadthread– VR Juggler is now VR Juggler is now
fully runningfully running
VR Juggler — www.vrjuggler.org
#include <simpleApp.h>
int main (int argc, char* argv[])
{
// Get kernel
vjKernel* kernel = vjKernel::instance();
simpleApp* app = new simpleApp(); // Create app obj
kernel->loadConfigFile(…); // Configure kernel
kernel->start(); // Start kernel thread
kernel->setApplication(app); // Give app to kernel
while ( ! exit )
{
// sleep }
}
VR Juggler VR Juggler main()main()
• Give the kernel an Give the kernel an application to runapplication to run
• Kernel now starts Kernel now starts calling the calling the application object’s application object’s methodsmethods
VR Juggler — www.vrjuggler.org
Application Object MethodsApplication Object MethodsInitializationInitialization
• init()init(): Application initialization: Application initialization– Ex: Loading data files, lookup tablesEx: Loading data files, lookup tables
• apiInit()apiInit(): Graphics API specific initialization: Graphics API specific initialization– Ex: scene graph loadingEx: scene graph loading
Frame functionsFrame functions• preFrame()preFrame(): Called at start of frame: Called at start of frame
– Ex: Updating data in response to device input Ex: Updating data in response to device input
• intraFrame()intraFrame(): Called while rendering: Called while rendering– Ex: Time consuming computation for next frameEx: Time consuming computation for next frame
• postFrame()postFrame(): Called after frame is done: Called after frame is done– Ex: Clean up, sync with external net or computeEx: Clean up, sync with external net or compute
+init()+apiInit()+preFrame()+intraFrame()+postFrame()+...()
vjApp
+draw()+contextInit()+contextPreDraw()+...()
vjGlApp
+init()+apiInit()+preFrame()+intraFrame()+postFrame()+draw()+contextInit()+contextPreDraw()+...()
myApp
VR Juggler — www.vrjuggler.org
Application InterfaceApplication Interface
• Other…Other…– ReconfigurationReconfiguration– ResetReset– ExitExit– Focus changeFocus change
+init()+apiInit()+preFrame()+intraFrame()+postFrame()+...()
vjApp
+draw()+contextInit()+contextPreDraw()+...()
vjGlApp
+init()+apiInit()+preFrame()+intraFrame()+postFrame()+draw()+contextInit()+contextPreDraw()+...()
myApp
VR Juggler — www.vrjuggler.org
#include <simpleApp.h>
int main (int argc, char* argv[])
{
// Get kernel
vjKernel* kernel = vjKernel::instance();
simpleApp* app = new simpleApp(); // Create app obj
kernel->loadConfigFile(…); // Configure kernel
kernel->start(); // Start kernel thread
kernel->setApplication(app); // Give app to kernel
while ( ! exit )
{
// sleep }
}
Call TimingCall Timing
• setApplication()setApplication() starts the kernel calling the starts the kernel calling the application’s member functionsapplication’s member functions
kern
vjKernel
while(running)
OGLApp
vjGlApp
drawMgr
vjGlDrawManager
inputMgr
vjInputManager
/postFrame():void
/intraFrame():void
/preFrame():void
/apiInit():void
/init():void
/sync():void
/draw():void
/initAPI():void
/updateAllData():void
VR Juggler — www.vrjuggler.org
Call timing: Init Call timing: Init membersmembers• init()init()
– Called after kernel Called after kernel gets app gets app
• apiInit()apiInit()– Called after Called after
graphics API is graphics API is runningrunning
kern
vjKernel
while(running)
OGLApp
vjGlApp
drawMgr
vjGlDrawManager
inputMgr
vjInputManager
/postFrame():void
/intraFrame():void
/preFrame():void
/apiInit():void
/init():void
/sync():void
/draw():void
/initAPI():void
/updateAllData():void
VR Juggler — www.vrjuggler.org
Call timing: Frame Call timing: Frame membersmembers• preFrame()preFrame()
– Called after input updateCalled after input update
• intraFrame()intraFrame()– Called while rendering of Called while rendering of
environment is happeningenvironment is happening
• postFrame()postFrame()– Called after frame but before Called after frame but before
tracker updatestracker updates
kern
vjKernel
while(running)
OGLApp
vjGlApp
drawMgr
vjGlDrawManager
inputMgr
vjInputManager
/postFrame():void
/intraFrame():void
/preFrame():void
/apiInit():void
/init():void
/sync():void
/draw():void
/initAPI():void
/updateAllData():void
VR Juggler — www.vrjuggler.org
vjGlAppvjGlApp: OpenGL : OpenGL Application InterfaceApplication Interface
• Derived from Derived from vjAppvjApp• OpenGL specific extensionsOpenGL specific extensions
– draw()draw() Draw the scene in OpenGLDraw the scene in OpenGL Called for each OpenGL contextCalled for each OpenGL context Stereo Stereo Called once per eye Called once per eye
– contextInit()contextInit(), , contextPreDraw()contextPreDraw(), , contextClose()contextClose()
Discussed laterDiscussed later
+init()+apiInit()+preFrame()+intraFrame()+postFrame()+...()
vjApp
+draw()+contextInit()+contextPreDraw()+...()
vjGlApp
+init()+apiInit()+preFrame()+intraFrame()+postFrame()+draw()+contextInit()+contextPreDraw()+...()
myApp
VR Juggler — www.vrjuggler.org
vjPfAppvjPfApp: Performer: PerformerApplication InterfaceApplication Interface
• Derived from Derived from vjAppvjApp• Performer specific Performer specific
extensionsextensions– initScene()initScene()
Create the scene graphCreate the scene graph
– getScene()getScene() Return the root of the scene Return the root of the scene
graphgraph
+init()+apiInit()+preFrame()+intraFrame()+postFrame()+...()
vjApp
+initScene()+getScene()+...()
vjPfApp
+init()+apiInit()+preFrame()+intraFrame()+postFrame()+initScene()+getScene()+...()
myPfApp
VR Juggler — www.vrjuggler.org
Common ClassesCommon Classes
Helper classes needed for app Helper classes needed for app developmentdevelopment• Mathematics: matrix, vector, pointMathematics: matrix, vector, point• Input devicesInput devices
VR Juggler — www.vrjuggler.org
Common Classes: Common Classes: vjMatrixvjMatrix
4x4 matrix4x4 matrix• OpenGL orderingOpenGL ordering
MethodsMethods• Rotation: Rotation: makeXYZEuler()makeXYZEuler(), , makeRot()makeRot()• Translation: Translation: makeTrans()makeTrans(), , setTrans()setTrans()• Multiplication: Multiplication: mult()mult(), , preMult()preMult(), , postMult()postMult()
• Many others… (see Many others… (see Programmer’s GuideProgrammer’s Guide))
VR Juggler — www.vrjuggler.org
Common Classes: Common Classes: vjVec3vjVec3 & & vjVec4vjVec4
• Class for float vectorClass for float vector• Used for points and raysUsed for points and rays• MethodsMethods
– +,-,=+,-,=– dot()dot(), , normalize()normalize(), , cross()cross()– Many others… (see Many others… (see Programmer’s GuideProgrammer’s Guide))
VR Juggler — www.vrjuggler.org
Common Classes: Common Classes: vjProxyvjProxy
• Proxies are used to access all input dataProxies are used to access all input datawand_pos = mWandProxy->getData();wand_pos = mWandProxy->getData();
• Proxies cache and transform input dataProxies cache and transform input data
0..1
0..1
0..*
vjPosProxy
vjPosProxy~vjPosProxyupdateDatagetUpdateTimesetTransformsetgetDatagetUnitgetPositionPtrgetTransformtransformDatagetChunkTypeconfiggetProxiedInputDevice
vjPosInterface
vjPosInterfaceoperator->operator*refresh
vjPosition
vjPosition~vjPositionconfigstartSamplingstopSamplingsampleupdateDatagetDeviceNamegetPosDatagetPosUpdateTime
VR Juggler — www.vrjuggler.org
Common Classes: Common Classes: vjDeviceInterfacevjDeviceInterface
– Used to get access to devices through proxiesUsed to get access to devices through proxies
– Smart pointer to a device proxySmart pointer to a device proxy
– Makes proxies easier to useMakes proxies easier to use
– init()init()mWand.init(“VJWand”);mWand.init(“VJWand”);
0..1
0..1
0..*
vjPosProxy
vjPosProxy~vjPosProxyupdateDatagetUpdateTimesetTransformsetgetDatagetUnitgetPositionPtrgetTransformtransformDatagetChunkTypeconfiggetProxiedInputDevice
vjPosInterface
vjPosInterfaceoperator->operator*refresh
vjPosition
vjPosition~vjPositionconfigstartSamplingstopSamplingsampleupdateDatagetDeviceNamegetPosDatagetPosUpdateTime
VR Juggler — www.vrjuggler.org
Common Classes: Common Classes: vjPosInterfacevjPosInterface
vjPosInterfacevjPosInterface• Used to get positional information. Used to get positional information.
– Ex. trackers, wand position, head positionEx. trackers, wand position, head position
• Derived from Derived from vjDeviceInterfacevjDeviceInterface• Dereferences to Dereferences to vjPosProxyvjPosProxy
– operator*()operator*(), , operator->()operator->()– Get proxy data with: Get proxy data with: getData()getData()
vjMatrix* wand_pos;vjMatrix* wand_pos;wand_pos = mWand->getData();wand_pos = mWand->getData();
VR Juggler — www.vrjuggler.org
Common Classes: Common Classes: vjDigitalInterfacevjDigitalInterface
vjDigitalInterfacevjDigitalInterface• Used to get digital information (ie. 0 or 1)Used to get digital information (ie. 0 or 1)
– Ex: wand buttonsEx: wand buttons
• getData()getData() returns integer returns integer– States (return value):States (return value):
OFFOFF ONON TOGGLE_ON: Just switched to on stateTOGGLE_ON: Just switched to on state TOGGLE_OFF: Just switched to off stateTOGGLE_OFF: Just switched to off state
VR Juggler — www.vrjuggler.org
Sample Application 1:Sample Application 1:Simple OpenGL ApplicationSimple OpenGL Application
simpleAppsimpleApp
VR Juggler — www.vrjuggler.org
Sample Application 1: simpleAppSample Application 1: simpleApp
Simple OpenGL drawing appSimple OpenGL drawing app• Member functionMember function
– vjApp::init()vjApp::init()– vjGlApp::draw()vjGlApp::draw()
• FilesFiles– simpleApp/simpleApp.hsimpleApp/simpleApp.h, , simpleApp/simpleApp.cppsimpleApp/simpleApp.cpp
+init()+apiInit()+preFrame()+intraFrame()+postFrame()+...()
vjApp
+draw()+contextInit()+contextPreDraw()+...()
vjGlApp
+init()+draw()+contextInit()+...()
simpleApp
VR Juggler — www.vrjuggler.org
class simpleApp: public vjGlApp
{
public:
simpleApp();
virtual void init();
virtual void draw();
public:
vjPosInterface mWand;
vjPosInterface mHead;
vjDigitalInterface mButton0;
vjDigitalInterface mButton1;
};
simpleApp: Data MemberssimpleApp: Data Members
• mWandmWand, , mHeadmHead::– Position interface to positional Position interface to positional
proxyproxy
– Get positionGet position
vjMatrix wand_pos;vjMatrix wand_pos;
wand_pos = *(mWand-wand_pos = *(mWand->getData());>getData());
• mButton0mButton0, , mButton1mButton1– Digital interface to digital proxyDigital interface to digital proxy
if(mButton0->getData())if(mButton0->getData())
cout << “Button Pressed”;cout << “Button Pressed”;
VR Juggler — www.vrjuggler.org
simpleApp: simpleApp: init()init()
• Initialize device Initialize device interfaceinterface
• Device nameDevice name– From configuration fileFrom configuration file– Name of device alias or Name of device alias or
proxyproxy
void simpleApp::init()
{
// Initialize devices
mWand.init(“VJWand”);
mHead.init(“VJHead”);
mButton0.init(“VJButton0”);
mButton1.init(“VJButton1”);
}
VR Juggler — www.vrjuggler.org
void simpleApp::draw()
{
...
// Create box offset matrix
vjMatrix box_offset;
box_offset.makeXYZEuler(-90,0,0);
box_offset.setTrans(0.0,1.0f,0.0f);
...
glPushMatrix();
// Push on offset
glMultMatrixf(box_offset.getFloatPtr());
...
drawCube();
glPopMatrix();
...
}
simpleApp: simpleApp: draw()draw()
• Create an offset Create an offset matrixmatrix
• Draw cubeDraw cube
VR Juggler — www.vrjuggler.org
Sample Application 2:Sample Application 2:OpenGL Application with Context-OpenGL Application with Context-
Specific DataSpecific Data
contextAppcontextApp
VR Juggler — www.vrjuggler.org
Context-Specific DataContext-Specific Data
What is a Context?What is a Context?• OpenGL Window OpenGL Window Context for OGL state Context for OGL state
machinemachine
What is context-specific data?What is context-specific data?• Display lists, texture objects, etc.Display lists, texture objects, etc.
Why do you need it?Why do you need it?• VR Juggler uses a single memory pool for all VR Juggler uses a single memory pool for all
threadsthreads– All threads have access to the same variablesAll threads have access to the same variables
• Ex: Multi-wall systemEx: Multi-wall system
VR Juggler — www.vrjuggler.org
Context-Specific DataContext-Specific Data
How does it workHow does it work• Template-based “smart pointer” classTemplate-based “smart pointer” class• Dereference like normal pointerDereference like normal pointer
– ie. operator*(), operator->()ie. operator*(), operator->()
vjGlContextData<GLuint> myDispList;vjGlContextData<GLuint> myDispList;……(* myDispList) = glGenList(1);(* myDispList) = glGenList(1);……glCallList(*myDispList);glCallList(*myDispList);
VR Juggler — www.vrjuggler.org
Class contextApp: public vjGlApp
{
public:
contextApp();
virtual void init();
virtual void contextInit();
virtual void draw();
…
public:
// Identifier for the cube display list
vjGlContextData<Gluint> mCubeDlId;
…
};
Context App: Data MembersContext App: Data Members
• Context-specific Context-specific data for a display data for a display list that draws a list that draws a cubecube
VR Juggler — www.vrjuggler.org
Context App: Context App: contextInit()contextInit()
• Create display listCreate display list• Context-specific Context-specific
version is usedversion is used
void simpleApp::contextInit()
{
// Allocate context specific data
(*mCubeDlId) = glGenLists(1);
glNewList((*mCubeDlId), GL_COMPILE);
glScalef(0.50f, 0.50f, 0.50f);
drawCube();
glEndList();
...
}
VR Juggler — www.vrjuggler.org
Context App: Context App: draw()draw()
• Render display listRender display list• De-reference De-reference
context-specific context-specific display list IDdisplay list ID
void simpleApp::draw()
{
// Get Wand matrix
vjMatrix wand_matrix;
wand_mat = *(mWand->getData());
...
glPushMatrix();
glPushMatrix();
glMultMatrixf(wand_mat.getFloatPtr());
glCallList(*mCubeDlId);
glPopMatrix();
...
glPopMatrix();
}
VR Juggler — www.vrjuggler.org
ConclusionConclusion
Questions?Questions?