这里涉及到了三种不同的贴图:
这里的天空,通常由贴图实现,实际上算是一种巧妙的障眼法。
1.球体贴图:将一个理想高反射的球体置于场景中央,从一个角度无穷远处拍摄此球体,将得到一张全景图。
2.立方体贴图:把摄像机置于场景中央,朝着x,-x,y,-y,z,-z方向将场景渲染出6张纹理。然后用6张纹理组成一个立方体的 6个面。这样一个真正的全景图组成了。
3.等距矩形贴图:又称球面投影、方格投影、等距柱状投影等。假想球面与圆筒面相切于赤道,赤道为没有变形的线。经纬线网格,同一般正轴圆柱投影,经纬线投影成两组相互垂直的平行直线。
public class a extends SimpleApplication implements ActionListener {
Spatial sky1;
Spatial sky2;
Spatial sky3;
Spatial sky4;
Spatial sky5;
Spatial sky6;
Spatial sky7;
int current = -1;
Spatial[] skies;
@Override
public void simpleInitApp() {
// 天空盒
Texture west = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_west.jpg");
Texture east = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_east.jpg");
Texture north = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_north.jpg");
Texture south = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_south.jpg");
Texture up = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_up.jpg");
Texture down = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_down.jpg");
sky1 = SkyFactory.createSky(assetManager, west, east, north, south, up, down);
// 天空盒
sky2 = SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", SkyFactory.EnvMapType.CubeMap);
// 天球,
sky3 = SkyFactory.createSky(assetManager, assetManager.loadTexture("Textures/Sky/St Peters/StPeters.hdr"),
new Vector3f(1, -1, 1), // 图片上下颠倒,故改变Y方向的法线
SkyFactory.EnvMapType.SphereMap);
// 天球
sky4 = SkyFactory.createSky(assetManager, "Textures/Sky/SkySphereMap.jpg", SkyFactory.EnvMapType.SphereMap);
// 天球
sky5 = SkyFactory.createSky(assetManager, "Textures/Sky/SkyEquirectMap.jpg", SkyFactory.EnvMapType.EquirectMap);
// 地球
sky6 = SkyFactory.createSky(assetManager, "Textures/Sky/earth.jpg", SkyFactory.EnvMapType.EquirectMap);
// 天球,
sky7 = SkyFactory.createSky(assetManager, "Textures/Sky/Path.hdr", SkyFactory.EnvMapType.EquirectMap);
skies = new Spatial[]{sky1, sky2, sky3, sky4, sky5, sky6, sky7};
setCurrentSky(0);
inputManager.addMapping("NEXT", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addMapping("BACK", new KeyTrigger(KeyInput.KEY_BACK));
inputManager.addListener(this, "BACK", "NEXT");
}
@Override
public void onAction(String name, boolean isPressed, float tpf) {
if (isPressed) {
if ("NEXT".equals(name)) {
if (current < skies.length-1)
setCurrentSky(current+1);
else
setCurrentSky(0);
} else if ("BACK".equals(name)){
if (current > 0)
setCurrentSky(current-1);
else
setCurrentSky(skies.length-1);
}
}
}
/**
* 设置当前天空
* @param index
*/
private void setCurrentSky(int index) {
if (current >= 0) {
skies[current].removeFromParent();
}
current = index;
rootNode.attachChild(skies[current]);
}
public static void main(String[] args) {
a app = new a();
app.start();
}
}