パスワードを忘れた? アカウント作成
15275547 journal
Java

wuzhiの日記: JOGLでマルチテクスチャ

日記 by wuzhi

五月連休.フィールドアスレチック や 神社参拝,川沿い遊歩道散策をしつつも,いつもの 3Dプログラミング.

ここ数日は,JOGL (Java OpenGL) のマルチテクスチャ処理のプログラミングをしていた.
https://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20050615
https://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/index.html?index-all.html
等を参考に.(なお,ここで言うマルチテクスチャ(複数テクスチャ)とは,一つの3Dモデルに対して,複数(種)のテクスチャを同時に適用すること.)

今回のお試しでは,ベースの teapot モデルに対して,チェック の テクスチャ と スフィアマップ のテクスチャを適用している.

複数テクスチャの内の一つ,スフィアマップのテクスチャは,こちらを拝借した.
https://seiga.nicovideo.jp/seiga/im8123098

もう一つの,チェック テクスチャは,ネットでパッと適当なものが見つからず,しかし簡単なものなので,GIMP で自作した.
https://commons.nicovideo.jp/material/nc241930

以下,模擬コード.(所々,省略している)

GLUT glut = new GLUT();

//JOGLの場合,このinit(...)にて色々と初期化処理が要る
final public void init(final GLAutoDrawable drawable){
        gl = drawable.getGL().getGL2(); //GLを取得しておく
        textureCheck = TextureIO.newTexture(new File("check.png"), true); //ファイルオープンと,glTexImage2D(...)に相当することをやってくれる,JOGL のAPI
        textureSphereMap = TextureIO.newTexture(new File("spheremap.png"), true);
        ...
}

//JOGLの場合,このdisplay(...)内にて描画処理を呼ぶ
final public void display(final GLAutoDrawable drawable) {
        ...
        gl.glActiveTexture(GL.GL_TEXTURE0);
        textureCheck.enable(gl); // glEnable(textureCheck.getTarget()); と同じ.なお,ここで言うgetTarget()のtargetとは,GL_TEXTURE_2D や GL_TEXTURE_RECTANGLE_ARB のこと.
        textureCheck.bind(gl); // glBindTexture(textureCheck.getTarget(), texture.getTextureObject()); と同じ.
                                                          // なお,ここで言う getTextureObject() の object とは,言わば読み込んだテクスチャ画像一つ一つに割り振られる識別子のよーな物で,テクスチャユニットとは別のもの!

        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT); // テクスチャの張り付け方を指定(横方向)
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT); // 同上(縦)

        gl.glActivateTexture(GL.GL_TEXTURE1); // テクスチャ ユニット1に切り換える!
        textureSphereMap.enable(gl);
        textureSphereMap.bind(gl);

        gl.glTexEnvi(GL2ES1.GL_TEXTURE_ENV, GL2ES1.GL_TEXTURE_ENV_MODE, GL2ES1.GL_MODULATE); // 今回拝借しているテクスチャファイルは "乗算"スフィアマップなので,このように指定
        gl.glTexGeni(GL2.GL_S, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_SPHERE_MAP); // スフィアマップの場合の指定(横)
        gl.glTexGeni(GL2.GL_T, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_SPHERE_MAP); // 同上(縦)
        gl.glEnable(GL2.GL_TEXTURE_GEN_S);//テクスチャ座標の自動生成を有効にする
        gl.glEnable(GL2.GL_TEXTURE_GEN_T);//テクスチャ座標の自動生成を有効にする

        glut.glutSolidTeapot(1.0); // 描画

        gl.glDisable(GL2.GL_TEXTURE_GEN_S);//テクスチャ座標の自動生成を無効にする
        gl.glDisable(GL2.GL_TEXTURE_GEN_T);//テクスチャ座標の自動生成を無効にする

        gl.glActiveTexture(GL.GL_TEXTURE0); // 元(デフォルト)のテクスチャ ユニットに戻しておく

        ... // 後略
}

一連の結果(テクスチャを適用したりしなかったり)が,以下の画像.
https://seiga.nicovideo.jp/seiga/im10739204

今回は少し手こずった…
今回のお試しでは,GLSLシェーダ による処理は未だ行っていない.
今回の処理を踏み台に,GLSLシェーダに対して複数テクスチャ(スフィアマップだけでなく,BumpマップやNormalマップ等)や時刻データ等を渡せば,その先の本当にやりたかったことの一つができる筈.

typodupeerror

吾輩はリファレンスである。名前はまだ無い -- perlの中の人

読み込み中...