www.jpct.net

jPCT - a 3d engine for Java => Support => Topic started by: tom3001 on September 16, 2009, 03:58:46 PM

Title: How to create a simple skybox horizon?
Post by: tom3001 on September 16, 2009, 03:58:46 PM
Hi.

What I'm trying to do is to create a simple horizon, as seen in old flightsim games. In fact just a monocolored blue sky and a green earth. I'd like to realize this by a second world called "horizonworld". That world actually contains TWO domes, one for the sky, and the other one for earth. I tried to modify the "AdvancedExample" at the jpct tutorial page, but I didn't succeed.

Can you please help me, or make a suggestion for a different/simpler approach? Thanks.
Title: Re: How to create a simple skybox horizon?
Post by: Melssj5 on September 16, 2009, 04:37:29 PM
Well, having another word just for rendering the horizon would work. you just have to call the rendering methods to have the framebuffer filled with that information, and then render the other world without clearing the framebuffer.


You can also have a cube with a texture like the horizon, and a secundary camera inside that cube, render that secundary camera into the frameBuffer and then render your game without clearing the framebuffer.


Title: Re: How to create a simple skybox horizon?
Post by: tom3001 on September 16, 2009, 07:26:59 PM
Ok, I tried it, but the behaviour of the domes is somewhat strange. You have to look up and down to the see sky or the horizon...
Here is my source code. You can look around with arrow keys, and alter the Z-Angle with Numblock + and -.

The *.3ds dome-files are here:
sky.3ds : http://www.box.net/shared/o5xuh2g1m8
earth.3ds : http://www.box.net/shared/ilymqjk1mm

What am I doing wrong?  ???


import com.threed.jpct.*;
import javax.swing.*;

import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class HorizonTest implements KeyListener {

private static float PI = (float) Math.PI;

private World world = null;
private World horizon = null;
private FrameBuffer buffer = null;
private Object3D box = null;
private Object3D earthdome = null;
private Object3D skydome = null;
private JFrame frame = null;

public static void main(String[] args) throws Exception {
new HorizonTest().loop();
}

public HorizonTest() throws Exception {

// Setup the frame
frame = new JFrame("Horizon Test");
frame.setSize(800, 600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
frame.addKeyListener(this);

// Set up the worlds
world = new World();
horizon = new World();
world.setAmbientLight(127, 127, 127);
horizon.setAmbientLight(255, 255, 255);

// Define textures
TextureManager.getInstance().addTexture("earth", new Texture(16,16,new Color(0,170,0)));
TextureManager.getInstance().addTexture("sky", new Texture(16,16,new Color(85,255,255)));

// Some box at the origin
box = Primitives.getBox(10f, 1f);
box.translate(0, 0.5f, 0); // Place it on the ground
world.addObject(box);

// Prepare the Earthdome
earthdome = Object3D.mergeAll(Loader.load3DS("earth.3ds", 2));
earthdome.build();
earthdome.rotateX(-PI / 2f);
earthdome.setTexture("earth");
earthdome.calcTextureWrap();
tileTexture(earthdome, 3);
earthdome.translate(box.getTransformedCenter().calcSub(earthdome.getTransformedCenter()));
earthdome.setLighting(Object3D.LIGHTING_NO_LIGHTS);

// Prepare the Skydome
skydome = Object3D.mergeAll(Loader.load3DS("sky.3ds", 2));
skydome.build();
skydome.rotateX(-PI / 2f);
skydome.setTexture("sky");
skydome.calcTextureWrap();
tileTexture(skydome, 3);
skydome.translate(box.getTransformedCenter().calcSub(skydome.getTransformedCenter()));
skydome.setLighting(Object3D.LIGHTING_NO_LIGHTS);

// Build
horizon.addObject(earthdome);
horizon.addObject(skydome);

world.buildAllObjects();

earthdome.compileAndStrip();
skydome.compileAndStrip();

// View
Camera cam = world.getCamera();
cam.setPosition(0,0,-150);
cam.lookAt(new SimpleVector(0,0,0));
cam.setFOV(1.5f);
}

private void loop() throws Exception {
buffer = new FrameBuffer(800, 600, FrameBuffer.SAMPLINGMODE_NORMAL);

while (frame.isShowing()) {

// Update the camera
horizon.getCamera().setBack(world.getCamera().getBack().cloneMatrix());

buffer.clear();
horizon.renderScene(buffer);
horizon.draw(buffer);
world.renderScene(buffer);
world.draw(buffer);
buffer.update();
buffer.display(frame.getGraphics(),0,0);
Thread.sleep(10);
}

buffer.disableRenderer(IRenderer.RENDERER_OPENGL);
buffer.dispose();
frame.dispose();
System.exit(0);
}

public void keyPressed(KeyEvent e) {

int keyCode = e.getKeyCode();

//System.out.println("key code : " + keyCode);

if (keyCode == 37) { // left arrow
world.getCamera().rotateCameraY(-0.05f);
}
else if (keyCode == 38) { // up arrow
world.getCamera().rotateCameraX(-0.05f);
}
else if (keyCode == 39) { // right arrow
world.getCamera().rotateCameraY(0.05f);
}
else if (keyCode == 40) { // down arrow
world.getCamera().rotateCameraX(0.05f);
}
else if (keyCode == 109) { // numblock "-"
world.getCamera().rotateCameraZ(-0.05f);
}
else if (keyCode == 107) { // numblock "+"
world.getCamera().rotateCameraZ(0.05f);
}
}

public void keyReleased(KeyEvent e) {
}

public void keyTyped(KeyEvent e) {
}

private void tileTexture(Object3D obj, float tileFactor) {
PolygonManager pm = obj.getPolygonManager();

int end = pm.getMaxPolygonID();
for (int i = 0; i < end; i++) {
SimpleVector uv0 = pm.getTextureUV(i, 0);
SimpleVector uv1 = pm.getTextureUV(i, 1);
SimpleVector uv2 = pm.getTextureUV(i, 2);

uv0.scalarMul(tileFactor);
uv1.scalarMul(tileFactor);
uv2.scalarMul(tileFactor);

int id = pm.getPolygonTexture(i);

TextureInfo ti = new TextureInfo(id, uv0.x, uv0.y, uv1.x, uv1.y,
uv2.x, uv2.y);
pm.setPolygonTexture(i, ti);
}
}
}
Title: Re: How to create a simple skybox horizon?
Post by: EgonOlsen on September 16, 2009, 11:02:15 PM
That's caused by the far clipping plane being too close for those domes. Try something like

Config.farPlane=10000;

right at the beginning of your code and it should look better.
Title: Re: How to create a simple skybox horizon?
Post by: tom3001 on September 17, 2009, 02:06:54 AM
Thank you, it's working now!