#FF0000 12  2007 - #000655 JSR-184 -    (world)  
#def       3D   ,  JSR-184.        .          .     -  3D   Image2D        .            ,   () .    -   ,  3D . 
          (world). 
       Image2D.     Image2D     Mesh .      . 
   Image2D
texg3d.bindTarget(sceneTexture); //   Image2D 
texg3d.render(texWorld); //     Image2D
g3d.bindTarget(g); // ,  Image2D      Graphics3D
g3d.render(world); //   
         (2, 4, 8, 16, 32, 64, 128, 256). 
sceneTexture = new Image2D(Image2D.RGB, 64, 64); 
 Image2D    
   Image2D         . 
 sceneTexture     texture1 ,  sceneTexture     .  ,    . 
  
    (46 kB) 
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.m3g.*;
import javax.microedition.m3g.Camera;
import javax.microedition.lcdui.game.*;

import java.util.*;

public class map3DTexture extends MIDlet {

    private Display d;
    private mapTextureCanvas mapTextureCanvas;

    public map3DTexture(){
        mapTextureCanvas = new mapTextureCanvas(this);
        d = Display.getDisplay(this);
        d.setCurrent(mapTextureCanvas);
    }

    public void startApp() {
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }
}

class mapTextureCanvas extends GameCanvas implements Runnable{

    private MIDlet midlet;

    private Graphics3D g3d; //     .
    private World world; //     .
    private Camera camera; //   
    private Mesh plane; // 

    private Graphics3D texg3d;
    private Mesh texMesh;
    private World texWorld; //        Image2D
    private Camera texCamera;
    private Image2D sceneTexture = null; // 3D   
    private Texture2D texture; //   

    private void doTexture(){
        
        sceneTexture = new Image2D(Image2D.RGB, 64, 64);

        texg3d = Graphics3D.getInstance();
        texWorld = new World();
        
        texCamera = new Camera();
        texWorld.addChild(texCamera); //    

        float w = getWidth();
        float h = getHeight();

        texCamera.setPerspective(60.0f, w / h, 0.1f, 150f);
        texWorld.setActiveCamera(texCamera);

        Background bg = new Background();
        try{
            Image texImg = Image.createImage("/bgImage.png");
            bg.setImage(new Image2D(Image2D.RGB, texImg));
        }catch(Exception e){}

        texWorld.setBackground(bg);

        texMesh = createpyramid();
        texMesh.postRotate(45.0f, 0.5f, 1.0f, 0.0f);
        texMesh.translate(0.0f, 0.0f, -5.0f);
        texWorld.addChild(texMesh);
    }
    
    public mapTextureCanvas(MIDlet m){
        super(false);

        midlet = m;
        setFullScreenMode(true);
        
        doTexture();
        
        g3d = Graphics3D.getInstance();
        world = new World();

        camera = new Camera();
        world.addChild(camera); //    .

        float w = getWidth();
        float h = getHeight();

        //          .
        camera.setPerspective(60.0f, w / h, 0.1f, 150f);
        camera.translate(0.0f, 0.0f, 0.0f);
        world.setActiveCamera(camera);

        plane = createPlane();
        world.addChild(plane);
        plane.translate(0.0f, 0.0f, -5.0f);
        Background bg = new Background();
        bg.setColor(0x000000);
        world.setBackground(bg);

        Thread t = new Thread(this);
        t.start(); 
    }

    public void draw3D(Graphics g){

        try{
            texg3d.bindTarget(sceneTexture); //  Image2D   
            texg3d.render(texWorld); //     Image2D
        }finally{
            texg3d.releaseTarget();
        }

        try{
            g3d.bindTarget(g); // ,  Image2D      Graphics3D
            g3d.render(world); //   
        }finally{
            g3d.releaseTarget();
        }
    }

    private void draw2D(Graphics g){
        g.setColor(0xFFFFFF);
        g.drawString("Exit", 3, getHeight(), Graphics.LEFT | Graphics.BOTTOM);
    }

    protected void keyPressed(int key){

        switch(key){
            case - 3:
                break;
            case -4:
                break;
            case -6:
                midlet.notifyDestroyed();
                break;
            case -7:
                break;
        }
    }

    public void run() {
        Graphics g = getGraphics();

        while(true){

            texMesh.postRotate(3.0f, 0.0f, 1.0f, 0.0f); // rotate the pyramid
            plane.postRotate(3.0f, 0.0f, 1.0f, 0.0f); // rotate the plane
            draw3D(g);
            draw2D(g);
            flushGraphics();

            try{
                Thread.sleep(10);
            }catch(Exception e){}
        }
    }


