Really should have put an 's' on the title of this, since I seem to always have more. :)
Today's topic: Lighting. Or perhaps, models. I can't tell where my problem is. So, I went through a ton of Blender tutorials, and created myself a nice die, with only one face. It's red, with white pips, all smooth and happy.
Then I create a simple BaseGame class intended to do little but show this model. I ripped most of the code from FlagRush2, with the lighting and chase cam code from FlagRush9 (so I can move the camera around). Since these forums show a nice little scroll box when there's a lot of code, I'll just dump the whole thing right here. You can see it's all ripped from FlagRush and the wiki on how to load models.
public class ModelTest extends BaseGame {
private Node scene;
protected Timer timer;
private int width, height, depth, freq;
private boolean fullscreen;
private Camera cam;
private ChaseCamera chaser;
public static void main(String[] args) {
ModelTest app = new ModelTest();
app.setConfigShowMode(ConfigShowMode.ShowIfNoConfig);
app.start();
}
protected void initSystem() {
width = settings.getWidth();
height = settings.getHeight();
depth = settings.getDepth();
freq = settings.getFrequency();
fullscreen = settings.isFullscreen();
try {
display = DisplaySystem.getDisplaySystem(settings.getRenderer());
display.createWindow(width, height, depth, freq, fullscreen);
cam = display.getRenderer().createCamera(width, height);
} catch (JmeException e) {
System.out.println("ERROR: Could not create displaySystem - " + e);
System.exit(1);
}
//set the background to black
display.getRenderer().setBackgroundColor(ColorRGBA.black.clone());
//initialize the camera
cam.setFrustumPerspective(45.0f, (float)width / (float)height, 1, 1000);
Vector3f loc = new Vector3f(0.0f, 0.0f, 25.0f);
Vector3f left = new Vector3f(-1.0f, 0.0f, 0.0f);
Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);
// Move our camera to a correct place and orientation.
cam.setFrame(loc, left, up, dir);
// Signal that we've changed our camera's location/frustum.
cam.update();
// Get a high resolution timer for FPS updates.
timer = Timer.getTimer();
display.getRenderer().setCamera(cam);
KeyBindingManager.getKeyBindingManager().set("exit", KeyInput.KEY_ESCAPE);
}
protected void reinit() {
display.recreateWindow(width, height, depth, freq, fullscreen);
}
protected void initGame() {
scene = new Node("Root Node");
cam.update();
MaxToJme md3tojme = new MaxToJme(); //the converter
Node node = null; //Where to dump mesh.
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream(); //For loading the raw file
// File Path for the model (dump file in toplevel of classpath)
URL url = this.getClass().getResource("die.3ds");
InputStream is=null;
try {
is = url.openStream();
} catch (IOException e) {
e.printStackTrace();
}
// Converts the file into a jme usable file
try {
md3tojme.convert(is, bytearrayoutputstream);
} catch (IOException e) {
e.printStackTrace();
}
// Used to convert the jme usable file to a TriMesh
BinaryImporter binaryImporter = new BinaryImporter();
ByteArrayInputStream in=new ByteArrayInputStream(bytearrayoutputstream.toByteArray());
//importer returns a Loadable, cast to Node
try {
node = (Node)binaryImporter.load(in);
} catch (IOException e) {
e.printStackTrace();
}
node.setModelBound(new BoundingBox());
node.updateModelBound();
//attach node to scene graph
node.updateRenderState();
scene.attachChild(node);
DirectionalLight light = new DirectionalLight();
light.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
light.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, .5f));
light.setDirection(new Vector3f(1,-1,0));
light.setShadowCaster(true);
light.setEnabled(true);
// Attach the light to a lightState and the lightState to rootNode.
LightState lightState = display.getRenderer().createLightState();
lightState.setEnabled(true);
lightState.setGlobalAmbient(new ColorRGBA(.2f, .2f, .2f, 1f));
lightState.attach(light);
scene.setRenderState(lightState);
HashMap<String, Object> props = new HashMap<String, Object>();
props.put(ThirdPersonMouseLook.PROP_MAXROLLOUT, "10");
props.put(ThirdPersonMouseLook.PROP_MINROLLOUT, "3");
props.put(ThirdPersonMouseLook.PROP_MAXASCENT, ""+45 * FastMath.DEG_TO_RAD);
props.put(ChaseCamera.PROP_INITIALSPHERECOORDS, new Vector3f(5, 0, 30 * FastMath.DEG_TO_RAD));
props.put(ChaseCamera.PROP_DAMPINGK, "4");
props.put(ChaseCamera.PROP_SPRINGK, "9");
chaser = new ChaseCamera(cam, node, props);
chaser.setMaxDistance(12);
chaser.setMinDistance(2);
}
protected void update(float interpolation) {
timer.update();
interpolation = timer.getTimePerFrame();
chaser.update(interpolation);
if (KeyBindingManager.getKeyBindingManager().isValidCommand("exit")) {
finished = true;
}
}
protected void render(float interpolation) {
display.getRenderer().clearBuffers();
display.getRenderer().draw(scene);
}
protected void cleanup() {
}
}
What I get on my screen is a completely white die. I can spin it, so the chase cam seems to work, and I can see the beveled edges, so I know it's my model. But I can't see the pips because there are no shadows, and it's certainly not red and white like the Blender render shows.
So I guess I did one (or more) of three things wrong:
A) Didn't properly create the thing in Blender. Maybe I missed something about materials or textures.
B) I didn't properly load the object. There are a million things enable on every jME object. :)
C) I didn't properly light the scene. FlagRush looked great, but... see B, above. :)
I know it's a lot of code, but it should be rote for anybody who does jME a lot, and I'm sure I'm just missing something simple. If you'd like me to attach my die.3ds file, just let me know.
Thanks so much! You guys have been a great help. I picked up jME about a week ago and Blender yesterday, so I've been trying to cram a lot into my brain. You've been instrumental is getting it all to fit. :)