240-571 j2me: m3g/11 intro to j2me. prog. v objectives: –to introduce m3g; –to start talking...
TRANSCRIPT
240-571 J2ME: M3G/1 1
Intro to J2ME. Prog.Intro to J2ME. Prog.
ObjectiveObjectives:s:– to to introduce M3G;introduce M3G;– to start talking about "M3G Chapter 2. An Animated Model"to start talking about "M3G Chapter 2. An Animated Model"
leave the floor, penguin, and animation details until next timeleave the floor, penguin, and animation details until next time
240-571, Semester 2, 2006-2007
M3G. Part 1
240-571 J2ME: M3G/1 2
1. Features1. Features M3G: the Mobile 3D Graphics APIM3G: the Mobile 3D Graphics API
– developed as JSR-184developed as JSR-184– present in WTK 2.2 and laterpresent in WTK 2.2 and later
– a combination of high-level and low-level featuresa combination of high-level and low-level features retained and immediate modesretained and immediate modes
– combined with J2ME via the Canvas or combined with J2ME via the Canvas or GameCanvas classesGameCanvas classes
240-571 J2ME: M3G/1 3
No callbacksNo callbacks No separate rendering threadNo separate rendering thread
– so you must code your own animation loop so you must code your own animation loop using a timer or a threadusing a timer or a thread
Requires CLDC 1.1. for floatsRequires CLDC 1.1. for floats– make sure to select it in the WTKmake sure to select it in the WTK
240-571 J2ME: M3G/1 4
Two ModesTwo Modes Retained Mode (high-level API)Retained Mode (high-level API)
– build a 3D scene by building a scene graphbuild a 3D scene by building a scene graph– the scene graph is rendered automaticallythe scene graph is rendered automatically– similar to Java 3D, but a much smaller APIsimilar to Java 3D, but a much smaller API
and a few extrasand a few extras
Immediate Mode (low-level API)Immediate Mode (low-level API)– based on OpenGL ESbased on OpenGL ES– no scene graph data structureno scene graph data structure
240-571 J2ME: M3G/1 5
Scene Graph ExampleScene Graph Example
World
Group
Mesh
Mesh Sprite
Group
Camera Light Light
a World objectis the top node
240-571 J2ME: M3G/1 6
Mesh: a 3D model Mesh: a 3D model – subclasses: morphing mesh, skinned meshsubclasses: morphing mesh, skinned mesh
Sprite: a 2D imageSprite: a 2D image A Group is a useful way of grouping objects so A Group is a useful way of grouping objects so
they can be transformed with a single operation.they can be transformed with a single operation. Typical transformations:Typical transformations:
– scaling, rotation, translationscaling, rotation, translation– animation based on key framesanimation based on key frames
240-571 J2ME: M3G/1 7
Mesh DetailsMesh Details
VertexBuffer
IndexBuffer
Appearance
composedof 1 or more
1 or more
VertexBufferpositions
VertexArray
normalsVertexArray
coloursVertexArray
composedof 0 or 1
0 or 1
tex. coords.VertexArray 0 or more
Appearance
Material
PolygonMode
CompositingMode
composedof
Fog
Texture2D Image2D
1 or more
Mesh
240-571 J2ME: M3G/1 8
2. WTK 2.2 Examples2. WTK 2.2 Examples
Life3D– the Game of Life in 3D
PogoRoo– a kangaroo bouncing on a pogo stick
retainedmode– animates a skateboarder model
a M3D filea M3D file
240-571 J2ME: M3G/1 9
Hello WorldHello World
public class Test extends MIDlet { private MyCanvas c = new MyCanvas();
protected void startApp() { Display.getDisplay(this).setCurrent(c); }
protected void pauseApp() {} protected void destroyApp() {}}
240-571 J2ME: M3G/1 10
public class MyCanvas extends Canvas { private Graphics3D iG3D; // for rendering private World scene; // for the scene graph
public MyCanvas() { iG3D = Graphics3D.create(); scene = (World) Loader.load(”/w.m3d”)[0]; }
protected void paint(Graphics g) { iG3D.bindTarget(g); iG3D.render( scene ); iG3D.releaseTarget(); // flush }}
240-571 J2ME: M3G/1 11
Animated WorldAnimated World
public class Test extends MIDlet { MyCanvas c = new MyCanvas(); MyTimer updater = new MyTimer(); . . .
private class MyTimer extends TimerTask { public MyTimer() { new Timer().schedule(this,0,40); } // 40ms
public void run() { c.repaint(); } }}
240-571 J2ME: M3G/1 12
public class MyCanvas extends Canvas { int time = 0; . . .
protected void paint(Graphics g) { iG3D.bindTarget(g); scene.animate(time += 40); // 25 fps iG3D.render( scene ); iG3D.releaseTarget(); }}
240-571 J2ME: M3G/1 13
3. M3G Chapter 2. An Animated Model3. M3G Chapter 2. An Animated Model
Make a penguin walk in circlesMake a penguin walk in circleshttp://fivedots.coe.psu.ac.th/~ad/jg/m3g2/
240-571 J2ME: M3G/1 14
3.1. Features3.1. Features
Uses retained mode.Uses retained mode. The scene includes a single directional light, The scene includes a single directional light,
a textured floor, a light blue backgrounda textured floor, a light blue background– or an image backgroundor an image background
Mixes M3G rendering and MIDP's Mixes M3G rendering and MIDP's drawString()drawString()
Penguin model is an animated MeshPenguin model is an animated Mesh– it translates and rotatesit translates and rotates
240-571 J2ME: M3G/1 15
AnimM3G Class DiagramsAnimM3G Class Diagrams
MIDlet
Canvas
CommandListener
TimerTask
240-571 J2ME: M3G/1 16
Scene GraphScene Graph
Worldscene
LightBackground Camera
Mesh
floorMesh
Group
built by theFloor class
Mesh model
transRotGroup
animated
built by the AnimModel class
scene graphchildren
240-571 J2ME: M3G/1 17
3.2. AnimCanvas Constructor3.2. AnimCanvas Constructor
private World scene; // global variable
public AnimCanvas(...) { // ... other code scene = new World(); buildScene();
// ... other code }
240-571 J2ME: M3G/1 18
private void buildScene() // add nodes to the scene graph { addCamera(); addLight(); addBackground();
animModel = new AnimModel(); scene.addChild( animModel.getModelGroup() ); // add the model
addFloor(); } // end of buildScene()
240-571 J2ME: M3G/1 19
3.3. Adding the Camera3.3. Adding the Camera
private void addCamera() { Camera cam = new Camera(); float aspectRatio = ((float) getWidth()) / ((float) getHeight()); cam.setPerspective(70.0f, aspectRatio, 0.1f, 50.0f);
cam.setTranslation(0.0f, 0.5f, 2.0f); // up and back // cam.setOrientation(-10.0f, 1.0f, 0, 0); // angle downwards slightly
scene.addChild(cam); scene.setActiveCamera(cam); }
240-571 J2ME: M3G/1 20
AnimM3G Viewed from AboveAnimM3G Viewed from Above
cam.setTranslation(0.0f, 5.0f, 0.0f); cam.setOrientation(-90.0f, 1.0f, 0, 0);
240-571 J2ME: M3G/1 21
3.4. Adding a Light3.4. Adding a Light
private void addLight() { Light light = new Light(); // default white, directional light
light.setIntensity(1.25f); // make it a bit brighter
light.setOrientation(-45.0f, 1.0f, 0, 0); // down and into scene
scene.addChild(light); }
240-571 J2ME: M3G/1 22
3.5. Adding a Background3.5. Adding a Background
private void addBackground() { Background backGnd = new Background(); backGnd.setColor(0x00bffe); // a light blue background
scene.setBackground(backGnd); }
240-571 J2ME: M3G/1 24
A Background ImageA Background Image private void addBackground()
{ Background backGnd = new Background(); Image2D backIm = loadImage("/clouds.gif"); // cloudy blue sky
if (backIm != null) { backGnd.setImage(backIm); backGnd.setImageMode(Background.REPEAT, Background.REPEAT); } else backGnd.setColor(0x00bffe); // a light blue background
scene.setBackground(backGnd); }
240-571 J2ME: M3G/1 25
private Image2D loadImage(String fn) { Image2D im = null; try { im = (Image2D) Loader.load(fn)[0]; } catch (Exception e) { System.out.println( "Cannot make image from " + fn); } return im; } // end of loadImage()
240-571 J2ME: M3G/1 26
3.6. Adding the Floor3.6. Adding the Floor
private void addFloor() { Image2D floorIm = loadImage("/bigGrid.gif"); // large, so slow to load Floor f = new Floor( floorIm, 8); //8 by 8 sz
// Image2D floorIm = loadImage("/grass.gif"); // or try "/floor.png" // Floor f = new Floor( floorIm, 6);// 6 by 6
scene.addChild( f.getFloorMesh() ); }
240-571 J2ME: M3G/1 28
3.7. Adding the Penguin3.7. Adding the Penguin // global for translating and rotating the model
private Group transRotGroup;
public AnimModel() { // other code ...
Mesh model = makeModel();
// reposition the model's start position and size model.setTranslation(0.25f, 0.25f, 0.25f); // so at center model.scale(0.5f, 0.5f, 0.5f);
// translation/rotation group for the model transRotGroup = new Group(); transRotGroup.addChild(model);
// other code ... }
240-571 J2ME: M3G/1 29
Changing the Penguin's PositionChanging the Penguin's Position
Mesh model = makeModel();
// reposition the model's start position and size model.setTranslation(0.25f, 0.25f, 0.25f); // so at center model.scale(0.5f, 0.5f, 0.5f);
240-571 J2ME: M3G/1 30
3.8. Updating the Application3.8. Updating the Application
timer
run(){ animCanvas.update(); }
AnimTimer (in AnimM3G)
update(){ // increment world time // call animate() on world // call repaint()}
AnimCanvas
paint(){ // render the 3D scene // draw 2D info. string}
AnimCanvas
call run() every PERIOD ms
update the canvas
KVM repaint request
240-571 J2ME: M3G/1 31
AnimCanvasAnimCanvas // global timing information
private int appTime = 0; private int nextTimeToAnimate;
public AnimCanvas(AnimM3G top) { // other code... // start the animation nextTimeToAnimate = scene.animate(appTime); }
public void update() // called by TimerTask every PERIOD (50) ms { appTime++; if (appTime >= nextTimeToAnimate) { nextTimeToAnimate = scene.animate(appTime) + appTime; repaint(); } }
240-571 J2ME: M3G/1 32
Rendering the SceneRendering the Scene private Graphics3D iG3D; // global
public AnimCanvas(AnimM3G top) { // other code... iG3D = Graphics3D.getInstance(); }
protected void paint(Graphics g) { iG3D.bindTarget(g); try { iG3D.render(scene); } catch(Exception e) { e.printStackTrace(); } finally { iG3D.releaseTarget(); } // show the model's coordinates in MIDP g.drawString( animModel.getPosition(), 5,5, Graphics.TOP|Graphics.LEFT); }
safer coding style