0

We did an openvr java binding using jna and it's true what they usually say about jna, it's quite easy to implement.

On the contrary, it has some performance penalties. Googling around and reading some papers, jna is from 10 to almost 80 times slower than jni (here and here).

This wouldn't be a problem for not-critical performance scenarios, but we run into some performance issues and we are trying to addresses all the causes, such as the binding for example.

I searched for some time and there are a lot of different ways to achieve this, but given the header we'd like to port is relatively easy (last famous words..) we are trying to do it manually.

I started by the two most important calls, VR_Init and VR_ShutDown:

inline IVRSystem *VR_Init( EVRInitError *peError, EVRApplicationType eApplicationType )
{
    IVRSystem *pVRSystem = nullptr;

    EVRInitError eError;
    VRToken() = VR_InitInternal( &eError, eApplicationType );
    COpenVRContext &ctx = OpenVRInternal_ModuleContext();
    ctx.Clear();

    if ( eError == VRInitError_None )
    {
        if ( VR_IsInterfaceVersionValid( IVRSystem_Version ) )
        {
            pVRSystem = VRSystem();
        }
        else
        {
            VR_ShutdownInternal();
            eError = VRInitError_Init_InterfaceNotFound;
        }
    }

    if ( peError )
        *peError = eError;
    return pVRSystem;
}

/** unloads vrclient.dll. Any interface pointers from the interface are
* invalid after this point */
inline void VR_Shutdown()
{
    VR_ShutdownInternal();
}

The corresponding java class is pretty simple:

public class HelloVr {

    static {
        System.loadLibrary("openvr_api");
    }

    static final int VRInitError_None = 0, VRApplication_Scene = 1;

    public native IVRSystem VR_Init(ByteBuffer peError, int eApplicationType);

    public native void VR_Shutdown();

    public static void main(String[] args) {
        new HelloVr();
    }

    public HelloVr() {

        ByteBuffer peError = ByteBuffer.allocateDirect(Integer.BYTES).order(ByteOrder.nativeOrder());

        IVRSystem hmd = VR_Init(peError, VRApplication_Scene);

        System.out.println("error: " + peError.getInt(0));
    }

    class IVRSystem {

        private long nativePtr = 0L;
    }
}

Now is time to compile HelloVr.java into HelloVr.class by typing

javac HelloVr.java

But I get Unexpected Token:

PS C:\Users\GBarbieri\Documents\NetBeansProjects\Test\Test\src\test> "C:\Program Files\Java\jdk1.8.0_102\bin\javac.exe"
.\HelloVr.java
Unerwartetes Token ".\HelloVr.java" im Ausdruck oder in der Anweisung.
Bei Zeile:1 Zeichen:66
+ "C:\Program Files\Java\jdk1.8.0_102\bin\javac.exe" .\HelloVr.java <<<<
    + CategoryInfo          : ParserError: (.\HelloVr.java:String) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnexpectedToken

why?

Community
  • 1
  • 1
elect
  • 6,765
  • 10
  • 53
  • 119

1 Answers1

0

Not exactly the ideal answer I was looking for, but it made it working.

I added the javac.exe directly to the PATH environment variable and simply run:

javac HelloVr.java
elect
  • 6,765
  • 10
  • 53
  • 119