www.pudn.com > Bluegammon蓝牙的应用编程.rar > Context3D.java
// Copyright (c) 2005 Sony Ericsson Mobile Communications AB // // This software is provided "AS IS," without a warranty of any kind. // ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, // INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A // PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. // // THIS SOFTWARE IS COMPLEMENTARY OF JAYWAY AB (www.jayway.se) package bluegammon.gui; import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.Image; import javax.microedition.m3g.Appearance; import javax.microedition.m3g.Camera; import javax.microedition.m3g.Graphics3D; import javax.microedition.m3g.Image2D; import javax.microedition.m3g.IndexBuffer; import javax.microedition.m3g.Light; import javax.microedition.m3g.Material; import javax.microedition.m3g.Texture2D; import javax.microedition.m3g.Transform; import javax.microedition.m3g.TriangleStripArray; import javax.microedition.m3g.VertexArray; import javax.microedition.m3g.VertexBuffer; import bluegammon.Resources; /** *The 3d context used in this game. Consists of the scene which is * a camera with one main headlight; and dice, string or piece objects. * Also contains functionality for creating objects and defining materials. * We only have one 3d context, thus the singleton pattern.
**
* The dice and the piece is constructed mathematically based on the * JSR184 specifications. *
** The piece is constructed from a number of predefined pie-slices. The greater amount * of slices, the more circular piece - but also the amount of triangles per piece will increase, * impacting the performance. Each piece consists of 4 * numberOfSlices triangles. *
*
*
** The dice is calculated using a somewhat more complicated model. Each dice consists of * 6 * 6 faces + 8 corners = 44 triangles.
** A graphical representation of how one face of the dice is calculated is depicted below:
* * @author Peter Andersson */ public class Context3D { /** Field of view, degrees on horizontal axis */ public static final float FOVY = 35f; /** Z-axis near clipping plane */ public static final float NEAR_CLIPPING_PLANE = 1f; /** Z-axis far clipping plane */ public static final float FAR_CLIPPING_PLANE = 512f; /** The camera of the scene */ protected Camera m_camera; /** The position and direction of the camera */ protected Transform m_cameraTransform; /** The light of the scene */ protected Light m_light; /** The position and direction of the light*/ protected Transform m_lightTransform; /** Appearence cahce */ protected Appearance[] m_appearances = new Appearance[2]; /** Texture cache */ protected Texture2D[] m_textures = new Texture2D[2]; /** Dice vertex buffer cache */ protected VertexBuffer m_diceVertBuffer; /** Dice index buffer cache */ protected IndexBuffer m_diceIndexBuffer; /** Piece vertex buffer cache */ protected VertexBuffer m_pieceVertBuffer; /** Piece index buffer cache */ protected IndexBuffer m_pieceIndexBuffer; /** Quick and dirty screen to 3d coordinate transformation factor */ protected double m_scr2ThreeD; /** Quick and dirty 3d to screen coordinate transformation factor */ protected double m_threeD2Scr; /** Width of screen */ protected int m_width; /** Height of screen */ protected int m_height; /** Half width of screen */ protected int m_halfWidth; /** Half height of screen */ protected int m_halfHeight; /** Singleton instance */ protected static Context3D m_inst = null; /** Light source rotation around Y axis */ protected static final float LIGHT_ROT = 33f; /** Tangens for light source rotation */ protected static final double TAN_LIGHT_ROT = Math.tan(Math.toRadians(LIGHT_ROT)); /** Number of slices in a piece */ protected static final int PIECE_SLICES = 10; /** Unity value in 3D coordinates */ protected static final short UNITY = Short.MAX_VALUE / 8; /** * Returns singleton instance. * @return The singleton instance. */ public static Context3D getInstance() { if (m_inst == null) { m_inst = new Context3D(); } return m_inst; } /** * Sets up our viewport, camera, lighting - everyting needed for the scene * @param width The width of the viewport * @param height The height of the viewport */ public void init(int width, int height) { m_width = width; m_height = height; m_halfWidth = width / 2 - 1; m_halfHeight = height / 2 - 1; // create a camera m_camera = new Camera(); m_camera.setPerspective( FOVY, // field of view (float)width / (float)height, // aspectRatio NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE); // camera transform matrix m_cameraTransform = new Transform(); m_cameraTransform.setIdentity(); m_cameraTransform.postTranslate(0f, 0f, 1f); // create a light m_light = new Light(); m_light.setColor(0xffffff); m_light.setIntensity(1.1f); m_light.setMode(Light.DIRECTIONAL); // ligth transform matrix - shine from near right to far left m_lightTransform = new Transform(); m_lightTransform.setIdentity(); m_lightTransform.postTranslate(0f, 0f, 10f); m_lightTransform.postRotate(LIGHT_ROT, 0f, 1f, 0f); // transformation factors double factor = 2.15; // Magic 3d factor, works for K750 when calculating // 2d-3d and 3d-2d coordinate transformations. // This factor might need to be altered on bigger screens. double tanFovY = Math.tan(Math.toRadians(FOVY)); m_threeD2Scr = factor * (double)height / (2d * tanFovY); m_scr2ThreeD = 2d * tanFovY / (factor * (double)height); } /** * Recalculates a x 3d coordinate to a screen x coordinate. * @param coordinate3D The 3d x coordinate * @param z The depth of the 3d coordinate * @return The screen coordinate */ public float toScreenCoordinateX(float coordinate3D, float z) { return (float)(-coordinate3D * m_threeD2Scr / z); } /** * Recalculates a screen x coordinate to a 3d x coordinate. * @param coordinateScreen The screen x coordinate * @param z The depth of the 3d coordinate * @return The 3d x coordinate */ public float to3DCoordinateX(float coordinateScreen, float z) { return (float)((-coordinateScreen + m_halfWidth) * m_scr2ThreeD * z); } /** * Recalculates a 3d y coordinate to a screen y coordinate. * @param coordinate3D The 3d y coordinate * @param z The depth of the 3d coordinate * @return The screen y coordinate */ public float toScreenCoordinateY(float coordinate3D, float z) { return (float)(coordinate3D * m_threeD2Scr / z); } /** * Recalculates a screen y coordinate to a 3d y coordinate. * @param coordinateScreen The screen y coordinate * @param z The depth of the 3d coordinate * @return The 3d y coordinate */ public float to3DCoordinateY(float coordinateScreen, float z) { return (float)((coordinateScreen - m_halfHeight) * m_scr2ThreeD * z); } /** * Returns delta x coordinate of shadow position given * specified delta z between object and projection plane. * @param deltaZ The difference in z between object * and shadow projecton plane. * @return Delta x coordinate in 3d units. */ public float getShadowProjectionDeltaX(float deltaZ) { if (deltaZ == 0) { return 0; } else { return (float)(Math.abs(deltaZ) * TAN_LIGHT_ROT); } } /** * Binds a graphics context and set up the common * 3d environment used in this game. * * @param g The graphics environment to render upon. * @return A Graphics3D object with common 3d environment settings. */ public Graphics3D bindScene(Graphics g) { Graphics3D g3d = Graphics3D.getInstance(); // Use dithering and true-color, no z-buffering g3d.bindTarget(g, false, Graphics3D.DITHER | Graphics3D.TRUE_COLOR); g3d.setCamera(m_camera, m_cameraTransform); g3d.resetLights(); g3d.addLight(m_light, m_lightTransform); return g3d; } /** * Creates an rgb buffer rendered a shadow that is transparant. * * @param size Shadow size * @param sizeDim Blank border. * @return An rgb buffer containing a transparant shadow */ public static int[] createShadowRGB(int size, int sizeDim) { int[] shadow = new int[size * size]; Image shadowImg = Image.createImage(size, size); Graphics g = shadowImg.getGraphics(); g.setColor(0xff0000); g.fillRect(0, 0, size * 2, size * 2); for (int i = 0; i < 4; i++) { g.setColor((i + 1) << 4); g.fillArc(i + sizeDim, i + sizeDim, size - 2 * (i + sizeDim), size - 2 * (i + sizeDim), 0, 360); } shadowImg.getRGB(shadow, 0, size, 0, 0, size, size); for (int i = 0; i < shadow.length; i++) { if ((shadow[i] & 0x00ffffff) == 0xff0000) { shadow[i] = 0x00000000; // totally transparant } else { // calculate semitransparancy depending on shadow color int trans = ((shadow[i] & 0x000000ff) << 56) & 0xff000000; shadow[i] = trans; } } return shadow; } /** * Returns the appearance (texture and material) for a piece. * @param white true for white appearance, false for black appearance. * @return The piece appearance. */ public Appearance getPieceAppearance(boolean white) { return getDiceAppearance(white); // Pieces and dices are of the same material } /** * Returns the appearance (texture and material) for a dice. * @param white true for white appearance, false for black appearance. * @return The dice appearance. */ public Appearance getDiceAppearance(boolean white) { int index = white ? 0:1; if (m_appearances[index] == null) { Material material = new Material(); material.setColor(Material.AMBIENT, 0x606060); material.setColor(Material.DIFFUSE, 0xf0e8e0); material.setColor(Material.SPECULAR, 0xffffff); material.setShininess(50.0f); m_appearances[index] = new Appearance(); m_appearances[index].setTexture(0, getTexture(white)); m_appearances[index].setMaterial(material); } return m_appearances[index]; } /** * Returns the textures used within this game. * @param white true for white textures, false for black textures. * @return the texture. */ public Texture2D getTexture(boolean white) { int index = white ? 0:1; if (m_textures[index] == null) { Image2D image2D = null; if (white) { image2D = new Image2D(Image2D.RGB, Resources.getImage(Resources.IMG_WHITE_TEXTURES)); } else { image2D = new Image2D(Image2D.RGB, Resources.getImage(Resources.IMG_BLACK_TEXTURES)); } // create the Texture2D and enable mipmapping // texture color is to be modulated with the lit material color m_textures[index] = new Texture2D(image2D); m_textures[index].setFiltering(Texture2D.FILTER_LINEAR, Texture2D.FILTER_LINEAR); m_textures[index].setWrapping(Texture2D.WRAP_CLAMP, Texture2D.WRAP_CLAMP); m_textures[index].setBlending(Texture2D.FUNC_MODULATE); } return m_textures[index]; } /** * Returns vertexbuffer for a piece. * @return a piece vertex buffer */ public VertexBuffer getPieceVertexBuffer() { if (m_pieceVertBuffer == null) { calculatePieceBuffers(); } return m_pieceVertBuffer; } /** * Returns indexbuffer for a piece. * @return a piece index buffer */ public IndexBuffer getPieceIndexBuffer() { if (m_pieceIndexBuffer == null) { calculatePieceBuffers(); } return m_pieceIndexBuffer; } /** * Returns vertexbuffer for a dice. * @return a dice vertex buffer */ public VertexBuffer getDiceVertexBuffer() { if (m_diceVertBuffer == null) { calculateDiceBuffers(); } return m_diceVertBuffer; } /** * Returns index buffer for a dice. * @return a dice index buffer */ public IndexBuffer getDiceIndexBuffer() { if (m_diceIndexBuffer == null) { calculateDiceBuffers(); } return m_diceIndexBuffer; } /** * Calculates piece vertex- and indexbuffers. */ protected void calculatePieceBuffers() { int slices = PIECE_SLICES; short I = UNITY; // Unit value short H = (short)(I / 8); // Heigth of piece is 2*diameter/8 short mH = (short)(-H); // Define vertices for the piece. Number of vertices for a piece is // nbrOfSlices * (nbrOfPointsTopSlice + nbrOfPointsBottomSlice + nbrOfPointsSide) short[] vert = new short[slices * 3 * (3+3+4)]; double angle = (2d*Math.PI/(double)slices)/2d; for (int i = 0; i < slices; i++) { // Define one slice of the piece int TOP = i*3*3; int BOT = i*3*3 + (slices*3*3); int SID = i*3*4 + 2*(slices*3*3); short sin = (short)((double)I*Math.sin(angle)); short cos = (short)((double)I*Math.cos(angle)); angle += (2d*Math.PI / (double)slices); short nsin = (short)((double)I*Math.sin(angle)); short ncos = (short)((double)I*Math.cos(angle)); // TOP vert[TOP++] = 0; // center pt vert[TOP++] = 0; vert[TOP++] = H; vert[TOP++] = cos; // edge pt vert[TOP++] = sin; vert[TOP++] = H; vert[TOP++] = ncos; // next edge pt vert[TOP++] = nsin; vert[TOP++] = H; // BOTTOM vert[BOT++] = 0; // center pt vert[BOT++] = 0; vert[BOT++] = mH; vert[BOT++] = ncos; // edge pt vert[BOT++] = nsin; vert[BOT++] = mH; vert[BOT++] = cos; // next edge pt vert[BOT++] = sin; vert[BOT++] = mH; // SIDE vert[SID++] = cos; // top edge pt vert[SID++] = sin; vert[SID++] = H; vert[SID++] = cos; // bottom next edge pt vert[SID++] = sin; vert[SID++] = mH; vert[SID++] = ncos; // top next edge pt vert[SID++] = nsin; vert[SID++] = H; vert[SID++] = ncos; // bottom edge pt vert[SID++] = nsin; vert[SID++] = mH; } // create VertexArray to hold the vertices VertexArray vertArray = new VertexArray(vert.length / 3, 3, 2); vertArray.set(0, vert.length / 3, vert); // Setup per-vertex normals for the piece; these match with the vertices // above. Each top/bottom-vertex-normal is perpendicular to the face. // Fake round corners by giving sphere-normals for each vertex of a side. // This enables a Goraudshading effect of round sides. byte[] vertexNormals = new byte[slices * 3 * (3+3+4)]; angle = (2d*Math.PI/(double)slices)/2d; for (int i = 0; i < slices; i++) { int TOP = i*3*3; int BOT = i*3*3 + (slices*3*3); int SID = i*3*4 + 2*(slices*3*3); byte sin = (byte)((double)127*Math.sin(angle)); byte cos = (byte)((double)127*Math.cos(angle)); angle += (2d*Math.PI / (double)slices); byte nsin = (byte)((double)127*Math.sin(angle)); byte ncos = (byte)((double)127*Math.cos(angle)); // TOP vertexNormals[TOP++] = 0; // center vertexNormals[TOP++] = 0; vertexNormals[TOP++] = 127; vertexNormals[TOP++] = 0; // edge vertexNormals[TOP++] = 0; vertexNormals[TOP++] = 127; vertexNormals[TOP++] = 0; // next edge vertexNormals[TOP++] = 0; vertexNormals[TOP++] = 127; // BOTTOM vertexNormals[BOT++] = 0; // center vertexNormals[BOT++] = 0; vertexNormals[BOT++] = -127; vertexNormals[BOT++] = 0; // edge vertexNormals[BOT++] = 0; vertexNormals[BOT++] = -127; vertexNormals[BOT++] = 0; // next edge vertexNormals[BOT++] = 0; vertexNormals[BOT++] = -127; // SIDES vertexNormals[SID++] = cos; // top edge vertexNormals[SID++] = sin; vertexNormals[SID++] = 0; vertexNormals[SID++] = cos; // bottom edge vertexNormals[SID++] = sin; vertexNormals[SID++] = 0; vertexNormals[SID++] = ncos; // top next edge vertexNormals[SID++] = nsin; vertexNormals[SID++] = 0; vertexNormals[SID++] = ncos; // bottom next edge vertexNormals[SID++] = nsin; vertexNormals[SID++] = 0; } // create a vertex array for the normals of the object VertexArray normArray = new VertexArray(vertexNormals.length / 3, 3, 1); normArray.set(0, vertexNormals.length / 3, vertexNormals); // per vertex texture coordinates // texsize = 256x32 => 32*(8x1) short[] tex = new short[slices * 2 * (3+3+4)]; angle = (2d*Math.PI/(double)slices)/2d; int offsX = 14 * I / 8; for (int i = 0; i < slices; i++) { int TOP = i*3*2; int BOT = i*3*2 + (slices*3*2); int SID = i*4*2 + 2*(slices*3*2); short sin = (short)((double)I*Math.sin(angle)); short cos = (short)((double)I*Math.cos(angle)); angle += (2d*Math.PI / (double)slices); short nsin = (short)((double)I*Math.sin(angle)); short ncos = (short)((double)I*Math.cos(angle)); // TOP tex[TOP++] = (short)(I / 8 + offsX); // center tex[TOP++] = I; tex[TOP++] = (short)((I + cos) / 8 + offsX); // edge tex[TOP++] = (short)(I + sin); tex[TOP++] = (short)((I + ncos) / 8 + offsX); // next edge tex[TOP++] = (short)(I + nsin); // BOTTOM tex[BOT++] = (short)(I / 8 + offsX); // simile tex[BOT++] = I; tex[BOT++] = (short)((I + ncos) / 8 + offsX); tex[BOT++] = (short)(I + nsin); tex[BOT++] = (short)((I + cos) / 8 + offsX); tex[BOT++] = (short)(I + sin); // SIDE tex[SID++] = 0; // top edge tex[SID++] = 0; tex[SID++] = (short)(2*I / 8); // bottom edge tex[SID++] = 0; tex[SID++] = 0; // top next edge tex[SID++] = (short)(2*I); tex[SID++] = (short)(2*I / 8); // bottom next edge tex[SID++] = (short)(2*I); } // create a vertex array for the texture coordinates VertexArray texArray = new VertexArray(tex.length / 2, 2, 2); texArray.set(0, tex.length / 2, tex); // create the VertexBuffer float posScale = 1.0f / (float)(I); float texScale = 1.0f / (float)(2f * I); m_pieceVertBuffer = new VertexBuffer(); m_pieceVertBuffer.setPositions(vertArray, posScale, null); // 1/UNITY scale, no bias m_pieceVertBuffer.setNormals(normArray); m_pieceVertBuffer.setTexCoords(0, texArray, texScale, null); // 1/(2*UNITY) scale, no bias // the length of each triangle strip int[] stripLen = new int[slices*(1+1+1)]; for (int i = 0; i < slices; i++) { int TOP = i; int BOT = i + slices; int SID = i + 2*slices; stripLen[TOP] = 3; // Top pie slice stripLen[BOT] = 3; // Bottom pie slice stripLen[SID] = 4; // Side } // create the index buffer for our object (this tells how to // create triangle strips from the contents of the vertex buffer). m_pieceIndexBuffer = new TriangleStripArray(0, stripLen); } /** * Calculates dice vertex- and index buffers. */ protected void calculateDiceBuffers() { // Define values for dice, these are used throughout the // definitions of vertices, normals, and texture coordinates short I = UNITY; // Unit value short s = (short)(I/2); // Size of corner (0 - I) short D = (short)(I-s); // Position of corner short mI = (short)(-I); // Negative unit value short mD = (short)(mI+s); // Negative position of corner // Define vertices for the dices short[] vertices = { // FACES // front mI,mD, I, mD,mI, I, I,mD, I, D,mI, I, mI, D, I, mI,mD, I, I, D, I, I,mD, I, mD, I, I, mI, D, I, D, I, I, I, D, I, // back I,mD,mI, D,mI,mI, mI,mD,mI, mD,mI,mI, I, D,mI, I,mD,mI, mI, D,mI, mI,mD,mI, D, I,mI, I, D,mI, mD, I,mI, mI, D,mI, // right I,mI,mD, I,mD,mI, I, I,mD, I, D,mI, I,mI, D, I,mI,mD, I, I, D, I, I,mD, I,mD, I, I,mI, D, I, D, I, I, I, D, // left mI, I,mD, mI,D,mI, mI,mI,mD, mI,mD,mI, mI, I, D, mI,I,mD, mI,mI, D, mI,mI,mD, mI, D, I, mI,I, D, mI,mD, I, mI,mI, D, // bottom mI,mI,mD, mD,mI,mI, I,mI,mD, D,mI,mI, mI,mI, D, mI,mI,mD, I,mI, D, I,mI,mD, mD,mI, I, mI,mI, D, D,mI, I, I,mI, D, // top I, I,mD, D, I,mI, mI, I,mD, mD, I,mI, I, I, D, I, I,mD, mI, I, D, mI, I,mD, D, I, I, I, I, D, mD, I, I, mI, I, D, // CORNERS // near, top // left mI, D, I, mD, I, I, mI, I, D, // right I, D, I, I, I, D, D, I, I, // near, bottom // left mI,mD, I, mI,mI, D, mD,mI, I, // right I,mD, I, D,mI, I, I,mI, D, // far, top // left mI, D,mI, mI, I,mD, mD, I,mI, // right I, D,mI, D, I,mI, I, I,mD, // far, bottom // left mI,mD,mI, mD,mI,mI, mI,mI,mD, // right I,mD,mI, I,mI,mD, D,mI,mI }; // create a VertexArray to hold the vertices for the object VertexArray vertArray = new VertexArray(vertices.length / 3, 3, 2); vertArray.set(0, vertices.length / 3, vertices); double n = Math.sqrt(I*I + I*I + D*D); // Length of any corner vector byte nI = (byte)(127d*(double)I/n); byte mnI = (byte)(-nI); byte nD = (byte)(127d*(double)D/n); byte mnD = (byte)(-nD); // Setup per-vertex normals for the dice; these match with the vertices // above. Each face-vertex-normal is perpendicular to each face. // Fake round corners by giving sphere-normals for each vertex of a corner. // This enables a Goraudshading effect of round corners. byte[] vertexNormals = { // FACES // front 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,0,127, 0,0,127, 0,0,127, 0,0,127, // back 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,0,-127, 0,0,-127, 0,0,-127, 0,0,-127, // right 127,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,0, 127,0,0, 127,0,0, 127,0,0, // left -127,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,0, -127,0,0, -127,0,0, -127,0,0, // top 0,-127,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, 0,-127,0, 0,-127,0, 0,-127,0, // bottom 0,127,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, 0,127,0, 0,127,0, 0,127,0, // CORNERS // near, top // left mnI, nD, nI, mnD, nI, nI, mnI, nI, nD, // right nI, nD, nI, nI, nI, nD, nD, nI, nI, // near, bottom // left mnI,mnD, nI, mnI,mnI, nD, mnD,mnI, nI, // right nI,mnD, nI, nD,mnI, nI, nI,mnI, nD, // far, top // left mnI, nD,mnI, mnI, nI,mnD, mnD, nI,mnI, // right nI, nD,mnI, nD, nI,mnI, nI, nI,mnD, // far, bottom // left mnI,mnD,mnI, mnD,mnI,mnI, mnI,mnI,mnD, // right nI,mnD,mnI, nI,mnI,mnD, nD,mnI,mnI }; // create a vertex array for the normals of the object VertexArray normArray = new VertexArray(vertexNormals.length / 3, 3, 1); normArray.set(0, vertexNormals.length / 3, vertexNormals); // per vertex texture coordinates // texsize = 256x32 => 32*(8x1) short txIbase = (short)((I + I)/8); short mtxIbase = (short)((mI + I)/8); short txDbase = (short)((D + I)/8); short mtxDbase = (short)((mD + I)/8); short tyI = (short)(I + (7*I)/8); // Mathematically, tyI should be 2*I - // however, this causes the 3d library to // crash in some cases, probably due to // that (2*I) * (1.0f / (float)(2*I)) becomes // somewhat greater than 1.000000f, making it // read texture beyond the image and thus crash short mtyI = (short)(mI + I); short tyD = (short)(D + I); short mtyD = (short)(mD + I); short[] txI = new short[8]; short[] mtxI = new short[8]; short[] txD = new short[8]; short[] mtxD = new short[8]; for (int i = 0; i < 8; i++) { txI[i] = (short)(txIbase + txIbase * i); mtxI[i] = (short)(mtxIbase + txIbase * i); txD[i] = (short)(txDbase + txIbase * i); mtxD[i] = (short)(mtxDbase + txIbase * i); } short[] tex = { // FACES // front - 1 mtxI[1],mtyD, mtxD[1],mtyI, txI[1],mtyD, txD[1],mtyI, mtxI[1], tyD, mtxI[1],mtyD, txI[1], tyD, txI[1],mtyD, mtxD[1], tyI, mtxI[1], tyD, txD[1], tyI, txI[1], tyD, // back - 6 mtxI[6],mtyD, mtxD[6],mtyI, txI[6],mtyD, txD[6],mtyI, mtxI[6], tyD, mtxI[6],mtyD, txI[6], tyD, txI[6],mtyD, mtxD[6], tyI, mtxI[6], tyD, txD[6], tyI, txI[6], tyD, // right - 4 mtxI[4],mtyD, mtxD[4],mtyI, txI[4],mtyD, txD[4],mtyI, mtxI[4], tyD, mtxI[4],mtyD, txI[4], tyD, txI[4],mtyD, mtxD[4], tyI, mtxI[4], tyD, txD[4], tyI, txI[4], tyD, // left - 3 mtxI[3],mtyD, mtxD[3],mtyI, txI[3],mtyD, txD[3],mtyI, mtxI[3], tyD, mtxI[3],mtyD, txI[3], tyD, txI[3],mtyD, mtxD[3], tyI, mtxI[3], tyD, txD[3], tyI, txI[3], tyD, // top - 5 mtxI[5],mtyD, mtxD[5],mtyI, txI[5],mtyD, txD[5],mtyI, mtxI[5], tyD, mtxI[5],mtyD, txI[5], tyD, txI[5],mtyD, mtxD[5], tyI, mtxI[5], tyD, txD[5], tyI, txI[5], tyD, // bottom - 2 mtxI[2],mtyD, mtxD[2],mtyI, txI[2],mtyD, txD[2],mtyI, mtxI[2], tyD, mtxI[2],mtyD, txI[2], tyD, txI[2],mtyD, mtxD[2], tyI, mtxI[2], tyD, txD[2], tyI, txI[2], tyD, // CORNERS // near mtxI[0],tyI, txI[0],mtyI, mtxI[0],mtyI, mtxI[0],tyI, txI[0],mtyI, txI[0], tyI, mtxI[0],tyI, txI[0],mtyI, mtxI[0],mtyI, mtxI[0],tyI, txI[0],mtyI, txI[0], tyI, // far mtxI[0],tyI, txI[0],mtyI, mtxI[0],mtyI, mtxI[0],tyI, txI[0],mtyI, txI[0], tyI, mtxI[0],tyI, txI[0],mtyI, mtxI[0],mtyI, mtxI[0],tyI, txI[0],mtyI, txI[0], tyI }; // create a vertex array for the texture coordinates VertexArray texArray = new VertexArray(tex.length / 2, 2, 2); texArray.set(0, tex.length / 2, tex); // create the VertexBuffer float posScale = 1.0f / (float)(I); float texScale = 1.0f / (float)(2 * I); m_diceVertBuffer = new VertexBuffer(); m_diceVertBuffer.setPositions(vertArray, posScale, null); // 1/UNITY scale, no bias m_diceVertBuffer.setNormals(normArray); m_diceVertBuffer.setTexCoords(0, texArray, texScale, null); // 1/(2*UNITY) scale, no bias // the length of each triangle strip int[] stripLen = { 4,4,4, // face front 4,4,4, // face back 4,4,4, // face left 4,4,4, // face right 4,4,4, // face bottom 4,4,4, // face top 3,3,3,3, // near corners 3,3,3,3 // far corners }; // create the index buffer for our object (this tells how to // create triangle strips from the contents of the vertex buffer). m_diceIndexBuffer = new TriangleStripArray(0, stripLen); } }
*
*