スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Android覚え書き

こんにちは
未だ陸に上がってる航海士ペチコです

【TDU2】Ferrari California

本日未明、岸に打ち上げられた謎のフェラーリカルフォルニアです
全然謎じゃないですね。砂噛むと色々大変ですね



今回は別クラスからメインアクティビティのview操作
ええ、まだ基礎から抜け出せないおばかペチコのための覚え書きです



main1
グラフィカルレイアウトのxmlでこういうtextviewとbuttonだけの簡単な画面を作って


メインアクティビティで別クラスBtnTestを呼び出すだけ
MainActivity.java

package com.example.helloworld01;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//ボタンのインスタンス
Button btn = (Button)findViewById(R.id.button1);
//イベントリスナーに別クラスを指定(コンテキストはメインを渡す)
btn.setOnClickListener(new BtnTest(this));
}

}



BtnTestクラス
BtnTest.java

package com.example.helloworld01;

import android.content.Context;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class BtnTest implements OnClickListener {

private Context context;

BtnTest(Context c){
//コンテキスト(メイン)の受け取り
context = c;
}

@Override
public void onClick(View v) {
//インスタンスをメインコンテキストから取得
TextView txv = (TextView)((MainActivity) context).findViewById(R.id.textView1);
txv.setText("でも航海してません");
Button btn = (Button)((MainActivity) context).findViewById(R.id.button1);
btn.setText("大後悔時代日記");
}

}

メインアクティビティをコンテキストで受け取ってテキストとボタンのテキストを変更
(MainActivity)はパッケージ名も含めて(com.example.helloworld01.MainActivity)にした方がいいのかも


main2
viewの操作ができました


基本中の基本ですがおばかはこんなところでも躓くのです

スポンサーサイト

Galaxy S4 + Eclipseで実機デバッグ

こんにちは

【TDU2】Ginetta F400

TDU2で一番のお気に入りはGinetta F400のペチコです
車高が低すぎてよくガードレールの隙間に挟まっています

【TDU2】Ginetta F400 behind
ゲーム中は後ろを見る事になるのでおしりのキュートさで決まります


今回は表題通りAndroidアプリの実機デバッグ
うちのPCのCPUがAMDのためエミュレータが激重なのです

色々詰まって色々調べたので自分用覚え書きです
こんなのでもどなたかの役に立つかもしれませんので。でも多分立たない


【本体の開発者モードをON】
ここ悩みました。Galaxy S4がそうですが隠しコマンドになってる機種があります

取り敢えず「設定」を開きます
設定

スライド

ランチャーから開いてもいいですし、ここまで細かく書く必要もないのですが、私も初スマホだったので一応丁寧にやります

設定の「その他」タブの中に「端末情報」の項目があるので選択
その他タブ

「端末情報」の中にビルド番号(灰色です)の項目があるのでそれを何度もタップします
ビルド番号

そうしたら開発者モードだかデベロッパーモードだかメッセージが出ると思います
既にやった後なので肝心の画像はありません。中途半端が信条です

上記を終わらせると「その他」タブに「開発者向けオプション」が表示されるので選択
開発者向けオプション

USBデバッグをONにします
USBデバッグ

その他項目は用途に合わせてお好みで
取り敢えず実機での作業は終了

※提供元不明のアプリを許可にしてない場合は
設定→その他(タブ)→セキュリティ→提供元不明のアプリ
の項目から許可しときます


次はPCにドライバを入れます


【PCにUSBドライバ導入】
私の環境がwinXP SP3なのでそれ前提で。適宜読み替えてください

まずSAMSUNGのサイトからKiesというソフトをダウンロードしてインストール

左のメニューの「WINDOWS用」→「DOWNLOAD KIES」でダウンロード
ここではS4前提なのでAndroid 4.3以下 対応機種 : Android OS 4.3 以下 (Galaxy S4, Note II)の方を選びました

適当なフォルダにダウンロードして実行、コーデックとかはお好みで。私は入れませんでした

画像がないのはこの作業繰り返すのがめんどくさかったから

ここで詰まったポイント
ドライバが入ったらPCを再起動しましょう

