FreeVR Library Programming Tutorial (w/ OpenGL)

The FreeVR Library will be used to exemplify many VR interface and programming techniques. FreeVR will work in most local VR facilities (eg. CAVE™ or Head-Based-Display), as well as on the available desktop machines in a simulated-VR mode. It can be used on PC's with Linux and OpenGL installed, or in a (currently very) limited way on PC's with Cygwin installed.

The FreeVR webpage is www.freevr.org.

This tutorial takes the approach of starting with an extremely simple initial example and then advancing in very small increments (baby steps) until we can perform some interesting tasks in virtual reality. Another point to make about this tutorial is that it is not intended as a means to learn advanced OpenGL programing. The computer graphics in these examples are all very simple. The goal of the tutorial is to highlight programming tasks that are unique to programming for a virtual reality system.

On the other hand, some basic OpenGL techniques can be learned by following this tutorial, as it will show how to handle texture maps, billboards, cutting planes, and moveable lights.

Other tutorials are under development for interfacing FreeVR to additional rendering and world simulation systems. Presently there is a tutorial available for the SGI Performer scene-graph library, but as Performer has greatly decreased in usage new tutorials will cover similar, but more popular libraries.

This tutorial has been most recently tested with FreeVR version 0.6a.








Components of a VR system

The FreeVR integration library — a crucial component of a VR system

Features of a typical VR-integration library



Example 0: A simple virtual world — in Xwindows (ex0)

 



Basic structure of FreeVR Library application

The FreeVR Library runs many tasks in parallel. This helps reduce tracker lag, as well as maintain better frame rates.

Function callbacks are used to inform the library how to render, etc. Shared memory is used by the library to maintain consistency across processes, and by the application to pass data from the simulation to the rendering.



Example 1: The bare essentials FreeVR application (ex1)

 


Example 2: A more civilized FreeVR application (ex2)



Example 3: A world with some action (ex3)

The two objects of the simple virtual world are now dynamic. They move over a simple path. One new (static) object has been added to the world. The user still cannot interact with the world other than moving to view it from another perspective.



Aside: Simulating VR on the Desktop

Frequently, the availability of a virtual reality facility might be limited. This might be the result of high usage of the facility, or for some developers, the facility might be located at a distance that precludes frequent visits. In any case, there is a general need for developers of VR applications to be able to do some amount of testing at their desktop, on systems that do not have the input or output capabilities of a true VR display. Therefore most VR integration libraries include the ability to simulate running VR applications with more mundane interfaces.

Aside: FreeVR naming conventions

To facilitate the writing and interpretation of FreeVR application code, the FreeVR library adheres to a set of naming conventions. The conventions are:




Aside: FreeVR complex types

FreeVR provides a small set of type definitions for operations on mathematical types that contain more than a single scalar value. In most cases, the internal data representation is a single dimensional array of values.

The types are:

The types vrPoint and vrVector have identical internal representations. Therefore they can be easily converted through a simple type-cast. However, mathematically points and vectors are different, therefore it is strongly advised that the appropriate type be used for any given circumstance.
NOTE: one can think of points and vectors as actually being 4 element arrays, with the fourth element of a point being '1' and the fourth element of a vector being '0'.

The use of the vrEuler type is strongly discouraged. There are two occasions in which vrEuler is not discouraged:

For functions returning values as a complex type, the first argument is always a pointer to the location into which the result will be copied. The function then returns a copy of that pointer as the return value. The reason for doing this is to eliminate the need for the library to continually allocate and deallocate memory when performing these operations. By returning a copy of the pointer as the return value, it is possible to nest operations.




Aside: FreeVR inputs

Having the ability to render worlds that provide the proper perspective for a VR user is a good start to creating a virtual reality experience. But a world in which all the user can do is move their head about to see from different perspectives can become boring rather quickly. Therefore, the next two examples (ex4 & ex5) begin to demonstrate the basic means by which physical inputs from a hand-held controller can affect the virtual world.

Later examples with introduce more complex means of interaction, including direct input interactions, virtual input interactions, as well as a means by which agent input interactions can be accomplished.

There are three types of FreeVR inputs that are most commonly used:

Each type of input can be querried in one of two ways:

Using the "Delta" form of the input queries can be especially useful when determining whether a button was just pressed or just released.

NOTE: In general, input queries should take place only in the simulation routine, and not in any of the rendering routines. The effects of the inputs should then be calculated as part of the simulation, and passed to the rendering routines as part of the state of the world.




Example 4: Very simple inputs — buttons (ex4)

The use of buttons to affect the virtual world is the most basic form of input possible. In this example, buttons 1 and 3 (which frequently correspond to left and right buttons on a VR controller) move the green pyramid up and down by one unit. Button 2 resets the green pyramid back to the center of the working volume.

                  

This type of interaction where the manipulation of a physical input device causes an immediate response to an object in the virtual world is known as the "physical control" input method.

Here is a sample of the new code:

	update_world(WorldDataType *wd)
	{
		...
		if (vrGet2switchDelta(1) == 1)
			wd->obj3_y += 1.0;
		if (vrGet2switchDelta(2) == 1)
			wd->obj3_y =  5.0;
		if (vrGet2switchDelta(3) == 1)
			wd->obj3_y -= 1.0;
		...
	}