    public Mesh createPlane(){
        int WIDTH = 21, HEIGHT = 2;

        short POINTS[] = new short[] {-1, -1, 0,
                                       1, -1, 0,
                                       1, 1, 0,
                                       -1, 1, 0};

        short TEXTURES[] = new short[] {0, 255,
                                         255, 255,
                                         255, 0,
                                         0, 0};

        int INDICES[] = new int[] {0, 1, 3, 2};
        int[] LENGTHS = new int[] {4};
        
        VertexArray POSITIONS_ARRAY, TEXTURE_ARRAY, COLOR_ARRAY;
        IndexBuffer INDEX_BUFFER;

        //   
        POSITIONS_ARRAY = new VertexArray(POINTS.length/3, 3, 2);
        POSITIONS_ARRAY.set(0, POINTS.length/3, POINTS);
        TEXTURE_ARRAY = new VertexArray(TEXTURES.length / 2, 2, 2);
        TEXTURE_ARRAY.set(0, TEXTURES.length / 2, TEXTURES);
        INDEX_BUFFER = new TriangleStripArray(INDICES, LENGTHS);

        VertexBuffer vertexBuffer = new VertexBuffer();
        vertexBuffer.setPositions(POSITIONS_ARRAY, 1.0f, null);
        vertexBuffer.setTexCoords(0, TEXTURE_ARRAY, 1.0f/255.0f, null);
        Mesh mesh = new Mesh(vertexBuffer, INDEX_BUFFER, null);

        Appearance appearance = new Appearance();
        PolygonMode pm = new PolygonMode();
        pm.setCulling(PolygonMode.CULL_NONE);
        appearance.setPolygonMode(pm);

        Image texImg;
        try{
            Texture2D texture1 = new Texture2D(sceneTexture);
            texture1.setBlending(Texture2D.FUNC_REPLACE);
            texture1.setWrapping(Texture2D.WRAP_CLAMP, Texture2D.WRAP_CLAMP);
            texture1.setFiltering(Texture2D.FILTER_NEAREST, Texture2D.FILTER_NEAREST);

            appearance.setTexture(0, texture1);

        }catch(Exception e){
            System.out.println("Failed to create texture");
        }

        mesh.setAppearance(0, appearance);

        return mesh;
    }

    private Mesh createpyramid(){

        //    . x, y, z
        short []POINTS = new short[] {-1, -1, 1, 1, -1, 1, 0, 1, 0, //  
                                       1, -1, 1, 1, -1, -1, 0, 1, 0, // 
                                       1, -1, -1, -1, -1, -1, 0, 1, 0, // 
                                      -1, -1, -1, -1, -1, 1, 0, 1, 0, // 
                                      -1, -1, 1, 1, -1, 1, 1, -1, -1, //  
                                      -1, -1, 1, 1, -1, -1, -1, -1, -1}; //  

        //      setTextCoords ,     0  1
        short []TEXTURES = new short[] {0, 255, 255, 255, 127, 0,
                                        0, 255, 255, 255, 127, 0,
                                        0, 255, 255, 255, 127, 0,
                                        0, 255, 255, 255, 127, 0,
                                        0, 0, 255, 0, 255, 255,
                                        0, 0, 255, 255, 0, 255};
                                                            
        //   ,  .
        int []INDICES = new int[] {0, 1, 2, //  
                                   3, 4, 5, // 
                                   6, 7, 8, // 
                                   9, 10, 11, // 
                                   12, 13, 14, //  
                                   15, 16, 17}; //  

        //      .
        int []LENGTH = new int[] {3, 3, 3, 3, 3, 3}; //    
        VertexArray POSITION_ARRAY, TEXTURE_ARRAY;
        IndexBuffer INDEX_BUFFER;

        // v VertexArray,   VertexBuffer
        POSITION_ARRAY = new VertexArray(POINTS.length / 3, 3, 2);
        POSITION_ARRAY.set(0, POINTS.length / 3, POINTS);
        TEXTURE_ARRAY = new VertexArray(TEXTURES.length / 2, 2, 2);
        TEXTURE_ARRAY.set(0, TEXTURES.length / 2, TEXTURES);
        INDEX_BUFFER = new TriangleStripArray(INDICES, LENGTH);

        // VertexBuffer     VertexArrays,     , , ,      .
        VertexBuffer vertexBuffer = new VertexBuffer();
        vertexBuffer.setPositions(POSITION_ARRAY, 1.0f, null);
        vertexBuffer.setTexCoords(0, TEXTURE_ARRAY, (1.0f/255.0f), null);
        vertexBuffer.setTexCoords(1, TEXTURE_ARRAY, (1.0f/255.0f), null);
        //   
        Mesh mesh = new Mesh(vertexBuffer, INDEX_BUFFER, null);

        Appearance appearance = new Appearance(); //   ,    
        PolygonMode polygonMode = new PolygonMode(); polygonMode.setPerspectiveCorrectionEnable(true);
        polygonMode.setCulling(PolygonMode.CULL_BACK); //  CULL_BACK (  )    
appearance.setPolygonMode(polygonMode);

        Image texImg;
        try{
            texImg = Image.createImage("/texture2.png");
            texture = new Texture2D(new Image2D(Image2D.RGB, texImg));
            texture.setWrapping(Texture2D.WRAP_CLAMP, Texture2D.WRAP_CLAMP);
            texture.setBlending(Texture2D.FUNC_MODULATE);
            texture.setFiltering(Texture2D.FILTER_NEAREST, Texture2D.FILTER_NEAREST);

            appearance.setTexture(0, texture); 
        }catch(Exception e){
            System.out.println("Failed to create texture");
        }

        mesh.setAppearance(0, appearance); //    3D 
        return mesh;
    }