いや当たり前なのですがwinの警告出なかったのでいけるのかなあとしばらく詰まってました
非常にものぐさなのです


【実機でUSB接続】
PCの再起動が終わったら、別に開かなくていいと思うけどKiesのソフトを開きます
通常とliteがありますが違いがわかりません。どちらでも問題なかったです

Kies
Kiesを起動するとこんな画面が出るので、実機に付属のUSBケーブルでPCと接続します

繋いだら実機からぽぺっ♪って音がしてPCのKiesに接続中の画面が出ます
接続中
Potable Deviceウインドウが開きますが閉じましょう。マイコンピュータからいつでも開けますし

ちなみにドライバを入れた後PCを再起動しないと接続中がいつまで経っても終わりません
実体験済みです


接続成功
接続成功

接続が成功するとこんな画面になります
SDカードが512Mです。もっと大きいものを使いましょう

Kiesは同期とかファームのアップとか出来るみたいですが必要ないので、もう二度と立ち上げることはないでしょう
今回は確認のために起動しただけです


【Eclipseでデバッグ/実行構成を実機に】
Eclipseのパッケージエクスプローラから実機で実行したい対象のプロジェクトを選択
プロジェクト選択


メニューの「実行」か右クリックメニューで「実行の構成(デバッグ構成)」を選択
構成


ターゲットタブのデプロイ・ターゲット選択モードをお好みに選択して「適用」
実行の構成 ターゲットタブ
エミュレータと併用したかったのでここでは常にプロンプトを表示にしました


右下に「実行」ボタンがあるので実行してみましょう


実行するとまずターゲット選択プロンプトが出ます
実機選択

正常に接続されている場合は実機がOline表示されますので選択して「OK」


無事に実機で起動できました
実機で実行
テストした後は実機からアンインストールしときましょう
無駄アプリが増えて後でめんどくさくなります私だけ

※AndroidManifest.xml アプリケーションタブのDebuggableはtrueにした方がいいのかな?←よくわかってない


自作アプリがいつものホーム画面にっ!!!

※黒歴史は削除削除

もちろんただの浴衣自慢なのは言うまでもありません
ピンクだいすき


UnityでAndroidアプリ

こんにちは

Veyron
TDU2のブガッティ・ヴェイロンで400km/hオーバー!とか言って遊んでたら制御しきれなくて盛大にクラッシュして、面白い格好で止まってたからスクリーンショット取ってたらフランス人に救助されて、そのままなぜかオアフ1周ツーリングに出掛けることになった、ここまで全くのムダ情報のペチコです


色々ネットを見てたら面白そうなのがあったのでやってみました
タイトル通りUnity3Dでアンドロイドアプリを作ってみたのです


こちらのサイト様が非常に参考になりました
というかいつもの丸パクリです!


立方体をコグに変えただけです

Unityでコグコグ

期せずして帆がゼブラっぽくなって格好良くなりましたが、blenderで書き出したらおかしくなっただけです
C#スクリプトは横回転するようにしただけの丸パクリです

Androidエミュレータのbluestacksを起動してると、ビルド(build&run)で勝手にインストールから起動までやってくれました

Bluestacks

サイズとか考えてないので妙に縦長ですが、くるくるとコグが回りました
でもエミュレータな以上まだPC上で動作しているのにすぎませんので、次は実機でチャレンジ!


実機もUSBで繋いでたらビルドでインストールから起動までやってくれるみたいですが、今回はさっきできたapkを実機に放り込んでインストールしました

実機はGalaxy S4です

※黒歴史になりそう(もうなってる)なので画像削除しました

なんか妙なものも映り込んでますが気にしないでください

赤で囲ってるのがさっき作った回転コグ君ver1.00βです
いつものホームに自分が作ったアプリがあるなんて感動です
浴衣自慢したかったからいつものホームではないのはナイショです

コグが3Dで回転するだけのアプリなんでSS取った後は即アンインストールしましたけど

実機で3Dプレビュー

ここではただの静止画ですがちゃんと実機でくるくるしてる所をSS撮りました
手持ちの携帯で丸パクリ自分のアプリが動いてるなんて感動しました!

