Introduction to VR Programming with GeeXLab


How to program the HTC Vive in GeeXLab

GeeXLab 0.14+ comes with a very cool feature: the support of Virtual Reality (or VR for the impatient!) via the use of the OpenVR library. OpenVR functionalities are accessible in Lua and Python via the OpenVR plugin of GeeXLab (plugin_gxc_openvr_x32.dll or plugin_gxc_openvr_x64.dll on Windows platforms). Currently only Windows platforms are supported, but I can build the Linux 64-bit version if necessary (and I will certainly build it in the future). I tested the OpenVR plugin with the HTC Vive headset. I don’t know if it will work with the Oculus Rift but according to what I read on the Net, it should work.

Virtual reality… VR is very cool, especially for a graphics programmer. Why? Because for the first time, the graphics programmer can visit the 3D world that he’s programming. Even the simplest 3D object, the triangle, is an amazing spectacle the first time you see it through the VR headset. The RGB triangle (RGB because it’s nicer) is there, in front of you, and you can walk around it, you can almost touch it… like it was really there. You are in the matrix!

Here’s the hello world of VR programming: the RGB triangle:


VR demo in GeeXLab

 
and just for fun, here is a close-up of the right eye of the HTC Vive headset:


VR demo in GeeXLab

 
Programming VR in GeeXLab is quite simple. Basically, you need for each eye:
– one perspective camera
– one render target

You also need functions of the gh_vr library that is available in Lua and Python.

The size of the render target for each eye can be get with gh_vr.get_recommended_render_target_size(). For the HTC Vive, the size of a render target is 1512×1680 pixels.

Here are the 4 steps to render a scene in VR:
1/ update the left and right cameras with gh_vr.update_cameras()
2/ render the world from the point of view of the left camera into the render target of the left eye.
3/ render the world from the point of view of the right camera into the render target of the right eye.
4/ send both render targets to the HMD (Head Mounted Display) using gh_vr.submit().

The principle is simple. The practice with GeeXLab too. Here is the INIT code (Lua) for the RGB triangle demo:

---------------------------------
-- Create 2 render targets
--
vr_rt_w, vr_rt_h = gh_vr.get_recommended_render_target_size()    
rt_left_eye = gh_render_target.create(vr_rt_w, vr_rt_h)
rt_right_eye = gh_render_target.create(vr_rt_w, vr_rt_h)


---------------------------------
-- Create 2 cameras
--
aspect = vr_rt_w / vr_rt_h
camera_left_eye = gh_camera.create_persp(60, aspect, 0.1, 100.0)
Camera_right_eye = gh_camera.create_persp(60, aspect, 0.1, 100.0)


---------------------------------
-- Create a triangle and a ground plane
--
triangle = gh_mesh.create_triangle()
ground = gh_mesh.create_plane(10, 10, 20, 20)

 
Now the FRAME script, still in Lua:

---------------------------------
-- Update left and right cameras
--
gh_vr.update_cameras(camera_left_eye, camera_right_eye)



---------------------------------
-- Render the world (triangle and ground plane) for the left eye.
--
gh_render_target.bind(rt_left_eye)
  
gh_camera.bind(camera_left_eye)
gh_renderer.clear_color_depth_buffers(0.0, 0.0, 0.0, 1.0, 1.0)

gh_gpu_program.bind(vertex_color_prog)

gh_renderer.wireframe()
gh_object.render(ground)
gh_renderer.solid()

gh_object.set_euler_angles(triangle, 0, 0, 0)
gh_object.set_position(triangle, 0, 0.5, -1.0)
gh_object.render(triangle)

gh_render_target.unbind(rt_left_eye)



---------------------------------
-- Render the world for the right eye.
--
gh_render_target.bind(rt_right_eye)
  
gh_camera.bind(camera_right_eye)
gh_renderer.clear_color_depth_buffers(0.0, 0.0, 0.0, 1.0, 1.0)

gh_gpu_program.bind(vertex_color_prog)

gh_renderer.wireframe()
gh_object.render(ground)
gh_renderer.solid()

gh_object.set_euler_angles(triangle, 0, 0, 0)
gh_object.set_position(triangle, 0, 0.5, -1.0)
gh_object.render(triangle)

gh_render_target.unbind(rt_right_eye)



---------------------------------
-- Send render target to the HMD
--
gh_vr.submit(rt_left_eye, rt_right_eye)
  

 
I put in bold the functions of the OpenVR plugin. Very limited.

The RGB triangle demo can be found in the gl-32/vr/demo01/ folder of the code sample pack.

Leave a Comment

Your email address will not be published. Required fields are marked *