4角形ポリゴンにアルファチャネル付きテクスチャ画像を貼り付けます。

前田稔の超初心者のプログラム入門

プログラムの作成

  1. アルファチャネル付きの BMP 画像をテクスチャとして貼り付けます。
    メモ帳などでタイプして TexAlpha32.java の名前で保存して下さい。
    //★ 4角形ポリゴンにアルファ付きテクスチャを張付る    前田 稔
    import java.awt.*;
    import javax.swing.*;
    import java.io.*;
    import java.awt.image.BufferedImage;
    import javax.imageio.ImageIO;
    import javax.media.j3d.*;
    import javax.vecmath.*;
    import com.sun.j3d.utils.universe.*;
    import com.sun.j3d.utils.image.TextureLoader;
    
    public class TexAlpha32 extends JFrame
    {
        // main Method
        public static void main(String[] args)
        {   new TexAlpha32();  }
    
        // Constructor
        public TexAlpha32()
        {   // JFrame の初期化
            super("Texture Alpha BMP32");
            setSize(300,300);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            // Java3D関係の設定
            GraphicsConfiguration g_config = SimpleUniverse.getPreferredConfiguration();
            Canvas3D canvas = new Canvas3D(g_config);
            add(canvas);
    
            // SimpleUniverseを生成
            SimpleUniverse universe = new SimpleUniverse(canvas);
            universe.getViewingPlatform().setNominalViewingTransform();
    
            // シーンの生成
            BranchGroup scene = CreateScene();
            universe.addBranchGraph(scene);
            setVisible(true);
        }
    
        // テクスチャを張り付けた矩形を生成
        private BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
    
            // 矩形の座標を定義
            Point3d[] vertices =
            {  new Point3d(-0.7, -0.7, 0.0),  new Point3d( 0.7, -0.7, 0.0), // 左下,  右下
               new Point3d( 0.7,  0.7, 0.0),  new Point3d(-0.7,  0.7, 0.0)  // 右上,  左上
            };
    
            // テクスチャの座標を定義
            TexCoord2f[] txcoords =
            {  new TexCoord2f(0.0f, 0.0f),  new TexCoord2f(1.0f, 0.0f),   // 左下,  右下
               new TexCoord2f(1.0f, 1.0f),  new TexCoord2f(0.0f, 1.0f)    // 右上,  左上
            };
    
            // 色の定義(青)
            Color3f[] colors =
            {  new Color3f(0.0f, 0.0f, 1.0f), new Color3f(0.0f, 0.0f, 1.0f),
               new Color3f(0.0f, 0.0f, 1.0f), new Color3f(0.0f, 0.0f, 1.0f)
            };
    
            // 背景色を設定(緑)
            Background bg = new Background(new Color3f(0.3f, 0.7f, 0.3f));
            bg.setApplicationBounds(new BoundingSphere(new Point3d(), 100.0));
            objRoot.addChild(bg);
    
            // 矩形ポリゴンを生成(テクスチャ + Color + 属性)
            QuadArray geom = new QuadArray(vertices.length, 
                GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.TEXTURE_COORDINATE_2);
            geom.setCoordinates(0, vertices);
            geom.setTextureCoordinates(0, 0, txcoords);
            geom.setColors(0, colors);
    
            // ポリゴンにテクスチャを設定
            BufferedImage bimage = loadAlpha("C:\\DATA\\Test\\kishi32.bmp");
            Texture2D texture2d = (Texture2D)new TextureLoader(bimage, this).getTexture();
            Appearance app = new Appearance();
            app.setTexture(texture2d);
    
            // 透明度の設定
            app.setTransparencyAttributes(new TransparencyAttributes(TransparencyAttributes.BLENDED, 0.0f));
            Shape3D grid = new Shape3D(geom, app);
            grid.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
    
            // テクスチャ属性
            TextureAttributes txattr = new TextureAttributes();
            txattr.setTextureMode(TextureAttributes.DECAL);
            app.setTextureAttributes(txattr);
    
            objRoot.addChild(grid);
            return objRoot;
        }
    
        // Alpha Cannel Image の入力
        public static BufferedImage loadAlpha(String fileName)
        {   BufferedImage img= null;
            int     width;
            int     height;
            int     len;
            byte[]  buf = new byte[64];
    
            try
            {   InputStream in = new FileInputStream(fileName);
                BufferedInputStream bin = new BufferedInputStream(in);
    
                // BITMAPFILEHEADER を入力
                if ((len= bin.read(buf, 0, 14))==-1)    return null;
                if (buf[0]!='B' || buf[1]!='M')     return img; // BMP以外
    
                // BITMAPINFOHEADER を入力
                if ((len= bin.read(buf, 0, 40))==-1)    return null;
                width= byte2int(buf, 4);
                height= byte2int(buf, 8);
                int  biBitCount= (buf[14]&0xFF) | ((buf[15]<<8)&0xFF00);
                if (biBitCount!=32) return null;        // 32bit以外
                int ary[] = new int[width * height];
                byte bt[] = new byte[width * height * 4];
                if ((len= bin.read(bt, 0, width*height*4))==-1) return null;
                bin.close();
                img= new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
                cvt(bt, ary);
                for(int y=0; y<height; y++)
                {   for(int x=0; x<width; x++)
                    {   img.setRGB(x, height-y-1, ary[y*width+x]);  }
                }
            }
            catch(Exception e) { }
            return img;
        }
    
        // byte[] ⇒ int[] 変換
        public static void cvt(byte[] bt, int ary[])
        {   for(int i=0; i<ary.length; i++)
                ary[i]= byte2int(bt, i*4);
        }
    
        // byte[] ⇒ int 変換
        public static int byte2int(byte[] buf, int p)
        {   return (buf[p]&0xFF) | ((buf[p+1]<<8)&0xFF00) | ((buf[p+2]<<16)&0xFF0000) | ((buf[p+3]<<24)&0xFF000000);
        }
    }
    
  2. アルファチャネル付きの BMP 画像を作成して、テクスチャとして貼り付けます。
    矩形に色を設定しているので、テクスチャの透明部分から透けて見えます。
    矩形の色を変えてみて下さい。
    アルファチャネルが機能していることが良く解るでしょう。
            // 色の定義(黄)
            Color3f[] colors =
            {  new Color3f(1.0f, 1.0f, 0.0f), new Color3f(1.0f, 1.0f, 0.0f),
               new Color3f(1.0f, 1.0f, 0.0f), new Color3f(1.0f, 1.0f, 0.0f)
            };
        

プログラムの説明

  1. アルファチャネル付きの画像を作成するツールを開発しました。
    前田稔の超初心者のプログラム入門の「Game Program & 各種 Tool」から提供しています。
    ところが、画像は作成出来ても Java にはアルファチャネル付きでロードする方法が見つかりません。
    仕方なくアルファチャネル付き BMP 画像を入力するメソッドを自前で開発しました。
    詳細は アルファチャネル付き画像をロード を参照して下さい。
  2. アルファチャネル付きの BMP 画像をテクスチャとして矩形に貼り付けます。
    矩形の頂点座標の定義とテクスチャ座標の定義です。
    矩形ポリゴンの色を青に設定しています。
            // 矩形の座標を定義
            Point3d[] vertices =
            {  new Point3d(-0.7, -0.7, 0.0),  new Point3d( 0.7, -0.7, 0.0), // 左下,  右下
               new Point3d( 0.7,  0.7, 0.0),  new Point3d(-0.7,  0.7, 0.0)  // 右上,  左上
            };
    
            // テクスチャの座標を定義
            TexCoord2f[] txcoords =
            {  new TexCoord2f(0.0f, 0.0f),  new TexCoord2f(1.0f, 0.0f),   // 左下,  右下
               new TexCoord2f(1.0f, 1.0f),  new TexCoord2f(0.0f, 1.0f)    // 右上,  左上
            };
    
            // 色の定義(青)
            Color3f[] colors =
            {  new Color3f(0.0f, 0.0f, 1.0f), new Color3f(0.0f, 0.0f, 1.0f),
               new Color3f(0.0f, 0.0f, 1.0f), new Color3f(0.0f, 0.0f, 1.0f)
            };
        
  3. テクスチャと矩形の色と背景の色が良く分かるように背景を緑に設定しました。
            // 背景色を設定(緑)
            Background bg = new Background(new Color3f(0.3f, 0.7f, 0.3f));
            bg.setApplicationBounds(new BoundingSphere(new Point3d(), 100.0));
            objRoot.addChild(bg);
        
  4. QuadArray で色を設定した矩形ポリゴンにテクスチャを貼り付けます。
    COLOR_3 が色の設定で、TEXTURE_COORDINATE_2 がテクスチャの設定です。
    透明度を設定(TransparencyAttributes)するとアルファチャネルが有効になります。
    Shape3D に ALLOW_GEOMETRY_READ を許可して下さい。
    テクスチャ属性を設定するときに必要です。
            // 矩形ポリゴンを生成(テクスチャ + Color + 属性)
            QuadArray geom = new QuadArray(vertices.length, 
                GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.TEXTURE_COORDINATE_2);
            geom.setCoordinates(0, vertices);
            geom.setTextureCoordinates(0, 0, txcoords);
            geom.setColors(0, colors);
    
            // ポリゴンにテクスチャを設定
            BufferedImage bimage = loadAlpha("C:\\DATA\\Test\\kishi32.bmp");
            Texture2D texture2d = (Texture2D)new TextureLoader(bimage, this).getTexture();
            Appearance app = new Appearance();
            app.setTexture(texture2d);
            // 透明度の設定
            app.setTransparencyAttributes(new TransparencyAttributes(TransparencyAttributes.BLENDED, 0.0f));
            Shape3D grid = new Shape3D(geom, app);
            grid.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
        
  5. TextureAttributes でテクスチャ属性を設定します。
    DECAL を設定するとテクスチャの透明部分から矩形の色が透けて見えます。
            // テクスチャ属性
            TextureAttributes txattr = new TextureAttributes();
            txattr.setTextureMode(TextureAttributes.DECAL);
            app.setTextureAttributes(txattr);
        
  6. アルファチャネル付き BMP 画像のロードは アルファチャネル付き画像をロード を参照して下さい。

超初心者のプログラム入門(Java2)