7,671 views
この記事は最終更新から 2628日 が経過しています。
1. やりたいこと
(10) OpenGL ESのミニマム実装 では、OpenGLで作った Viewに直線を引いてみた。
今回は…
OpenGLで作った Viewに画像を表示したい!
2. やってみる!
(1) 表示する画像を選定する。
いらすとやさんからサッカーボールの画像をダウンロードさせていただいた。

ボールにしたのは、いつか画面上を転がしてみようと思ったので。
(2) Android Studioのプロジェクトにボール画像をリソース登録する。
上記(1)で入手した画像ファイルを res/drawable に登録する。

(3) プログラムを書く。
解説は後回しにして作ったプログラムを貼り付けておく。
1) MainActivity
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
MyGLView m_glView;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
m_glView = new MyGLView(this);
setContentView(m_glView);
}
@Override protected void onPause() {
super.onPause();
m_glView.onPause();
}
@Override protected void onResume() {
super.onResume();
m_glView.onResume();
}
}
2) MyGLView
import android.content.Context;
import android.opengl.GLSurfaceView;
public class MyGLView extends GLSurfaceView {
private MyGLRenderer m_renderer;
public MyGLView(Context context){
super(context);
m_renderer = new MyGLRenderer(context);
setRenderer(m_renderer);
}
}
3) MyGLRenderer
import android.content.Context;
import android.opengl.GLSurfaceView;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class MyGLRenderer implements GLSurfaceView.Renderer {
private Context m_context; // アプリのコンテキスト
private MyGLPic m_pic; // 表示画像
public MyGLRenderer( Context context ){
m_context = context;
}
@Override public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glDisable(GL10.GL_DITHER); // 機能無効化 : ディザリング
gl.glEnable(GL10.GL_DEPTH_TEST); // 機能有効化 : 隠面消去用 Depth Buffer更新
gl.glEnable(GL10.GL_TEXTURE_2D); // 機能有効化 : 2Dテクスチャ
gl.glEnable(GL10.GL_ALPHA_TEST); // 機能有効化 : アルファテスト(αチャネルによる画素の有効/無効判定)
gl.glEnable(GL10.GL_BLEND); // 機能有効化 : ブレンド(画像の重ね合わせ)
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); // カラーブレンド(画像重ね合わせ)モード : アルファブレンド
// 描画する画像をリソースから取得
m_pic = new MyGLPic();
m_pic.SetTexture(gl, m_context.getResources(), R.drawable.ball);
}
@Override public void onSurfaceChanged(GL10 gl, int width, int height) {
}
@Override public void onDrawFrame(GL10 gl) {
// 描画用バッファをクリア
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
m_pic.Draw(gl); // 画像を描画
}
}
4) MyGLPic
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import javax.microedition.khronos.opengles.GL11Ext;
public class MyGLPic {
protected int m_textureNo;
protected float m_width, m_height; // 画像の表示幅と高さ
protected int m_crop_x, m_crop_y; // テクスチャ切り出し左上オフセット座標
protected int m_crop_w, m_crop_h; // テクスチャ切り出し幅と高さ
protected float m_pos_x, m_pos_y, m_pos_z; // テクスチャ表示位置
public MyGLPic(){
m_textureNo = 0;
}
// 本インスタンスに画像をロード
public void SetTexture( GL10 gl, Resources res, int id ) {
InputStream is = res.openRawResource(id);
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(is);
} finally {
}
try {
is.close();
} catch (IOException e) {
Log.d("MyGLPic", "Can't load resource.");
}
gl.glEnable(GL10.GL_ALPHA_TEST);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
// 下地色とテクスチャ色との合成方法 : 乗算
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE);
// テクスチャIDを割り当て
int[] ary_textureNo = new int[1];
gl.glGenTextures(1, ary_textureNo, 0);
m_textureNo = ary_textureNo[0];
// テクスチャIDをバインドし、データとIDを関連付ける。
gl.glBindTexture(GL10.GL_TEXTURE_2D, m_textureNo);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
// ポリゴン内の画像の繰り返し指定 S軸、T軸ともに繰り返しなし。
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE );
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE );
// テクスチャのリサンプリングアルゴリズム指定
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR );
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR );
// 表示座標設定
int img_w = bitmap.getWidth();
int img_h = bitmap.getHeight();
SetPos(0, img_h, img_w, -img_h,0, 0, 0, img_w, img_h);
}
//テクスチャ表示サイズ、表示位置情報をセット
public void SetPos( int crop_x,int crop_y,int crop_w,int crop_h, float pos_x, float pos_y, float pos_z, float disp_w, float disp_h ){
m_crop_x = crop_x;
m_crop_y = crop_y;
m_crop_w = crop_w;
m_crop_h = crop_h;
m_pos_x = pos_x;
m_pos_y = pos_y;
m_pos_z = pos_z;
m_width = disp_w;
m_height = disp_h;
}
public void Draw( GL10 gl ){
gl.glDisable(GL10.GL_DEPTH_TEST); // デプステストOFF
// 表示するテクスチャをバインド
gl.glActiveTexture(GL10.GL_TEXTURE0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, m_textureNo);
// テクスチャから指定部分を切り出して表示
int rect[] = {m_crop_x, m_crop_y, m_crop_w, m_crop_h};
((GL11)gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, rect, 0);
((GL11Ext) gl).glDrawTexfOES(m_pos_x, m_pos_y, m_pos_z, m_width, m_height);
gl.glEnable(GL10.GL_DEPTH_TEST); // デプステストOFFON
}
}
上記のプログラムを実機上で動かしたときのスクリーンショットがこちら。

近いうちにこのボールを動かしてみたい。
3. 所感
・いろいろと手続きが多くて、見よう見まねで動かしただけって感じだ。
・ライブラリを使わせていただくのだから、ライブラリの都合に合わせるしかない。
・手続きがこれで必要十分なのかは不明… 今後わかったことを追記して行こう。
4. 参考情報
ありがとうございます。 m(_ _)m
http://www.web-sky.org/program/opengl/opengl03.html
http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20040917
アクセス数(直近7日): ※試験運用中、BOT除外簡易実装済2025-12-14: 1回 2025-12-13: 0回 2025-12-12: 1回 2025-12-11: 0回 2025-12-10: 0回 2025-12-09: 3回 2025-12-08: 1回