質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • Android Studio

    4300questions

    Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

立方体に複数のimageをテクスチャマッピングしたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 983
退会済みユーザー

退会済みユーザー

今立体のすべての面に一つの画像をテクスチャマッピングしているのですが、複数の画像を張り付けたいと思っています。
もし複数のテクスチャを

textureId = loadTexture(gl, r, R.drawable.one);


のほかに使いたいときは

textureId = loadTexture(gl, r, R.drawable.one);

textureId = loadTexture(gl, r, R.drawable.two);


と入れればよいのでしょうか?

class Cube {
    //各バッファの接点
    private FloatBuffer mVertexBuffer;
    private FloatBuffer mNormalBuffer;
    private ShortBuffer mIndexBuffer;
    private FloatBuffer mTextureBuffer;
    // 接続する頂点の配列数
    private int numberOfindex = 36;
    //テクスチャの管理id
    private int textureId;

    //角度
    private float angle = 0f;

    public Cube(GL10 gl, Resources r) {
        float x = 2f;
        float y = 2f;
        float z = 0.1f;

        //頂点
        float[] vertices = {
                x, y, z,  -x, y, z,  -x,-y, z,   x,-y, z,  // v0-v1-v2-v3 front
                x, y, z,   x,-y, z,   x,-y,-z,   x, y,-z,  // v0-v3-v4-v5 right
                x, y, z,   x, y,-z,  -x, y,-z,  -x, y, z,  // v0-v5-v6-v1 top
                -x, y, z,  -x, y,-z,  -x,-y,-z,  -x,-y, z,  // v1-v6-v7-v2 left
                -x,-y,-z,   x,-y,-z,   x,-y, z,  -x,-y, z,  // v7-v4-v3-v2 bottom
                x,-y,-z,  -x,-y,-z,  -x, y,-z,   x, y,-z   // v4-v7-v6-v5 back
        };
        //テクスチャUV座標
        float[] textures = {
                1, 0,   0, 0,   0, 1,   1, 1,  // v0-v1-v2-v3 front
                0, 0,   0, 1,   1, 1,   1, 0,  // v0-v3-v4-v5 right
                0, 1,   1, 1,   0, 0,   1, 0,  // v0-v5-v6-v1 top
                1, 0,   0, 0,   0, 1,   1, 1,  // v1-v6-v7-v2 left
                0, 1,   1, 1,   1, 0,   0, 0,  // v7-v4-v3-v2 bottom
                0, 1,   1, 1,   1, 0,   0, 0   // v4-v7-v6-v5 back
        };

        //法線ベクトル 表面と裏面どちらを向いているか
        float[] normals = {
                0, 0, 1,   0, 0, 1,   0, 0, 1,   0, 0, 1,   // v0-v1-v2-v3 front
                1, 0, 0,   1, 0, 0,   1, 0, 0,   1, 0, 0,   // v0-v3-v4-v5 right
                0, 1, 0,   0, 1, 0,   0, 1, 0,   0, 1, 0,   // v0-v5-v6-v1 top
                -1, 0, 0,  -1, 0, 0,  -1, 0, 0,  -1, 0, 0,   // v1-v6-v7-v2 left
                0,-1, 0,   0,-1, 0,   0,-1, 0,   0,-1, 0,   // v7-v4-v3-v2 bottom
                0, 0,-1,   0, 0,-1,   0, 0,-1,   0, 0,-1    // v4-v7-v6-v5 back
        };

        short indices[] = {
                0, 1, 2,   0, 2, 3,   // front
                4, 5, 6,   4, 6, 7,   // right
                8, 9,10,   8,10,11,   // top
                12,13,14,  12,14,15,   // left
                16,17,18,  16,18,19,   // bottom
                20,21,22,  20,22,23    // back
        };


        // Vertex
        mVertexBuffer = makeFloatBuffer(vertices);

        //Normal
        mNormalBuffer = makeFloatBuffer(normals);

        // index
        mIndexBuffer = makeShortBuffer(indices);

        // texture
        mTextureBuffer = makeFloatBuffer(textures);

        textureId = loadTexture(gl, r, R.drawable.one);
    }