GooglePlayとかに載せて世界に配信できるアプリ作りたいけど、根性ないから無理だろうなあ


DXライブラリでハーフランバートにバンプマッピング

こんにちは、未だドライブに夢中のペチコです

TDU2 Jaguar D-Type

車に「ペチコート」ってペインティングしてるのですが、外国の方から見たら日本語で「割烹着」って書いてるようなものなんでしょうか


今回はハーフランバートにバンプマップを付けてみました
正直用途の分からないシェーダです。やってみたかっただけです
レースに優勝したからそのSSを上げたかったとかその辺はナイショです

頂点シェーダ
HLN_VS.fx
// 頂点シェーダーの入力
struct VS_INPUT
{
float4 Pos : POSITION ; // ローカル
float2 Tex : TEXCOORD0 ; // テクスチャUV
float3 Tan : TANGENT0;
float3 Bin : BINORMAL0;
float3 Normal : NORMAL0 ; // ローカル
} ;

// 頂点シェーダーの出力
struct VS_OUTPUT
{
float4 Pos : POSITION ; // 射影
float2 Tex : TEXCOORD0 ; // テクスチャUV
float3 VPos : TEXCOORD1 ; // 座標( ビュー空間 )
float3 VTan : TEXCOORD2 ; // 接線( ビュー空間 )
float3 VBin : TEXCOORD3 ; // 従法線( ビュー空間 )
float3 VNorm : TEXCOORD4 ; // 法線( ビュー空間 )
} ;

// C++ 側で設定する定数の定義
float4x4 g_World : register( c94 ) ; // ローカル→ワールド
float4x4 g_View : register( c6 ) ; // ワールド→ビュー
float4x4 g_Proj : register( c2 ) ; // ビュー→射影

// main関数
VS_OUTPUT main( VS_INPUT VSInput )
{
VS_OUTPUT VSOutput;

//ローカル→ワールド→ビュー→射影変換
float4 worldPosition = mul(VSInput.Pos, g_World);
float4 viewPosition = mul(worldPosition, g_View);
VSOutput.Pos = mul(viewPosition, g_Proj);

// ビューへ
float3 N = mul(VSInput.Normal,(float3x3)g_World);
N = normalize(mul(N,(float3x3)g_View));
float3 T = mul(VSInput.Tan,(float3x3)g_World);
T = normalize(mul(T,(float3x3)g_View));
float3 B = mul(VSInput.Bin,(float3x3)g_World);
B = normalize(mul(B,(float3x3)g_View));

// テクスチャ
VSOutput.Tex = VSInput.Tex;

VSOutput.VPos=viewPosition.xyz;
VSOutput.VTan=T;
VSOutput.VBin=B;
VSOutput.VNorm=N;

return VSOutput;
}


ビューポジションとビューに変換したNormal,Tangent,Binormalをピクセルシェーダに送ってます

ピクセルシェーダ
HLN_PS.fx
// ピクセルシェーダーの入力
struct PS_INPUT
{
float2 Tex : TEXCOORD0 ; // テクスチャUV
float3 VPos : TEXCOORD1 ; // 座標( ビュー空間 )
float3 VTan : TEXCOORD2 ; // 接線( ビュー空間 )
float3 VBin : TEXCOORD3 ; // 従法線( ビュー空間 )
float3 VNorm : TEXCOORD4 ; // 法線( ビュー空間 )
} ;

// ピクセルシェーダーの出力
struct PS_OUTPUT
{
float4 Color0 : COLOR0 ;
} ;

// マテリアルパラメータ
struct MATERIAL
{
float4 Diffuse ; // ディフューズカラー
float4 Specular ; // スペキュラカラー
float4 Power ; // スペキュラの強さ
} ;

