⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lightsamplecanvas.java

📁 3D J2ME 代码集合
💻 JAVA
字号:


import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;

import javax.microedition.m3g.*;

class LightSampleCanvas extends GameCanvas implements Runnable{
  
    private Graphics3D g3d; // Graphics object used to render the world.
    private World world; // This world contains the camera and the pyramidMesh.
    private Camera camera; // the camera in the scene
    private Mesh icosahedronMesh; // the icosahedron in the scene
    private Light light;
    private int lightIndex = 0;
    private javax.microedition.midlet.MIDlet midlet;
    private Image SwitchImage = null;
    private final int SCREEN_WIDTH;
    private final int SCREEN_HEIGHT;

    public LightSampleCanvas(javax.microedition.midlet.MIDlet m){
        super(false);
        midlet = m;
        try{
            SwitchImage = Image.createImage("/switch.png");

        }catch(Exception e){
            System.out.println("FAILED TO LOAD IMAGES!!");
        }
          
       setFullScreenMode(true);

        SCREEN_WIDTH = getWidth();
        SCREEN_HEIGHT = getHeight(); 
       
        g3d = Graphics3D.getInstance();
        world = new World();

        camera = new Camera();
        world.addChild(camera); // add the camera to the world.

        light = new Light();                    // Create a new light
        light.translate(0.0f, 0.0f, -1.0f); // The light position
        light.setMode(Light.SPOT);   // Light Mode
        light.setColor(0xFFFFFF);           // The color of the light 'WHITE'
        light.setSpotExponent(128.0f); // splot light concentration 0 to 128
        light.setSpotAngle(60);
        world.addChild(light);                // Add the light to the world to be rendered.

        // Constructs a perspective projection matrix and sets that as the current projection matrix.
        camera.setPerspective(60.0f, (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT, 0.1f, 50f);
        
        
        icosahedronMesh = createIcosahedron(); // create our Icosahedron.
        
        icosahedronMesh.setTranslation(0.0f, 0.0f, -3.0f); // move the icosahedron 3 units into the screen.
        world.addChild(icosahedronMesh);

        world.setActiveCamera(camera);
        
        Thread t = new Thread(this);
        t.start();
    }
    
    public void keyPressed(int key){
        switch(key){
          
            case -7:
                nextLight();    // change light
                break;
            case -11:
                midlet.notifyDestroyed();
                break;
        }
    }
    
    /*
     * Change the Light Mode to be used.
     */
    public void nextLight(){
        //lightIndex = lightIndex == 3?0:lightIndex+1;
        lightIndex = 3;
        switch(lightIndex){
            case 0:
                light.setMode(Light.AMBIENT);
                break;
            case 1:
                light.setMode(Light.DIRECTIONAL);
                break;
            case 2:
                light.setMode(Light.OMNI);
                break;
            case 3:
                light.setMode(Light.SPOT);
                break;
        }
    }
    

    
    public void draw3D(Graphics g){
        g.setColor(0x000000);
        g.fillRect(0, 0, getWidth(), getHeight());
        try{
            g3d.bindTarget(g); // Binds the given Graphics or mutable Image2D as the rendering target of this Graphics3D
            g3d.render(world); // Render the world
        }finally{
            g3d.releaseTarget();
        }
    }

    private void draw2D(Graphics g){
        g.setColor(0xFFFFFF);
        switch(lightIndex){
            case 0:
                g.drawString("Ambient", 0, 0, 0);
                break;
            case 1:
                g.drawString("Directional", 0, 0, 0);
                break;
            case 2:
                g.drawString("Omni", 0, 0, 0);
                break;
            case 3:
                g.drawString("Spot", 0, 0, 0);
                break;
        }
        
        g.drawImage(SwitchImage, SCREEN_WIDTH, SCREEN_HEIGHT, Graphics.RIGHT | Graphics.BOTTOM);
    }
    
    public void run() {
        Graphics g = getGraphics();

        while(true){
            
       
               // icosahedronMesh.postRotate(1.0f, 0.0f, 1.0f, 0.0f);
             
        
      //  light.postRotate(1.0f, 1.0f, 0.0f, 0.0f); //enable this to make the light rotate around it's x-axis
        
            draw3D(g);
            draw2D(g);
            
            flushGraphics();
        }
    }


    private Mesh createIcosahedron(){
        final short X = 525;
        final short Z = 850;
        short[]ORG_POINTS = new short[] {-X, 0, Z,      X, 0, Z,    -X, 0, -Z,      X, 0, -Z,
                                                                   0, Z, X,      0, Z, -X,    0, -Z, X,      0, -Z, -X,
                                                                   Z, X, 0,     -Z, X, 0,     Z, -X, 0,     -Z, -X, 0};

        int []ORG_INDICES = new int[] {0,4, 1,        0,9,4,       9,5,4,       4,5,8,      4,8,1,
                                                            8,10,1,       8,3,10,     5,3,8,       5,2,3,       2,7,3,
                                                            7,10,3,       7,6,10,     7,11,6,     11,0,6,     0,1,6,
                                                            6,1,10,       9,0,11,     9,11,2,     9,2,5,       7,2,11};


        short[]POINTS = new short[72*3];
        int []INDICES = new int[80*3+80];

        for(int i=0; i<36; i++){
            POINTS[i] = ORG_POINTS[i];
        }
        for(int i=0; i<60; i++){
            INDICES[i] = ORG_INDICES[i];
        }
        
        // Start sub deviding
        // every triangle should become 4 triangles.
        VEK v12, v23, v31;
        int pointIndex = 36;
        int numPoints  = 12;
        int indiceIndex = 60;
        for(int i=0; i<60; i+=3){
            VEK v1 = new VEK(POINTS[INDICES[i]*3], POINTS[INDICES[i]*3+1], POINTS[INDICES[i]*3+2]);
            VEK v2 = new VEK(POINTS[INDICES[i+1]*3], POINTS[INDICES[i+1]*3+1], POINTS[INDICES[i+1]*3+2]);
            VEK v3 = new VEK(POINTS[INDICES[i+2]*3], POINTS[INDICES[i+2]*3+1], POINTS[INDICES[i+2]*3+2]);

            v12 = new VEK(v1.X + v2.X, v1.Y + v2.Y, v1.Z+v2.Z);
            v23 = new VEK(v2.X + v3.X, v2.Y + v3.Y, v2.Z+v3.Z);
            v31 = new VEK(v3.X + v1.X, v3.Y + v1.Y, v3.Z+v1.Z);

            v12 = MATH.vekNormalizePoint(v12);
            v23 = MATH.vekNormalizePoint(v23);
            v31 = MATH.vekNormalizePoint(v31);
            
            // 3 new points
            POINTS[pointIndex] = v12.X;     // numPoints
            POINTS[pointIndex+1] = v12.Y;
            POINTS[pointIndex+2] = v12.Z;

            POINTS[pointIndex+3] = v23.X; // numPoints + 1
            POINTS[pointIndex+4] = v23.Y;
            POINTS[pointIndex+5] = v23.Z;

            POINTS[pointIndex+6] = v31.X; // numPoints + 2
            POINTS[pointIndex+7] = v31.Y;
            POINTS[pointIndex+8] = v31.Z;
            pointIndex+=9;
            
            // 4 new triangles
            INDICES[indiceIndex] = INDICES[i];
            INDICES[indiceIndex+1] = numPoints;
            INDICES[indiceIndex+2] = numPoints+2;

            INDICES[indiceIndex+3] = INDICES[i+1];
            INDICES[indiceIndex+4] = numPoints+1;
            INDICES[indiceIndex+5] = numPoints;

            INDICES[indiceIndex+6] = INDICES[i+2];
            INDICES[indiceIndex+7] = numPoints+2;
            INDICES[indiceIndex+8] = numPoints+1;
            
            INDICES[indiceIndex+9] = numPoints;
            INDICES[indiceIndex+10] = numPoints+1;
            INDICES[indiceIndex+11] = numPoints+2;
            
            indiceIndex += 12;
            numPoints +=3;
        }
        
        // a normal is created for every point.
        short[] NORMALS = new short[POINTS.length];
        VEK a, b, c;
         for(int i=0; i<NORMALS.length; i+=3){
             a = new VEK(POINTS[i], POINTS[i+1], POINTS[i+2]);
             VEK v = MATH.vekNormalizeNormal(a);
             NORMALS[i] = v.X;
             NORMALS[i+1] = v.Y;
             NORMALS[i+2] = v.Z;
         }
        
        
        int []LENGTH = new int[100];// {3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3};
        for(int i=0; i<100; i++){
            LENGTH[i] = 3;
        }
        VertexArray POSITION_ARRAY, NORMAL_ARRAY;
        IndexBuffer INDEX_BUFFER;
        
        // Create a VertexArray to be used by the VertexBuffer
        POSITION_ARRAY = new VertexArray(POINTS.length / 3, 3, 2);
        POSITION_ARRAY.set(0, POINTS.length / 3, POINTS);
        NORMAL_ARRAY = new VertexArray(NORMALS.length / 3, 3, 2);
        NORMAL_ARRAY.set(0, NORMALS.length / 3, NORMALS);
        INDEX_BUFFER = new TriangleStripArray(INDICES, LENGTH);

        // VertexBuffer holds references to VertexArrays that contain the positions, colors, normals, 
        // and texture coordinates for a set of vertices
        VertexBuffer vertexBuffer = new VertexBuffer();
        vertexBuffer.setPositions(POSITION_ARRAY,(1.0f/1000.0f), null);
        vertexBuffer.setNormals(NORMAL_ARRAY);
        
        // Create the 3D object defined as a polygonal surface
        Mesh mesh = new Mesh(vertexBuffer, INDEX_BUFFER, null);
        
        Appearance appearance = new Appearance(); // A set of component objects that define the rendering attributes of a Mesh
        PolygonMode polygonMode = new PolygonMode(); // An Appearance component encapsulating polygon-level attributes
        polygonMode.setPerspectiveCorrectionEnable(true);
        polygonMode.setCulling(PolygonMode.CULL_FRONT); // Use CULL_FRONT for performance
        appearance.setPolygonMode(polygonMode);

        Material material = new Material();
        material.setColor(Material.AMBIENT, 0xFFFFFF);
        material.setVertexColorTrackingEnable(true);
        appearance.setMaterial(material);
 
        mesh.setAppearance(0, appearance); // Set the appearance to the 3D object        

        return mesh;
    }
}

class VEK{
    public short X;
    public short Y;
    public short Z;

    public VEK(){
        X=Y=Z=0;
    }

    public VEK(int x, int y, int z){
        X = (short)x;
        Y = (short)y;
        Z = (short)z;
    }
    public String toString(){
        return "X=" + X + " Y=" + Y + " Z=" + Z;
    }
}

/*
 *  A few extra math methods used to create the Icosahedron
 */
class MATH{
    public static VEK vekCalculateNormal(VEK v1, VEK v2, VEK v3)  // calculate the normal for a triangle
    {
            VEK q = new VEK(v2.X - v1.X, v2.Y- v1.Y, v2.Z -v1.Z);
            VEK p = new VEK(v3.X - v1.X, v3.Y- v1.Y, v3.Z -v1.Z);
            VEK c = new VEK(p.Y*q.Z - p.Z * q.Y, p.Z*q.X - p.X*q.Z, p.X*q.Y - p.Y*q.X);
            return c;
    }

    public static double vekLength(VEK u) // return the length of the vektor
    {
            return Math.sqrt((u.X*u.X) + (u.Y*u.Y) + (u.Z*u.Z));
    }
    
    public static VEK vekNormalizeNormal(VEK u)  // Normalize a NORMAL
    {
            double length = vekLength(u);

            if(length==0){
                    u.X=u.Y=u.Z=0;
                     return u;
            }
            double a, b, c;
            a = u.X / length;
            b = u.Y / length;
            c = u.Z / length;
            a *= 127;
            b *= 127;
            c *= 127;
            u.X = (short)(a);
            u.Y = (short)(b);
            u.Z = (short)(c);
            return u;
    }

    public static VEK vekNormalizePoint(VEK u)  // Normalize a POINT
    {
            double length = vekLength(u);

            if(length==0){
                    u.X=u.Y=u.Z=0;
                     return u;
            }
            double a, b, c;
            a = u.X / length;
            b = u.Y / length;
            c = u.Z / length;
            a *= 1000;
            b *= 1000;
            c *= 1000;
            u.X = (short)(a);
            u.Y = (short)(b);
            u.Z = (short)(c);
            return u;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -