Tuesday, September 04, 2007

My first hack on WWJ

It is not any amazing thing but I want to show my first hack on WWJ code. Really this is the second hack, the first is my LayerSet class that allows create set of layers.

I have modified a bit the WWJ source code (in the SurfaceTileRenderer class) to allow some layers make use of the, until now not used, property opacity.
For example you can put a BMNGSurfaceLayer but you can change its opacity, or better said, you can invoke the setOpacity method but the opacity value is never used in the render process and thus the layer never changes its opacity.

Take a look at this two screenshots. The first is a normal set of layers:


The second shows the CountryBoundariesLayer and the landsat layer with opacity changed:


Which is the secret?
You know some layers like BMNGSurfaceLayer, CountryBoundariesLayer and USGS* are based on BasicTiledImageLayer that extends the TiledImageLayer class. The later class uses the SurfaceTileRenderer to render the tiles.


In
TiledImageLayer.draw() method change:
dc.getGeographicSurfaceTileRenderer().renderTiles(dc, this.currentTiles);
by
dc.getGeographicSurfaceTileRenderer().renderTiles(dc, this.currentTiles, this);

In SurfaceTileRenderer change:
public void renderTiles(DrawContext dc, Iterable tiles) {
by
public void renderTiles(DrawContext dc, Iterable tiles, AbstractLayer layer) {

and put this code (only the later 'if):
...
if (!dc.isPickingMode()) {
gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
} else {
gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_COMBINE);
gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_SRC0_RGB, GL.GL_PREVIOUS);
gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_COMBINE_RGB, GL.GL_REPLACE);
}

if(layer!=null){
// Set transparency
gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE);
gl.glColor4f(1, 1, 1, (float)layer.getOpacity());
}
...

Finally, create overload the method (to not affect other calls):
public void renderTiles(DrawContext dc, Iterable tiles) {
this.renderTiles(dc, tiles, null);
}

And thats all.

3 comments:

Chiss said...

Cool!

I hope this gets integrated in the SDK! Looks like something straightforward enough, but not something I would have found, having zero OpenGL knowledge.. and a limited supply of free time! Thanks for sharing this.

exignoto@alice.it said...

Great!

I'm trying to do a thing like this, but i have a problem.
I want use the Blending function! I have modified the TiledImageRender, putting a simple function of Blending, but nothing append...
do you have any suggest???

Thanx
Michele

Antonio Santiago said...

See the methods 'doRender' and 'draw' TiledImageLayer class. Also see the code and take a look at SurfaceTileRenderer class (renderTiles method).
I'm starting with the WWJ API. Remember you can get better answers from the WWJ forum.