FC2ブログ

Entries

OpenGL その2b GLSurfaceViewを追い出す(そして高速化)

SDK15r3

ソースコード

今までのコードだと、初期生成するActivityに全部コードを書くことになりあまり美しくありません。
またレイアウトXMLが使えないので別クラスにしてみました。

異なる点としてまずレイアウトXMLのmain.xmlを以下のようにしています。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<!-- 点描画Class -->
<test.sample.TS_OpenGL_02b.dotClass
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
/>

</FrameLayout>


GLSurfaceViewを拡張したdotClassをViewの1つとして登録しています。
ButtonもGLSurfaceViewもViewの一種のためこのようなことが可能になっています。

dotClass.javaはそのまま載せます

public class dotClass extends GLSurfaceView implements GLSurfaceView.Renderer{
private int dispWidth = 0;
private int dispHeight = 0;
private static Random rand = new Random();
private int one = 0x10000; // 固定小数点で=1
private int pointNum = 1000; // 描画数

public dotClass( Context ctx){
super( ctx );
Init(); // 初期化
}
public dotClass( Context ctx, AttributeSet attrs){
super( ctx, attrs );
Init(); // 初期化
}

// 初期化
private void Init(){
// レンダラーの指定
this.setRenderer( this );
}

// 画面初期化
public void onSurfaceCreated( GL10 gl, EGLConfig config ){
gl.glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); // サーフェイスクリア色の指定 RGBA

gl.glShadeModel( GL10.GL_FLAT ); // フラットシェーディング

gl.glHint( GL10.GL_POINT_SMOOTH_HINT, GL10.GL_FASTEST ); // 補完精度を速度優先に変更

gl.glEnableClientState( GL10.GL_VERTEX_ARRAY ); // 頂点配列の許可
gl.glEnableClientState( GL10.GL_COLOR_ARRAY ); // 色情報配列の許可
gl.glDisable( GL10.GL_TEXTURE_2D ); // テクスチャは使わない
}


// サーフェース変更
public void onSurfaceChanged( GL10 gl, int width, int height ){
// 画面サイズの記憶
dispWidth = width;
dispHeight = height;

gl.glViewport( 0, 0, width, height ); // ビューポートの再セット

// 射影行列の指定
gl.glMatrixMode( GL10.GL_PROJECTION ); // 射影行列(プロジェクションモード)
gl.glLoadIdentity(); // 単位行列のセット
GLU.gluOrtho2D( gl, 0.0f, width, 0.0f, height ); // 投影変換(画面左下を(0,0)としたクリッピング設定)

}


// 描画
public void onDrawFrame( GL10 gl ){
gl.glClear( GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT ); // 描画バッファクリア&背景塗りつぶし

int x = 0;
int y = 0;
int i = 0,j=0;
int vertex[] = new int[pointNum * 2];
int color[] = new int[pointNum * 4];

// pointNum個ほど描いてみる
for( i=0 ; i<pointNum ; i++ ){
if( dispWidth != 0 ){
x = rand.nextInt(dispWidth);
}
if( dispHeight != 0 ){
y = rand.nextInt(dispHeight);
}
vertex[i*2] = x * 0x10000; // 固定小数点
vertex[i*2+1] = y * 0x10000; // 固定小数点

for( j=0 ; j<4 ; j++ ){
color[i*4 + j] = one;
}
}
drawPoint( gl, vertex, color, 5 );
try{
Thread.sleep( 17 );
} catch ( InterruptedException e ){
}
// System.gc(); // ガベコレ対策&sleep代わり
}

// 点描画
private void drawPoint( GL10 gl, int[] vertex, int[] color, int size ){
gl.glPointSize( size ); // 描画サイズをsizeにする
gl.glVertexPointer( 2, GL10.GL_FIXED, 0, getIntBuffer( vertex ) ); // 表示座標のセット
gl.glColorPointer( 4, GL10.GL_FIXED, 0, getIntBuffer( color ) ); // カラーのセット
gl.glDrawArrays( GL10.GL_POINTS, 0, pointNum ); // pointNumだけ描画する
}

// Intバッファの生成
private IntBuffer getIntBuffer( int[] table ) {
ByteBuffer bb = ByteBuffer.allocateDirect( table.length * 4 ); // まずはByteBufferを確保
bb.order( ByteOrder.nativeOrder() ); // オーダータイプの設定
IntBuffer ib = bb.asIntBuffer(); // IntBufferをByteBufferサイズから確保
ib.put( table ); // IntBufferに押し込む
ib.position( 0 ); // IntBufferの位置を先頭に
return ib;
}
}


必ず行うこととしてコンストラクタの部分でRendererを決めなければならないので
「implements GLSurfaceView.Renderer」して、Init内でsetRendererを実行しています。

あとはその2aと大体同じですが、点の座標をバッファに入れてから
一度だけ描画命令をするように変更しました。これで点を1000個表示してもフレーム落ちすることはなくなりました
#前のやり方が悪いだけなんですけどね…
opengl_02b.png
スポンサーサイト



コメント

[C9] 承認待ちコメント

このコメントは管理者の承認待ちです

コメントの投稿

コメントの投稿
管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://android20092009.blog67.fc2.com/tb.php/27-478ccf0f
この記事にトラックバックする(FC2ブログユーザー)

Appendix

プロフィール

Ukai2009

Author:Ukai2009
FC2ブログへようこそ!

最新記事

検索フォーム

ブロとも申請フォーム

この人とブロともになる

QRコード

QRコード