NOTE that by using the "Delta" version of the input query we can easily specify that the world database should be altered precisely when a particular button has just been pressed (vs. all the time that it is pressed).

  • There are minor differences between ex3 and ex4.

    Example 5: Very simple inputs — valuators/joysticks (ex5)

    Another typical controller input for virtual reality (as well as other hardware such as game controllers) is the joystick. A joystick is really just two valuators connected to allow one to easily move in both the X and Y directions at the same time.

                      

    NOTES:

  • It is generally a good idea to have a "dead zone" around the zero value due to the nature of physical inputs — often there is no precise zero value so a small positive or negative number will be returned instead. Also, light presses on sensitive joysticks may cause unwanted movement. The JS_EPSILON factor represents the size of the dead zone.

  • This example shows two ways of handling the "dead zone". In the case of the joy_x value, as soon as the X dimension of the joystick moves past the epsilon value, the movement will immediately jump to that value, causing a discontinuity in the movement.

    For the joy_y value, the epsilon value is subtracted from the input (in a sign-neutral way) such that when the input moves slightly outside the epsilon range, it will respond with slight movements reflecting the small delta between the actual value and the epsilon.

  • The previous button inputs (from example 4) are still active, so they too can control the green pyramid, and in particular button 2 will reset the location of the pyramid — though the code changed a bit to reset all three location parameters.

    Example 6: Very simple output — 2D text (ex6)

    Text rendering is often useful as part of the user interface, or for debugging applications. This example introduces a very basic way of adding text into the rendering of the virtual world. It is not the best method for most circumstances, but will serve to get us started.

                      


    Example 7: A virtual pointer & Coordinate Systems (ex7)

                      
     


    Example 8: Objects with behavior & using vectors (ex8)

    Objects that move on their own can make for a more interesting virtual world. In this example, we use the direction the wand is pointing (a 6sensor input) to affect the direction of a small projectile.



    Example 9: Object Selection (ex9)

     


    Example 10: Manipulating the world (ex10)

     


    Example 11: Using Locks to Safeguard the Code (ex11)



    Example 12: Traveling through the world (ex12)

    Another common way to "interact" with a virtual world is to move through it.

     


    Example 13: Agent-style interaction with the world (ex13)



    Example 14: User Interface: Virtual Controls (ex14a-14f)


    The following six examples show how different forms of virtual controls can be implemented and used to control actions within the virtual world.

    These examples are implemented in a very rudimentary fashion, with limits on how they can be positioned in the virtual world.

    These examples now require some additional shapes not included in the simpler version of the shape source code. The new shapes code is in (wrs_shapes.c).



    Example 14a: Virtual Controls: Toggle Button (ex14a)



    Example 14b: Virtual Controls: Slider (ex14b)



    Example 14c: Virtual Controls: Lever (ex14c)



    Example 14d: Virtual Controls: Radio Buttons (ex14d)



    Example 14e: Virtual Controls: Joystick (ex14e)



    Example 14f: Virtual Controls: Push Button (ex14f)



    Example 15: The four methods of manipulation (ex15)

    This example is not yet fully implemented.



    Example 16: 3D text in the world (ex16)



    Example 17: Objects with textured surfaces (ex17)

    Objects with textured surfaces, make for a more interesting looking virtual world.

    Example 18: Objects with billboarded textured surfaces (ex18)

    A common technique in computer graphics to simplify rendering (and thus reduce rendering time), is to use a textured plane that rotates to continually face the viewer — known as a "billboard". Common examples include trees and spheres.

    Example 19: The world in miniature (ex19)

    The World-in-Miniature (WIM) technique is a common virtual world interface tool.

    Example 20: Clipping away part of the world (ex20)

    Using standard OpenGL clipping routines, we can provide a means for the user to see-through part of the world.

    Example 21: Using OpenGL lighting for interactive lights (ex21)

    In addition to manipulating objects in the world, sometimes it is valuable to manipulation other features of the world, such as the lighting parameters. In this case, giving us the effect of holding a flashlight.

    Tutorial Summary:

    This tutorial demonstrates most of the important and unique features of the FreeVR virtual reality integration library. Each function is introduced as part of a small progression toward increasinly more capable demonstration applications. The functions that are not presented here tend to be very similar to ones that are presented, plus many of the mathematical operations which do not need to be fully enumerated.

    The FreeVR webpage includes a functions reference document that fully lists all the functions needed for robust application development.

    Other tutorials are also under development to demonstrate the use of FreeVR with scene-graph and physics libraries. These will become available on the FreeVR tutorials webpage as they reach sufficiently documented states. There is also a FreeVR-Performer tutorial available on the webpage, though that is of limited value since the Performer library is not as widely used as it has been in the past.

    Programming Caveats to Remember:

    As a reminder, there are a handful of things to watch our for when writing virtual reality applications:

    
    
    


    
    
    
    Last modified 10 January 2010.
    Bill Sherman, shermanw@indiana.edu
    
    
    © Copyright William R. Sherman, 2010.
    All rights reserved. In particular, republishing any files associated with this tutorial in whole or in part, in any form (included electronic forms) is prohibited without written consent of the copyright holder. Porting to other rendering systems is also prohibited without written consent of the copyright holder.