// ライトパラメータ
struct LIGHT
{
float4 Position ; // 座標( ビュー空間 )
float3 Direction ; // 方向( ビュー空間 )
float4 Diffuse ; // ディフューズカラー
float4 Specular ; // スペキュラカラー
float4 Ambient ; // アンビエントカラーとマテリアルのアンビエントカラーを乗算したもの
float4 Range_FallOff_AT0_AT1 ; // x:有効距離 y:スポットライト用FallOff z:距離による減衰処理用パラメータ0 w:距離による減衰処理用パラメータ1
float4 AT2_SpotP0_SpotP1 ; // x:距離による減衰処理用パラメータ2 y:スポットライト用パラメータ0( cos( Phi / 2.0f ) ) z:スポットライト用パラメータ1( 1.0f / ( cos( Theta / 2.0f ) - cos( Phi / 2.0f ) ) )
} ;

// C++ 側で設定するテクスチャや定数の定義
sampler DiffuseMapTexture : register( s0 ) ; // ディフューズマップテクスチャ
sampler NormalMapTexture : register( s1 ) ; // ノーマルマップテクスチャ

float4 cfAmbient_Emissive : register( c1 ) ; // エミッシブカラー + マテリアルアンビエントカラー * グローバルアンビエントカラー
MATERIAL cfMaterial : register( c2 ) ; // マテリアルパラメータ
float4 cfFactorColor : register( c5 ) ; // 不透明度等
LIGHT cfLight : register( c32 ) ; // ライトパラメータ

// main関数
PS_OUTPUT main( PS_INPUT PSInput )
{
PS_OUTPUT PSOutput;

float2 Tex=PSInput.Tex.xy;
/*
// 頂点座標から視点へのベクトルを接底空間に投影した後正規化して保存
float3 TempF3;
TempF3.x = dot( PSInput.VTan, -PSInput.VPos.xyz ) ;
TempF3.y = dot( PSInput.VBin, -PSInput.VPos.xyz ) ;
TempF3.z = dot( PSInput.VNorm, -PSInput.VPos.xyz ) ;
float3 V_to_Eye = normalize( TempF3 ) ;
// texをずらして視差を付ける
float H = tex2D( NormalMapTexture, Tex ).a;
Tex = Tex + 0.010 * H * V_to_Eye.xy;
*/
// バンプマッピング
float3 N = 2.0f*tex2D( NormalMapTexture, Tex ).xyz-1.0f;
N = PSInput.VNorm + N.x * PSInput.VTan + N.y * PSInput.VBin;
N = normalize(N);

// ハーフランバート
float P = max(dot(N,-cfLight.Direction),0)*0.5f+0.5f;
P*=P;

//色
float4 C = P * cfLight.Diffuse * cfMaterial.Diffuse + cfLight.Ambient + cfAmbient_Emissive;
//テクスチャ
float4 D = tex2D( DiffuseMapTexture, Tex );

PSOutput.Color0.rgb = D * C.rgb ;
PSOutput.Color0.a = cfMaterial.Diffuse.a * D.a * cfFactorColor.a ;

return PSOutput;
}

コメントアウト部分は視差マッピング
法線マップのアルファに高さ(ハイトマップ)が埋め込まれていれば視差マッピングになります

バンプマッピング部分
N = PSInput.VNorm + N.x * PSInput.VTan + N.y * PSInput.VBin;
これでバンプマップになるそうです。海外の掲示板?で見かけました。これ試したかっただけなのです
接線と従法線とか全然理解してないのでビュー空間でやっていいの?ってカンジですが一応表示できるからよしとします

あとはこれでできた法線でハーフランバートやってるだけです
バンプ視差

左がバンプマッピング、右が視差マッピングです

うん、ほんと用途が皆無な気がしますが、
ハーフランバートの柔らかい影でも凹凸を付けたいって日がやってくるかもしれません



でもきっとこない


追記:
テキトー過ぎて行列の順序とか考えてなかったせいでモデルによっては描画が変になっちゃいますね

cppでモデル描画前に
MATRIX MatWorld = MV1GetLocalWorldMatrix(描画するモデルのハンドル);
MATRIX Camera_ViewMatrix = GetCameraViewMatrix() ;
MATRIX Camera_ProjectionMatrix = GetCameraProjectionMatrix() ;
SetVSConstFMtx(94,MatWorld);
SetVSConstFMtx(6,Camera_ViewMatrix);
SetVSConstFMtx(2,Camera_ProjectionMatrix);


頂点シェーダの行列変換部分を
VSOutput.Pos = mul(mul(mul(g_Proj, g_View), g_World), VSInput.Pos);
//N,T,Bもそれぞれこんなカンジにしないとダメかも
N = mul(mul(g_View, g_World), VSInput.Normal);


に追記および変更で正常になる、はずです。。行列とか全然分かってないです!(きっぱり)
大人しくライブラリ様の通りにしろってカンジですね

DXライブラリで大量モデル描画比較

こんにちは
割とピンキッシュなペチコです

ピンキー

下手なのでレースとか全然クリアしてませんがコレクションはだいすきです
Dolでも船枠がいっぱいあれば並べて楽しめるのに

PC版のTest Drive Unlimited 2ってゲームでこういうピンキーなのを見かけたら多分わたしです


今回はモデル描画でちょっと気になったところのテスト

大量にモデルを描画する際に
・ループで位置を変えながら通常描画する
・モデルのコピーを描画するモデル分作って描画
・全てのモデルを頂点バッファに格納して描画
の計測をやってみました

コードはこんな感じ

#include "DxLib.h"
#include <malloc.h>

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
VERTEX3D *Vertex ;
DWORD *Index ;
int VertexBufHandle ;
int IndexBufHandle ;
int ModelHandle ;
int IndexNum =0;
int VertexNum =0;
int i ;
LONGLONG Time1, Time2 ,Time3;
MV1_REF_POLYGONLIST RefMesh ;

// DXライブラリの初期化
ChangeWindowMode( TRUE ) ;
if( DxLib_Init() < 0 )
{
// エラーが発生したら直ちに終了
return -1 ;
}

// 裏画面を描画対象にする
SetDrawScreen( DX_SCREEN_BACK ) ;

// Zバッファを使用する
SetUseZBufferFlag( TRUE ) ;

// Zバッファへの書き込みを行う
SetWriteZBufferFlag( TRUE ) ;

// バックカリングを行う
SetUseBackCulling( TRUE ) ;

// モデルの読み込み
ModelHandle = MV1LoadModel( "grass.mv1" ) ;
int GraphHandle = LoadGraph( "grass.dds" ) ;

// 参照用メッシュの作成
MV1SetupReferenceMesh( ModelHandle, -1, TRUE ) ;
// 参照用メッシュの取得
RefMesh = MV1GetReferenceMesh( ModelHandle, -1, TRUE ) ;
// 頂点の数とインデックスの数を取得
IndexNum = RefMesh.PolygonNum * 3 * 10000 ;
VertexNum = RefMesh.VertexNum * 10000 ;

// 頂点データとインデックスデータを格納するメモリ領域の確保
Vertex = ( VERTEX3D * )malloc( sizeof( VERTEX3D ) * VertexNum ) ;
Index = ( DWORD * )malloc( sizeof( DWORD ) * IndexNum ) ;

