Using Custom Shaders in WorldWind Java / JOGL

1.9k views Asked by At

or Creating an IR effect in WorldWind Java

I need to emulate an infrared (IR) view in WorldWind, and I'm not sure about the best way to go about this. I should point out that I do not need to simulate IR (i.e. no heat maps) -- I just need to produce a reasonable facsimile of a black-and-white IR display. I have very limited graphics knowledge and no prior experience with OpenGL, JOGL, or WorldWind.

Based on my research so far, it seems that the best approach is to use a custom shader. However, as far as I can tell, WorldWind provides no high-level shader support.

I found the following relevant threads on a WorldWind forum, but I'm still not sure how to proceed:

To clarify my question(s):

How do I integrate a GLSL shader into a WorldWind application, if that is in fact the best approach? If not, how should I implement this effect?

1

There are 1 answers

0
Aaron Novstrup On BEST ANSWER

This turned out to be fairly straightforward, thanks to the contributions of tve and what_nick in this thread: GLSL Shader support that renders tiles correctly. Specifically, I reused the GLSL class contributed by tve (in shader_support_051308.zip) and modified what_nick's sample code.

I defined a DecoratedLayer class that allows any layer to be "decorated" with a new rendering strategy, then defined a ShadingDecorator that sets up the GLSL shader before delegating to the underlying layer's render method:

public class DecoratedLayer implements Layer {
    private final Layer _layer;
    private final I_LayerDecorator _decorator;

    public DecoratedLayer(Layer layer, I_LayerDecorator decorator) {
        _layer = layer;
        _decorator = decorator;
    }

    @Override
    public void preRender(DrawContext dc) {
       _decorator.preRender(dc, _layer);
    }

    @Override
    public void render(DrawContext dc) {
       _decorator.render(dc, _layer);
    }

    // all other methods delegate to _layer
}

public class ShadingDecorator implements I_LayerDecorator {
    private GLSL glsl;
    private final File vertfile;
    private final File fragfile;

    public ShadingDecorator(final File vertexShaderFile, 
                            final File fragmentShaderFile) {
        vertfile = vertexShaderFile;
        fragfile = fragmentShaderFile;
    }

    @Override
    public void preRender(DrawContext dc, Layer layer) {
        if (glsl == null) {
            glsl = new GLSL(dc.getGL());
            glsl.loadVertexShader(vertfile);
            glsl.loadFragmentShader(fragfile);
        }
        layer.preRender(dc);
    }

    @Override
    public void render(DrawContext dc, Layer layer) {
        if (glsl != null) {
            glsl.useShaders();
            glsl.startShader();
            GL gl = dc.getGL();
            gl.glUniform1i(glsl.getUniformLocation("tile_image"), 0);

            layer.render(dc);

            glsl.endShader();
        }
    }
}

More work is needed to make this fully general, but this should be a reasonable starting point.