Integrating native OpenGL middleware

Apologies in advance that I’ve copied this from where I’d mistakenly posted it originally (there was no “move post” function).

I’ve built a JNI library for Sundog’s Triton ocean simulation middleware and successfully rendered an animated ocean in my JME3 world, but the integration is imperfect: any of my JME geometry lies below the visual horizon is not being rendered (that is, the ship I am standing on is only visible in those portions that are higher above the water than me are displayed).

To get the ocean to render, I added a call to SimpleApplication.simpleRender that calls the various native functions required by Triton (code fragment below).


    private static SWIGTYPE_p_double mat0 = TritonEnvironment.new_double_array(16); // native Matrix4f
    private static SWIGTYPE_p_double mat1 = TritonEnvironment.new_double_array(16); // ditto

    private static SWIGTYPE_p_double getMatrix(Matrix4f in, SWIGTYPE_p_double mat) {                
        // converts a JME3 Matrix4f into a Triton native one
        int count = 0;
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++) 
                TritonEnvironment.double_array_setitem(mat, count++, in.get(j, i));     // transpose it          
            
        return mat;
    }
    
    public void render() {   // called from within SimpleApp.simpleRender()     
         
        Camera cam;
        
        cam = PlayerClient.getJMECamera(); 
        
        environment.SetCameraMatrix(getMatrix(cam.getViewMatrix(), mat0)); 
        environment.SetProjectionMatrix(getMatrix(cam.getProjectionMatrix(), mat1));
        
        ocean.Draw(GameClock.getSimTime());
    }

I’ve tested enough variations to see that the ocean’s surface is being drawn at the right distance from my camera (e.g., being in the big ship shows wave patterns that appear more distant than when I am standing on the lower deck of the smaller ship).

Is there some easy way I can fix this without altering the native code that produces the ocean modeling?

The video below shows the present state of affairs. The first 9 seconds use my own Java-based ocean, which behaves properly, showing the player standing on a large ship and shows a smaller ship to starboard. Then, it switches to the same scene using Triton’s ocean. The parts of my own ships that are below my eye are not drawn if ocean water would be visible behind them, and the smaller (lower) ship is completely invisible.

[video]http://www.youtube.com/watch?v=lTJSXjYaEMY[/video]

After seeing this video, Triton’s developer offered these impressions:

Are there any means within JME3 (e.g., render buckets, or moving where the call to the render() method above is made) to alter this? Is it possible that I will see better results if I initialize Triton later in the init sequence (it seems to have very little explicit connection to OpenGL at all… it might need to see a fully initialized JME3/OpenGL graphics environment before it is launched).

tone

a) jme does use depth buffer, so should work
b) jme honors depthbuffer, (else it would internally not being able to render anything)

ARe teh waves actually 3d, or are they a cleverly done texture? if so, you could try to just pass the texture object.

The waves are actually 3D. I can show them in wireframe, etc.

I have also built Silver Lining into a JNILIB. It fails to show anything at all.

tone

Latest thought from the developer is this: “If Triton’s working at all, I think the creation is fine. It’s all about the timing of the Ocean::Draw() call I think, relative to JME3’s rendering pipeline. It draws to whatever attached color and depth buffers happen to be in place at that time.”

I’ve been tinkering with it, but I am still in pretty much the same place as before. Has anyone combined JME3 with native code that draws directly onto the OpenGL layer as this one does?

I am presently calling the native code as follows… which means that it follows all the stuff JME3 draws. Is it possible to have it drawn at another time? Would that matter, or only shift the entire sea to another single Z depth?

    // in my SimpleApp-derived app:
    public void simpleRender(RenderManager rm) {                 
        if (TritonOcean3D.singleton != null)
            TritonOcean3D.singleton.render();             
    }

tone

jME is totally not made for this kind of interaction.

Have you tried creating a viewport for it, with a own offscreen buffer?
Then you would only need to merge it with the default jme output using the depthbuffer.

I think no matter what, whatever other OpenGL thing you shell out to would have to recreate its state from scratch in order to be sure it had what it needed (this is likely already true) but then it would have to put it all exactly back the way it found it. This is extremely unlikely to be true.

Otherwise, I think you will hopelessly confuse JME’s state management.

Is there no plausible way to proceed? Could I rework lwjglRenderer to put in hooks to render these objects properly?

tone