    //システム上のメモリ領域を確保するためのメソッド
    // Float用
    public static final FloatBuffer makeFloatBuffer(float[] arr) {
        ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);
        bb.order(ByteOrder.nativeOrder());
        FloatBuffer fb = bb.asFloatBuffer();
        fb.put(arr);
        fb.position(0);
        return fb;
    }

    //システム上のメモリ領域を確保するためのメソッド
    //Short用
    public static final ShortBuffer makeShortBuffer(short[] arr) {
        ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);
        bb.order(ByteOrder.nativeOrder());
        ShortBuffer fb = bb.asShortBuffer();
        fb.put(arr);
        fb.position(0);
        return fb;
    }

    //描画
    public void draw(GL10 gl) {
        //ここではz軸方向に -3.0だけ移動させます.
        gl.glTranslatef(0, 0, -30.0f);

        //マトリクスの回転
        gl.glRotatef(angle++, 0, 1, 0);

        //テクスチャ機能の有効化
        gl.glEnable(GL10.GL_TEXTURE_2D);
        //テクスチャオブジェクトの指定
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);

        // 頂点のポインタを設定
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);

        //法線ベクトルの指定
        gl.glNormalPointer(GL10.GL_FLOAT,0,mNormalBuffer);
        gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

        //テクスチャのポインタを設定
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);

        // 頂点の描画
        // gl.glDrawElements( プリミティブ, 頂点の数, タイプ, インデックス)
        gl.glDrawElements(GL10.GL_TRIANGLES, numberOfindex, GL10.GL_UNSIGNED_SHORT, mIndexBuffer);

    }
    /**
     * テクスチャを読み込む.
     * 読み込む画像のサイズは2の階乗の値でなければならない.
     */
    public static final int loadTexture(GL10 gl, Resources r, int resId) {
        int[] textures = new int[1];

        //読み込むBitmapのオプションの設定
        BitmapFactory.Options options = new BitmapFactory.Options();
        //リソースの自動リサイズをしない
        options.inScaled = false;
        // 32bit画像として読み込む
        options.inPreferredConfig = Config.ARGB_8888;
        //Bitmapの作成
        Bitmap bmp = BitmapFactory.decodeResource(r, resId, options);
        if (bmp == null) {
            return 0;
        }

        // OpenGL用のテクスチャを生成する
        gl.glGenTextures(1, textures, 0);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);

        //OpenGLへの転送が完了したので、VMメモリ上に作成したBitmapを破棄する
        bmp.recycle();

        return textures[0];
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

3Dにおけるテクスチャの考え方ですが、テクスチャとはモデルを一枚の革のようにバラバラに展開したときに、それぞれどの部分がどんな模様になるかを描いたものがテクスチャです。サイコロで例えるなら、モデルはプラスチックの立方体、テクスチャはサイコロの展開図になります。つまり、サイコロ1個に対しテクスチャは1枚であり、6枚のシールのようにペタペタそれぞれの面に貼るものではありません。
それをやるためにはglTexSubImage2Dという関数がよく使われます。1つのテクスチャオブジェクトに対し、ここからここまでの領域にaの画像、ここからここまでの領域にbの画像、cの画像、dの画像…と割り当てる処理です。
1枚のからっぽのテクスチャを用意しておき、6枚の画像をサイコロの展開図のようにテクスチャ上に貼り付けていけば、1枚のテクスチャで6面すべての画像を表現できます。
参考:http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20050610

補足しておくと、OpenGLはマルチテクスチャに対応していますが、それは6面それぞれにペタペタ貼るためではなく、何枚も「重ねて」表示するためのものです。サイコロの目が書いてあるテクスチャ、凹凸の表現が書いてあるテクスチャ、透明度を表すテクスチャなどを重ねて、複合した見た目を持たせるためのマルチテクスチャです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/01 10:53

    なるほど。私の考え方が間違っていたようですね

    キャンセル

  • 2017/02/01 10:59 編集

    やり方によっては6枚のバラバラのテクスチャを1面ずつ使うというやり方もできなくはないですが、GPU上のメモリの無駄遣いですし、テクスチャのサンプリング処理も6回走ることになるので、非常に非効率です。1枚のテクスチャ上に6枚の画像を並べて使う上記のやり方にしたほうがよいでしょう。床井研究室のOpenGL関連の記事は非常にわかりやすく、参考になりますよ。興味があれば他のページも一読してみてください。

    キャンセル

  • 2017/02/01 11:09

    参考のページのコードを全文読みたいのですがandroidstudioに使えるのはwindows版を見るのでしょうか?

    キャンセル

  • 2017/02/01 11:13

    床井研究室はWindows(というよりC言語)のOpenGLを扱っています。Androidにそのままコードが使えるわけではありませんが、GLの関数、定数名などはそのままAndroidでも同じはずなので、頭の中で置換えて読むしかありません。床井研究室の記事は、ソースコードよりもそれぞれのOpenGLの機能に関する説明や挿絵の充実ぶりが魅力なので、コピペでやりたいのであれば別のサイトを探したほうがよいでしょう…

    キャンセル

  • 2017/02/01 11:16

    はい、わかりました。ありがとうございます

    キャンセル

  • 2017/02/01 11:18

    基礎はしっかりしているようなので、がんばってくださいねー。

    キャンセル

同じタグがついた質問を見る

  • Android Studio

    4300questions

    Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。