📄 mycanvas.java
字号:
/*************************************************************************
MIDletMain is a demo application that shows the use of various
JSR 184 API calls to generate a 3D scene with animation. This file has
the Canvas that generates a cube using triangle strips. It next paints a
texture map to the cube's faces, and renders this all against a backdrop
image. A rotation transformation is also applied, and as the paint method
gets called periodically, the transformation is reapplied, making the cube
rotate. This example uses immediate mode rendering.
IMPORTANT: This code requires use of the M3G (JSR-184) API to function.
File: MyCanvas.java
Needs: MIDletMain.java
Resources: cubeface.png, backdrop.png
Created by: Tom Thompson
Edited by: Oscar Vivall
COPYRIGHT All rights reserved Sony Ericsson Mobile Communications AB 2004.
The software is the copyrighted work of Sony Ericsson Mobile Communications AB.
The use of the software is subject to the terms of the end-user license
agreement which accompanies or is included with the software. The software is
provided "as is" and Sony Ericsson specifically disclaim any warranty or
condition whatsoever regarding merchantability or fitness for a specific
purpose, title or non-infringement. No warranty of any kind is made in
relation to the condition, suitability, availability, accuracy, reliability,
merchantability and/or non-infringement of the software provided herein.
*************************************************************************/
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.m3g.*;
import javax.microedition.m3g.Camera;
// The custom Canvas that handles all of the 3D rendering
public class MyCanvas extends Canvas {
private Graphics3D iG3D;
private Camera iCamera;
private Light iLight;
private float iAngle = 0.0f; // Starting angle for 3D object
private Transform iTransform = new Transform();
private Background iBackground = new Background();
private VertexBuffer iVb; // Vertex positions, normals, colors, texcoords
private IndexBuffer iIb; // Indices to VertexBuffer, forming tri-strips
private Appearance iAppearance; // Material, texture, compositing, etc.
private Material iMaterial = new Material();
private Image iImage;
private Image2D backDrop; // Holds background image
private Transform transform3D;
// Construct the displayable
public MyCanvas() {
// Set up this Displayable to listen to command events
setCommandListener(new CommandListener() {
public void commandAction(Command c, Displayable d) {
if (c.getCommandType() == Command.EXIT) {
MIDletMain.quitApp(); // exit the MIDlet
} // end if
} // end commandAction()
}); // end of arguments to setCommandListener()
try {
init();
} // end try
catch(Exception e) {
e.printStackTrace();
} // end catch
} // end constructor
// Initialization of all components required to make 3D scene
private void init() throws Exception {
// Add the Exit command
addCommand(new Command("Exit", Command.EXIT, 1));
// Get the singleton Graphics3D instance
iG3D = Graphics3D.getInstance();
// Create a camera
iCamera = new Camera();
iCamera.setPerspective( 80.0f, // field of view
(float)getWidth() / (float)getHeight(), // aspectRatio
1.0f, // near clipping plane
1000.0f ); // far clipping plane
// Create a light
iLight = new Light();
iLight.setColor( 0xffffff ); // White light
iLight.setIntensity(1.25f); // overbright
// init some arrays for our object (cube)
// Each line in this array declaration represents a triangle strip for
// one side of a cube. The only primitive we can draw with is the
// triangle strip so if we want to make a cube with hard edges we
// need to construct one triangle strip per face of the cube.
// 1 * * * * * 0
// * * *
// * * *
// * * *
// 3 * * * * * 2
// The ASCII diagram above represents the vertices in the first line
// (the first tri-strip).
short[] vert = {10, 10, 10, -10, 10, 10, 10,-10, 10, -10,-10, 10, // front
-10, 10,-10, 10, 10,-10, -10,-10,-10, 10,-10,-10, // back
-10, 10, 10, -10, 10,-10, -10,-10, 10, -10,-10,-10, // left
10, 10,-10, 10, 10, 10, 10,-10,-10, 10,-10, 10, // right
10, 10,-10, -10, 10,-10, 10, 10, 10, -10, 10, 10, // top
10,-10, 10, -10,-10, 10, 10,-10,-10, -10,-10,-10 }; // bottom
// Create a VertexArray to hold the vertices for the object
VertexArray vertArray = new VertexArray( vert.length / 3, 3, 2 );
vertArray.set( 0, vert.length/3, vert );
// The per-vertex normals for the cube; these match with the faces
// above. Each normal is perpendicular to the surface of the object at
// the corresponding vertex. These are used in lighting computations.
byte[] norm = {0, 0, 127, 0, 0, 127, 0, 0, 127, 0, 0, 127,
0, 0, -127, 0, 0,-127, 0, 0,-127, 0, 0, -127,
-127, 0, 0, -127, 0, 0, -127, 0, 0, -127, 0, 0,
127, 0, 0, 127, 0, 0, 127, 0, 0, 127, 0, 0,
0, 127, 0, 0, 127, 0, 0, 127, 0, 0, 127, 0,
0, -127, 0, 0, -127, 0, 0, -127, 0, 0, -127, 0};
// Create a vertex array for the normals of the object.
VertexArray normArray = new VertexArray( norm.length / 3, 3, 1 );
normArray.set( 0, norm.length/3, norm );
// Per vertex texture coordinates. These specify the coordinates on a 2-D image
// that will be painted onto a surface. The image is 128 by 128 pixels, but
// we only use a portion of the image.
short[] tex = { 96, 32, 64, 32, 96, 64, 64, 64,
64, 32, 32, 32, 64, 64, 32, 64,
64, 0, 32, 0, 64, 32, 32, 32,
32, 0, 0, 0, 32, 32, 0, 32,
32, 32, 0, 32, 32, 64, 0, 64,
96, 0, 64, 0, 96, 32, 64, 32 };
// Create a vertex array for the texture coordinates of the object
VertexArray texArray = new VertexArray( tex.length / 2, 2, 2 );
texArray.set( 0, tex.length/2, tex );
int[] stripLen = { 4, 4, 4, 4, 4, 4 }; // The length of each triangle strip
// Create the VertexBuffer for our object
VertexBuffer vb = iVb = new VertexBuffer();
vb.setPositions( vertArray, 1.0f, null ); // Unit scale, zero bias
vb.setNormals( normArray );
vb.setTexCoords( 0, texArray, (1.0f/128.0f), null ); // 128-pixel scale, zero bias
// Create the index buffer for the object (this tells how to create triangle
// strips from the contents of the vertex buffer).
iIb = new TriangleStripArray( 0, stripLen );
// Load the image for the texture
iImage = Image.createImage("/res/cubeface.png");
// iImage = Image.createImage("/cubeface.png");
// Create the Image2D (we need this so we can make a Texture2D)
Image2D image2D = new Image2D( Image2D.RGB, iImage );
// Create the Texture2D and enable mipmapping
// Texture color is to be modulated with the lit material color
Texture2D texture = new Texture2D( image2D );
texture.setFiltering( Texture2D.FILTER_NEAREST, Texture2D.FILTER_NEAREST );
texture.setWrapping( Texture2D.WRAP_CLAMP, Texture2D.WRAP_CLAMP );
texture.setBlending( Texture2D.FUNC_MODULATE );
// Load image for the background
iImage = Image.createImage("/res/backdrop.png");
// iImage = Image.createImage("/backdrop.png");
backDrop = new Image2D(Image2D.RGB, iImage);
// Create the appearance
iAppearance = new Appearance();
iAppearance.setTexture( 0, texture ); // add the Texture2D to the Appearance
iAppearance.setMaterial(iMaterial);
iMaterial.setVertexColorTrackingEnable( true ); //Ttrack per-vertex colors
iMaterial.setColor(Material.SPECULAR, 0xFFFFFFFF); // Specular = white
iMaterial.setShininess(100.0f);
// iBackground.setColor( 0x8833FF ); // set the background color
iBackground.setImage( backDrop ); // Set the background image
// Set up the camera in the desired position
transform3D = new Transform();
transform3D.postTranslate(0.0f, 0.0f, 50.0f);
// Binds this light for immediate mode rendering. Otherwise it won't have an effect.
iG3D.setCamera( iCamera, transform3D );
// Set up a "headlight": a directional light shining from the direction of the camera.
// Binds this camera for immediate mode rendering. Won't have an effect otherwise.
iG3D.resetLights();
iG3D.addLight(iLight, transform3D );
} // end init()
// Paint the scene
protected void paint(Graphics g) {
// Bind the Graphics of this Canvas to our Graphics3D. The viewport
// is automatically set to cover the entire clipping rectangle of the
// Graphics object. The boolean parameters indicate that z-buffering,
// dithering and true color rendering are enabled. Because render() is
// applied to a submesh (a vertex buffer and not a Group or World node),
// the cube is rendered in immediate mode.
iG3D.bindTarget(g, true, Graphics3D.DITHER | Graphics3D.TRUE_COLOR);
// Clear the color and depth buffers--which draws the background image
iG3D.clear( iBackground );
// Update our transform (this will give us a rotating cube)
iTransform.postRotate(3.0f, 1.0f, 1.0f, 1.0f ); // rotate around this axis
// Render our cube, immediate mode. We provide the vertex and index buffers to specify
// the geometry; the appearance so we know what material and texture to use, and
// the transform to tell where to render the object.
iG3D.render( iVb, iIb, iAppearance, iTransform );
// Free the graphics object
iG3D.releaseTarget();
} // end paint()
} // end class myCanvas
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -