Spamassassinメモ


SpamAssassinの学習方法メモ

たくさんのスパムと、誤認識してしまうメールを放置していたので、
そろそろ学習させてみようと思います。

そのためのメモ。

上記のスクリプト走らせれば、学習される仕組みになっています。

hamは、Spamと誤認識したメールを学習させるモードで、うちでは、missJudgeフォルダにそういったメールを移動させているようにしています


XSI ModTool使ってみた


XSI ModTool使ってみた

Gamefestでは散々XSIModToolを推すので、早速ダウンロードしてインストールしてみました。

モデラー自体初心者なのでまずはサイトからpdfダウンロードしてきて、
チュートリアルを進めてみました。

そしてようやく簡単なモデルを作ってみることまで出来ました。
サンプルでもある壺と象まで到達。
最後に .xファイルをexportしてみようとしたらXSIが落ちました(涙
どうやらシーンファイルを保存してから exportしないといけないようです。

一番手こずったのは、ドキュメントは日本語、ソフトは英語のギャップと、カメラ操作でしょうか。つい、Alt押しながらカメラ移動やってしまう・・・


Gamefest


Gamefest1日目

今日はGamefestに参加してきました。

まず感想として、豪華なレセプションパーティでした。
初めて、立食で(食べたい)食べ物が無くならない状態で、幸せでした。

講演内容もグラフィックスに関して大半しめていたのですが、なかなかおもしろかったです。

DX9とDX10で相当変わっているなぁというのと同時にDX10でパフォーマンス意識するなら、描画エンジンは共通化できないなと思いました。

今月末にはCEDECもあるので、ここでDX関係の話は聞いておきたかったので予想通りの収穫でした。

明日はXNAメインの1日です。


ジェネリックプログラミングの練習2


ジェネリックプログラミング

今日は以前から気になった部分をやってみました。テンプレートで型1から型2への変換が可能かどうかをチェックするという代物です。これにより変換が可能だったら〜というプログラミングが可能になります。

個人的にはこれから多用しそうな予感。

[code lang=”cpp”]
template< class T1, class T2>
struct can_convert {
static yes_type check(T2);
static no_type check(…);
static T1 makeTo();
enum {
  value = (sizeof(check(makeTo())) == sizeof(yes_type))
};
};

class Base { };
class Derived : public Base { };
class Test { };

int main() {
bool canConv1 = can_convert<Derived*, Base*>::value; // true
bool canConv2 = can_convert<Test*, Base*>::value; // false
bool canConv3 = can_convert<int, float>::value; // true (with warning

return 0;
}
[/code]


魔界の前に


しりあらいぜーしょん

どうやらBoostのserialization以外にもC++でシリアライズ目的のライブラリがある模様。

その名も s11n.net という。
こちらも変わらずtemplateを駆使しているみたい。
そして日本語の解説サイトも見あたらないな。

これもちょっと覗いてみるか。Boostに比べれば可愛いくらいのtemplate使用な感じだったし。


いざ魔界へ


Boost魔界へ

以前のリフレクションシステムは、会社でのソースを見た後だったので、
恐ろしく構造が似ていました。いやー、見てもらったらパクリx2 言われてしまった。
実装はtemplateメインにしたのでちょっとは違うのですが。
使うユーザー側にとっては定義の仕方一緒だし…。

そんな中最近のBoostにはserializationが入ったらしいです。
これを使えばシリアライズできるじゃん!ということです。
ただシリアライズはできるもののフィールドに対するメタ情報を扱うわけではないです。

そういう背景もあって自分でなんとか作ってやろうじゃないかと勉強中です。

そのためにはBoostの該当コード理解しないとと思ってますが、魔界です…

正直何やってるかわからない。template地獄。実行させながら追ってみるもののやはりさっぱり。

出直してきます・・・・・ orz

とりあえず自分に足りない要素として、

  • メタプログラミングに対する理解が不十分
  • templateによるジェネリックプログラミングの理解

とくに後者は多段のtemplateが使えるようにならなきゃ話にならないですね。


DirectX10 (D3D10)


Tutorial04

今回はTutorial04を見てました。このサンプルは立方体(キューブ)の表示サンプルでした。
前回のTutorial02の部分に比べて増えたところと言えば、IndexBufferを作っているところです。
ほかには、シェーダーで透視変換させているところ。大きく変わった部分はないです。

IndexBufferもVertexBufferと同じくBufferDescriptionとSubresourceDescriptionの2つを設定して、デバイスのメソッドで作成するだけです。

変更になってる部分はデータをどう使うか指示するところ、
「D3D10_BIND_INDEX_BUFFER」「D3D10_BIND_VERTEX_BUFFER」の違いくらいです

描画する前には以下のように

各バッファをデバイスに設定し、プリミティブタイプを指定しておきます。この辺が若干以前と変わっています。
前はDrawPrimitive系でプリミティブタイプを指定していました。

また、インデックス用のフォーマット指定(D3DFMT_INDEX16/32)がありましたが、
どうやら今回からは統一されたようです。

気になったのはこのサンプル、インデックスに32ビット指定してます。
従来は16ビット(WORD型)を基本的に使っていたのに、このように変更となるとデバイスの最適化もこれからは32ビットインデックスが主流となっていくんですかねぇ…。(※ 現状のデバイス(当時)は16ビットインデックスに最適化されています)

シェーダーに対して、各マトリックスをセットして、パスを回しています。
見てわかるように描画のDrawIndexedの引数が減っています。すっきりしましたね〜。あとDX9世代でBegin/BeginPassで行っていたパスを回す処理が変更になっています。テクニックのDescから値を取得して、回数と使用指示を設定しているようです。

この辺は使う側としてはあまり変更がないといってもいいでしょう。
あまり大きな変更ではないように思います。

気になったのは今までシェーダー定数を書き換えたときには、CommitChangesなどのメソッドを呼んで確定させていた気がしますが、それが消えています。

シェーダーコード

HLSLの中身も若干変わっています。

今までfloat4x4とかやっていた部分がmatrixになっています!

Passの部分も

となっており、ぱっとみてわかる程度の変更です。

ここにジオメトリシェーダーの記述があって、そのうちいじってみたいなとわくわくです。


DirectX10 (D3D10)


Tutorial02解説

今回は、DX10での三角形(ポリゴン)描画までのサンプルを読み解いてみました。
前回までの初期化にプラスして、頂点データの作成、シェーダーの作成と要素が詰まってます。

シェーダーの作成は以下のようになってました。若干自分なりのコメントをつけてみました。

間違っている場合もあると思いますが、気づいた人はコメントでご指摘ください。(^^;

[code lang=”cpp”]
// Create the effect
// このフラグは新しいHLSLのセマンティクスを有効にするため?
// 従来のHLSLコードを通過させないためのフラグである模様
DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
dwShaderFlags |= D3D10_SHADER_DEBUG;
#endif
hr = D3DX10CreateEffectFromFile( L"Tutorial02.fx", NULL, NULL, "fx_4_0", dwShaderFlags, 0,
g_pd3dDevice, NULL, NULL, &g_pEffect, NULL, NULL );
[/code]

どうやらDX9時代と変更がない感じです。プロファイルが fx_4_0になったくらいでしょうか。
シェーダーのフラグでDX10用のHLSLを要求しているように見えます。

fxファイルを覗くとわかるのですが、technique10や今までに見慣れないセマンティクスが使われています。
これらを要求するためのフラグみたいです。

[code lang=”cpp”]
// Define the input layout
D3D10_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
};
UINT numElements = sizeof(layout)/sizeof(layout[0]);
// Create the input layout
D3D10_PASS_DESC PassDesc;
g_pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
// 上記で設定したinput elementと、シェーダーのバイトコードからinputレイアウトの作成.
hr = g_pd3dDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize, &g_pVertexLayout );
if( FAILED( hr ) ) return hr;
// Set the input layout
g_pd3dDevice->IASetInputLayout( g_pVertexLayout );
// Create vertex buffer
SimpleVertex vertices[] =
{
D3DXVECTOR3( 0.0f, 0.8f, 0.5f ),
D3DXVECTOR3( 0.5f, -0.5f, 0.5f ),
D3DXVECTOR3( -0.5f, -0.5f, 0.5f ),
};
D3D10_BUFFER_DESC bd;
bd.Usage = D3D10_USAGE_DEFAULT;
bd.ByteWidth = sizeof( SimpleVertex ) * 3;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA InitData;
InitData.pSysMem = vertices;
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
if( FAILED( hr ) ) return hr;
// Set vertex buffer
UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
g_pd3dDevice->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );
// Set primitive topology
g_pd3dDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
[/code]

シェーダーのバイトコードと、頂点宣言二つからinputlayoutを作成します。
そしてこのレイアウトはIA(InputAssembler)にセット。
この次に、ようやく頂点バッファの作成に取りかかります。

DX9時代とかなり変更になっているのがこの部分。
BufferDescriptionとSubresourceDescriptionの二つから頂点バッファを作成しています。

各DESCに値をセットして、初期化時にデータを転送してしまうっぽいです。

このD3D10_USAGE_DEFAULTフラグでは、GPUからのアクセスはできて、CPUからのアクセスは禁止という意味だそうです。
DX10からはすべてのバッファがMap(従来のLock)ができるわけではなくなりました。

つまり上記の例ではMapすら禁止ということで、初期化時にシステムメモリ上のデータを設定することで、初回1度だけデータ転送しているということなんでしょう。

SubResourceとはなんぞや?

よくわからなかったので調べてみました。

上記でもSubResourceDescription を設定してます。
このdescではバッファの初期データを与えるためにセットしています。

SubresourceDescriptionは実際のリソースデータを示し、データのサイズとレイアウトに関する情報を保持します。

どこかにも記述があったのですが、Subresourceっていわゆる実データなんでしょうか。
Surfaceに相当とか書いてあった気が…。


DirectX10 (D3D10)


