プロフィール

Na-7

Author:Na-7
SE(システムエンジニア)として約15年間システム系ソフト会社を勤めあげ、2008年3月退社。現在、ゲーム制作会社設立を目指して活動中。


アクセスカウンター


最新記事


最新コメント


最新トラックバック


月別アーカイブ


カテゴリ


DATE: CATEGORY:スポンサー広告
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
DATE: CATEGORY:三国志軍記開発
DrawUserIndexedPrimitives
テクスチャ座標書き替えテスト
Modelインスタンスに格納された頂点データを書き換えるテスト。これが出来れば1枚のテクスチャでアニメも可能。



◎テクスチャ統合公式サンプル

本題に入る前に、前回コメントでHOSSIEさんからスプライトシートのコンテンツパイプラインサンプルを教えて頂いたので触れておきます。

スプライトシートサンプル

大量のテクスチャファイルを1ファイルに結合してファイル名でアクセスできるようにしてくれるとのことで、とても便利そうなサンプルです。

今回は3D連画取得から画像統合まで1つにまとめたかったので使用しませんが、今後画像を統合する際は積極的に活用したいと思います。



◎境界線の原因

私は以前(地形モデル用のパターンテクスチャを統合したり、地形を板ポリ化して正射影画像を張り付けたりした際に)、「テクスチャの端に境界線が生じる」という問題に直面しました。

この問題が発生する度に、自分のプログラムミスではないかと散々悩んできましたが、その原因が上記サンプル付属ドキュメントに記述されてました。

サンプル付属ドキュメント(一部抜粋)

これによると、境界線の問題はグラフィックカードのフィルタリングによるものでした。原因が判明してちょっとスッキリしましたw



◎境界線問題の回避策について

上記ドキュメントはスプライトシート用のものなので「周囲に1 ピクセルのパディングを含めること」を回避策として挙げていますが、これは私のケースでも適用可能でしょうか?

改めて考えてみましたが、答えはNoです。スプライトの場合は、描画の開始座標と終了座標を持っていますが、モデルの場合は、1頂点につき1テクスチャ座標しか持っていないからです。

結局のところ、頂点データを4倍にするか、1頂点につきテクスチャ座標を4つ持たせて、パディングを指定可能とするしかありません。シェーダー(HLSL)内で現在描画中の頂点番号を参照できればシェーダー側で回避できそうですが、私が以前試した限りでは不可能でした。



◎BasicEffectのカスタマイズ

前置きが長くなりましたが、そろそろ本題に入りましょう。前回は連画を1つのファイルにまとめたので、今回はその画像ファイルを読み込んで表示します。

読み込みはContent.Load()で普通に読み込めば良いのですが、問題は表示ですね。XNA標準のBasicEffectではテクスチャ座標を指定することが出来ないので、テクスチャ座標を指定可能なシェーダーを用意する必要があります。

シェーダーを1から作るのは大変なので、BasicEffectのソースをカスタマイズしましょう。ソースはこちらで公開されているのですが、これを自作モデルに適用する方法がよくわからなくて、しばらく試行錯誤してしまいました。

最終的にはシンプルなコードで適用できるようになったので、サンプルコードをこちらにUPしておきました。



◎まとはずれ

実際にBasicEffectを改修しようとソースを解析した段階で、ようやく気が付きました。今回修正すべきはシェーダーではなく、頂点データだったのです。
私は何を考えていたのでしょうね、ハハハ…(^_^;;;

まぁ、いずれBasicEffectをカスタマイズする日が来ると思うので、後々の布石と言っておきましょう(汗)



◎頂点データの書き替え

板ポリモデルには4つの頂点があり、各頂点がテクスチャ座標を持っています。その値を変えるだけで、アニメーションが実現できるはずです。

問題は、Modelクラスに読み込んだ頂点データを書き換える方法です。以下の手順で試してみます。

1 頂点データフォーマットを確認する(参考はこちら
2 カスタム頂点構造体を作成する
3 頂点バッファデータのコピーを取得する
4 取得したデータを書き換える
5 書き替えたデータを頂点バッファにセットする

サンプルコード
(文字化けする場合は、ブラウザのエンコードを「日本語」に指定してください)

実際にやってみると、1~4まで出来ました。しかし5で書き替えたデータをセットすると、狙い通りにテクスチャ座標がずれた画面が瞬間的に表示され、直後エラーになりました。

InvalidOperationException
操作は中断されました。デバイスで設定されているリソースは変更できません。また、タイリングブラケット内で使用した後に変更することもできません。




◎エラーの原因

VertexBuffer.SetDataのヘルプを見ると、Xbox360に関する注意事項がいろいろ書いてあります(難しすぎてよくわかりません)が、x86系に関する記述はありません。しかし、

・狙い通りの画面が一瞬だけ表示される
 (初回のSetDataは成功したが、二回目で失敗する?)

・エラーはSetDataの箇所で発生するが、
 ModelMesh.Draw()をコメント化するとエラーにならない

これらの現象を考慮すると
「GPUがフレーム描画中にSetDataコマンドを発行して描画内容を変更しようとするとエラーになる」
ということではないでしょうか?



◎頂点データ書き換えテスト

ヘルプは(Xbox360の場合)DrawUserPrimitives等の使用を推奨しているので、そちらで試してみましょう。

サンプルコード

DrawUserPrimitives

テクスチャ座標の書き換えテストは成功しました(左上隅をずらした)が、三角形が1つ足りませんね。modelMeshPart.PrimitiveCountの値は2ですが、PrimitiveTypeをTriangleListにするとエラーになります。

この板ポリモデルはインデックス描画が必要ですね。DrawUserIndexedPrimitivesで表示してみましょう。

サンプルコード

DrawUserIndexedPrimitives

板ポリが正常に表示されました。テクスチャ座標の書き換えテストも成功しています。これでバッチリですね!



◎次回予告

ここまで来ればあと一息ですが、長文になってしまったので今回はここまで。

次回は最終実装です。このシリーズがここまで長引くとは思いませんでしたw

スポンサーサイト

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック


この記事にトラックバックする(FC2ブログユーザー)



copyright © ゲーム制作の舞台裏 all rights reserved.Powered by FC2ブログ
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。