int vnum=0;
int pnum=0;
for(int x=0;x<100;x++){
for(int z=0;z<100;z++){
// 画面に映る位置に3Dモデルを移動
MV1SetPosition( ModelHandle, VGet( x*100.0f, 0.0f, -z*100.0f ) ) ;
// Y軸回転
MV1SetRotationXYZ( ModelHandle, VGet( 0.0f, 60.0f * DX_PI_F / 180.0f, 0.0f ) ) ;

//// 参照用メッシュの作成
//MV1SetupReferenceMesh( ModelHandle, -1, TRUE ) ;
// 参照用メッシュの更新
MV1RefreshReferenceMesh( ModelHandle, -1, TRUE ) ;

// 参照用メッシュの取得
RefMesh = MV1GetReferenceMesh( ModelHandle, -1, TRUE ) ;
// 頂点データをコピー
for( i = 0 ; i < RefMesh.VertexNum ; i ++ )
{
Vertex[ i+vnum ].pos = RefMesh.Vertexs[ i ].Position ;
Vertex[ i+vnum ].norm = RefMesh.Vertexs[ i ].Normal ;
Vertex[ i+vnum ].dif = RefMesh.Vertexs[ i ].DiffuseColor ;
Vertex[ i+vnum ].spc = RefMesh.Vertexs[ i ].SpecularColor ;
Vertex[ i+vnum ].u = RefMesh.Vertexs[ i ].TexCoord[ 0 ].u ;
Vertex[ i+vnum ].v = RefMesh.Vertexs[ i ].TexCoord[ 0 ].v ;
Vertex[ i+vnum ].su = RefMesh.Vertexs[ i ].TexCoord[ 1 ].u ;
Vertex[ i+vnum ].sv = RefMesh.Vertexs[ i ].TexCoord[ 1 ].v ;
}

// インデックスデータをコピー
for( i = 0 ; i < RefMesh.PolygonNum ; i ++ )
{
Index[ i * 3 + 0 + pnum ] = ( WORD )RefMesh.Polygons[ i ].VIndex[ 0 ]+vnum ;
Index[ i * 3 + 1 + pnum ] = ( WORD )RefMesh.Polygons[ i ].VIndex[ 1 ]+vnum ;
Index[ i * 3 + 2 + pnum ] = ( WORD )RefMesh.Polygons[ i ].VIndex[ 2 ]+vnum ;
}
vnum+=RefMesh.VertexNum;
pnum+=RefMesh.PolygonNum*3;
}
}

// 頂点データとインデックスデータを格納する頂点バッファとインデックスバッファを作成
VertexBufHandle = CreateVertexBuffer( VertexNum, DX_VERTEX_TYPE_NORMAL_3D ) ;
IndexBufHandle = CreateIndexBuffer( IndexNum, DX_INDEX_TYPE_32BIT ) ;

// 頂点バッファとインデックスバッファにデータを転送
SetVertexBufferData( 0, Vertex, VertexNum, VertexBufHandle ) ;
SetIndexBufferData( 0, Index, IndexNum, IndexBufHandle ) ;

//モデルのコピー
int D_ModelHandle[10000];
for(int x=0;x<100;x++){
for(int z=0;z<100;z++){
D_ModelHandle[x*100+z]=MV1DuplicateModel( ModelHandle ) ;
// 画面に映る位置に3Dモデルを移動
MV1SetPosition( D_ModelHandle[x*100+z], VGet( x*100.0f, 0.0f, -z*100.0f ) ) ;
// Y軸回転
MV1SetRotationXYZ( D_ModelHandle[x*100+z], VGet( 0.0f, 60.0f * DX_PI_F / 180.0f, 0.0f ) ) ;
// テクスチャ
MV1SetTextureGraphHandle( D_ModelHandle[x*100+z], 0, GraphHandle, TRUE ) ;
//アルファテスト用
MV1SetMaterialDrawAlphaTest(D_ModelHandle[x*100+z],0,TRUE,DX_CMP_GREATER,128) ;
}
}

// 標準ライトの方向をX軸のプラス方向にする
SetLightDirection( VGet( 1.0f, 0.0f, 0.0f ) ) ;

//カメラ
SetCameraPositionAndTarget_UpVecY( VGet( -500.0f, 700.0f, 500.0f ), VGet( 500.0f, 0.0f, -500.0f ) ) ;

//アルファテスト用
SetDrawAlphaTest( DX_CMP_GREATER, 128 ) ;
MV1SetMaterialDrawAlphaTest(ModelHandle,0,TRUE,DX_CMP_GREATER,128) ;

// メインループ
while( ProcessMessage() == 0 )
{
// 画面をクリア
ClearDrawScreen() ;
// 頂点バッファ描画の時間計測
Time1 = GetNowHiPerformanceCount() ;
// 頂点バッファで描画
DrawPolygonIndexed3D_UseVertexBuffer( VertexBufHandle, IndexBufHandle, GraphHandle , TRUE ) ;
Time1 = GetNowHiPerformanceCount() - Time1 ;

// 画面をクリア
ClearDrawScreen() ;
Time2 = GetNowHiPerformanceCount() ;
for(int x=0;x<100;x++){
for(int z=0;z<100;z++){
// 画面に映る位置に3Dモデルを移動
MV1SetPosition( ModelHandle, VGet( x*100.0f, 0.0f, -z*100.0f ) ) ;
// Y軸回転
MV1SetRotationXYZ( ModelHandle, VGet( 0.0f, 60.0f * DX_PI_F / 180.0f, 0.0f ) ) ;
//モデル通常描画
MV1DrawModel( ModelHandle );
}
}
Time2 = GetNowHiPerformanceCount() - Time2 ;

// 画面をクリア
ClearDrawScreen() ;
Time3 = GetNowHiPerformanceCount() ;
for(int x=0;x<100;x++){
for(int z=0;z<100;z++){
// モデルコピー描画
MV1DrawModel( D_ModelHandle[x*100+z] ) ;
}
}
Time3 = GetNowHiPerformanceCount() - Time3 ;

// 掛かった時間を描画
DrawFormatString( 0, 0, GetColor( 255,255,255 ), "頂点バッファ :%4d micro sec", Time1 ) ;
DrawFormatString( 0, 16, GetColor( 255,255,255 ), "通常描画   :%4d micro sec", Time2 ) ;
DrawFormatString( 0, 32, GetColor( 255,255,255 ), "コピー描画  :%4d micro sec", Time3 ) ;

// 裏画面の内容を表画面に反映
ScreenFlip() ;
}

// DXライブラリの後始末
DxLib_End() ;

// ソフトの終了
return 0 ;
}


使用したモデルはこの時やった井形の草メッシュにアルファ抜きしたテクスチャです
別にメッシュはなんでもいいのですが、プログラム側で草を100x100ばらまいたという想定でやってみました

結果の前に簡単な説明
割とてきとうにやったので間違ってるトコとかあるかもしれません。どうぞよしなに

最初の方で参照用メッシュを作ってるのが頂点バッファ用
参照用メッシュから配置する草の数分頂点に突っ込んでいます
ここでは同じモデルが複数なので単純にモデルの頂点数*モデルの数でやってますが、別モデルも同じ頂点系に入れる場合はモデル毎の参照メッシュを作成して頂点数に加算ってやんなきゃダメですね
頂点バッファで扱う場合は、同じテクスチャを使用するマテリアルをまとめるので別モデルにすることは少なそうですが

頂点インデックス(unsigned short)の上限65536を超えてしまったので32bitのDWORDを使ってますが、対応してないグラフィックデバイスもあるそうなので、この数未満に抑えた方がいいのかもですね

通常モデルの描画はメインループ中で位置と回転を設定して100*100DrawModelしてます
使ったテクスチャがアルファ抜きやってますので、モデルのマテリアル毎のアルファテスト(MV1SetMaterialDrawAlphaTest)をやってます

コピーモデル描画は元の通常描画用モデルをMV1DuplicateModelで100*100個コピーしてます
コピーする際に移動回転も行っているので描画部はただDrawModelするだけにしてます
こちらも各コピーモデル毎にアルファテストの設定もやってます


肝心の結果
モデル描画速度比較

頂点バッファ使用:29ms
通常描画    :33366ms
コピー描画   :37042ms

おそろしく差が付きました
頂点数は16万ですが、頂点バッファを使用した時は、モデル一つ(頂点数16)描画(18ms~22ms)するのとほとんど変わりない速度で描画できています
コピー描画はあまりに数が多すぎてVRAM溢れちゃったのかもしれません。512Mしかないもので

草や木や地面などの動かない物体を大量に描画する時は頂点バッファを使うのが良さそうですね


ただ上の方法でモデルから頂点バッファを作成した場合に、ちょっと暗かったり微妙に描画結果が変わるんですよね
どっか間違えてるんでしょうね修正する気はなし


プロフィール

ペチコートさん

Author:ペチコートさん
大航海時代オンライン
Zephyros、Eurosサーバーに潜伏中

偽ペチコ1号・2号
ペチコの手下達
Zephyrosサーバーに潜伏中

最新記事
月別アーカイブ
カテゴリ
リンク
最新コメント
検索フォーム
QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。