基本からさわってみよう。D3D10

まずは2007Apr版のDXSDKをダウンロードして、サンプルを実行してみてました。
DirectX10がどう動いてくれるか、わくわくしながらサンプルを実行したのですが、

・・・意外と安定動作しない(><

ものによっては放置しておくだけで、GPUが停止し復帰しましたとのメッセージが出まくるし、プログラムの終了時にはエラーメッセージのダイアログが出るし。まだまだきちんと整備されていないということでしょうか。

あとこれは8600GTという点だからかもしれませんが、
ジオメトリシェーダー使ったサンプルが遅い!

極端に速度低下してました。CubeMapGSのサンプルなんか車モデルにしたら 5fpsくらいになってましたし。

それでも基本的にDX9と切り替えられるタイプのサンプルでは、
DX10のほうが高速動作している感じでした。FPSの向上もみられました。

Tutorial01解説もどき

自分のメモも含めて少し解説。DX9の頃と違って、かなり初期化周りも変更になっている。
Tutorial01.cppのソースを抜き出して以下に書いてみます。

※値のセット部分は省いてあるのでコピペしても動きません。

[code lang=”cpp”]
DXGI_SWAP_CHAIN_DESC sd; ZeroMemory( &sd, sizeof(sd) ); // この後、値を詰めていく
for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) {
g_driverType = driverTypes[driverTypeIndex]; // デバイスとスワップチェインを作成.
hr = D3D10CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice );
if( SUCCEEDED( hr ) ) break;
}

// 次にRenderTargetViewを作成。リソースの種類は2DTextureってことですね
ID3D10Texture2D *pBackBuffer;
hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), (LPVOID*)&pBackBuffer );
if( FAILED(hr) ) return hr;
hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );
pBackBuffer->Release();
if( FAILED(hr) ) return hr;

// 作成したビューをレンダーターゲットとしてセットする
g_pd3dDevice->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );[/code]

どうやら、スワップチェインを作成を作成した後、そのスワップチェインの中にあるバッファデータを取得。

そのデータを2Dのテクスチャデータとしてバインドし直してレンダーターゲット設定している、といったところでしょうか。

Render()処理

[code lang=”cpp”]
float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; //red,green,blue,alpha
g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
g_pSwapChain->Present( 0, 0 );
[/code]

これをみても明らかなように、レンダーターゲットに対してクリアしてます。
今まではPresentもpd3ddeviceでしたが、今回からはPresentはスワップチェインに対して操作しています。
より明確に分かれた感じがしますね。とりあえずTutorial01では、このくらいしか従来と大きく変わった部分は無さそうです。

あ、フォーマットの指定はかなり変わってました。よりデータ型を意識するものになっていました。


PC新調しました


新しいマシンを組みました

価格改定を待てず、Core2Duoのマシンを組み立てました。
どこへ行ってもE6400が無かったため、E6300で組み立て。

元々、新PCは二の次で、やりたかったことのメインは、
『GeForce8600GTを買うこと!そして、VistaでDirectX10!』
が本当の目的です。

新PCを組むなら P965のチップセットで〜も条件だったため、適当にパーツ選んできました。

CPU Core2Duo E6300
メモリ 2GB (DDR2 800)
M/B Gigabyte 965P-DS3P
VGA Albatron 8600GT (256MB)

こんな感じです。
これからVistaなど色々と入れてゴールデンウィークにはD3D10いじってみようと計画中です。