Search code examples
javashaderjoglworldwind

Using Custom Shaders in WorldWind Java / JOGL


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?


Solution

  • 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.