C++ DirectX11 ゲームプログラミング プログラミング

ゼロから始めるDirectX11ゲームプログラミング入門 #5「画像を面に貼ろう! - テクスチャマッピング その1- 」

ハッカドールMMDデータ © 2015 DeNA Co.,Ltd.

前回の#4で四角形のポリゴンを表示することができましたが、単色の板を出しただけでは、あまり楽しいものではないですよね。今回は画像ファイルを読み込み、このポリゴンに画像の色を付けてみましょう。

まずは、いろいろと準備をしておきましょう

まず最初に、今回の講座で必要になるファイルの準備やソースコードの改良をしておきましょう。今回のプログラム集中できるようにするためです。

新規ソースファイルの作成

DirectX.hとTexture.cppとTexture.hファイルを作成しよう

プロジェクトへの追加もお忘れなく

後ほど、画像の取り扱いをするためのTextureクラスを、このファイルに書いていきます。

DirectXのまとめ役ヘッダー(DirectX.h)の記述

今現在はDirect3D.hとTexture.hの2種類のファイルが出来ています。今後まだまだ増えていく予定なので、今回はわかりやすさを重視し、お手軽にDirectX関係のヘッダーを一気にインクルードできるように、まとめ役のヘッダーを作りたいと思います。

いままでDirect3D.hに書いていたDirectX関係のヘッダーを、ここに移植してきましょう。

DirectX.hで、DirectX関係のヘッダーをまとめてインクルード

今後、DirectX関係のヘッダーを作ったら、DirectX.hにincludeを追記していきます。

各ソースがDirectXを使うように修正

背景が黄色い行追加や変更した部分です。コメントにしている箇所は削除しても大丈夫です。

インクルードのイメージ

結構横着しましたが、最初はこの方法が楽だと思います。
DirectX.hをincludeするだけで、DirectX関係の機能が全て使えるようになりますね。

画像を読み込むには?

画像ファイルを読み込むには、どうすればよいでしょうか?画像ファイルといっても、いろんな形式があります。

例えば、jpg, bmp, gif, png, tif, tga, dds, hdr, psdなどなど・・・

これらの画像ファイルは、お互いほとんど共通点がなく、中身は全然違う形式になっています。それらの画像形式の内部を全て理解し、自由に扱えるようになるには、大変な時間と努力が必要になってしまいます。これではゲームを作るのはいつのことやらって感じですよね。

でも安心してください。様々な画像ファイルを読み込むプログラムは、世の中のすごい人たちが既に作ってくれており、しかも無料で使用できるように提供してくれています。今回はそのような便利なライブラリ(プログラム)を使用して、簡単に画像を読み込んじゃいましょう。

DirectXTexの導入

DirectXTexとは、DirectXを開発しているMicrosoftが、DirectXで楽に画像を扱えるようにしてくれるライブラリです。githubにソースコードと説明書がありますが、今回はもっと簡単に導入できる「NuGet」で導入したいと思います。

興味のある人のために、DirectXTexライブラリ(github)のURLを記載しておきます。特に説明書の存在は知っておいた方が良いので、そのURLも記載しておきます。
・github
https://github.com/microsoft/DirectXTex
・説明書(英語)
https://github.com/microsoft/DirectXTex/wiki/DirectXTex

NuGetでDirectXTexを導入する方法

まずは下図のように「ソリューションのNuGetパッケージの管理」を選択してください。

下図のように、DirectXTexを検索し、導入先プロジェクトをチェックを入れて、インストールを押す

これで導入できました。簡単ですね!

必要なヘッダーをインクルードしよう

DirectXTex.hをインクルードすると、使用可能になります。DirectX.hでインクルードしておこう。

画像を読み込む(Textureクラスの作成)

では実際にDirectXTexの機能を使って画像を読み込み、DirectXで使えるようにしましょう。

画像のことをテクスチャと読んだりします。「表面の質感」とかいう意味ですね。

Textureクラスの作成

画像を読み込んだり、読み込んだ画像を管理したりするためのクラスを作成しましょう。冒頭で作成したファイル(Texture.hとTexture.cpp)に書き込んでいきます。

説明

・DirectX::LoadFromWICFile関数

この関数がWIC画像を読み込む命令です。WICとは「Windows Imaging Component」の略で、簡単に言うとWindowsが対応している画像形式です。主にbmp, png, gif, tiff, jpegなどが読み込めます。

また、これら以外の画像ファイル(DDS、HDR)を読み込む関数も用意されています。この講座では主にpngファイルを使用していきます。

GenerateMipMaps関数

画像を読み込んだあとは、ミップマップ画像を生成しています。これは主に3Dの描画で活躍するものなので、今回は説明を省略します。

CreateShaderResourceView関数

最後に「リソースとシェーダーリソースビューを作成」をしています。読み込んだ画像データを、実際にDirectXの描画で使用できるようにビデオメモリに書き込んで、そのハンドルを作成しています。

  • リソース
    ・・・VRAMに置かれた画像データそのもの
  • ビュー
    ・・・画像本体であるリソースにアクセスするためのハンドル

描画で使用するのはビューの方です。今回作成したビューはシェーダーリソースビュー、略してSRVと言います。
ビューを使用することで、画像本体にアクセスできるんですね。

Textureクラスを使用して、実際に画像を読み込む

作ったTextureクラスを使用して、画像を読み込んでみましょう。今回使用する画像は以下の画像です。右クリックで保存しましょう。保存場所はApplicationフォルダ以下にDataフォルダを作ってそこに保存しておきます。

こんな感じに保存

テクスチャをシェーダーに送る

では次は読み込んだテクスチャを、デバイスコンテキストさんにお願いしてシェーダーにセットして、描画で使えるようにしましょう。

PSSetShadeResources関数で、ピクセルシェーダーのテクスチャスロットに画像をセットできます。テクスチャスロットとは簡単に言うと、テクスチャが入るロッカーみたいなものです。0~127の128個あります。合計128枚テクスチャを同時にロッカーに入れておけるのです。

このロッカーにテクスチャを入れておけば、シェーダーから簡単にテクスチャを使用することができるのです。

シェーダーでテクスチャから色を取得する

テクスチャスロットと言うロッカーにテクスチャを入れたので、実際にシェーダーからテクスチャを使用してみましょう。久々ですので覚えていますか?シェーダーのソースコードはSpriteShader.hlslというファイルです。

説明

// 0番のテクスチャスロットを使用する
Texture2D g_texture : register(t0);

ここで0番のロッカーに入っているテクスチャをg_textureという名前で使用します!って言ってます。

// 0番のサンプラスロットを使用する
SamplerState g_sampler : register(s0);

これはサンプラというものを使用するように言ってるとこです。サンプラはテクスチャから色を取得する道具のようなものです。この道具(サンプラ)の性能によって、色の取り方も変えることが出来ます。実は現在サンプラは作ってもないしセットもしてないのですが、一応動作するので今回はとりあえずこれで行きます。後ほど正式にサンプラも作っていきます。

// テクスチャから色を取得
float4 texColor = g_texture.Sample(g_sampler, float2(0.6, 0.6));

ここがテクスチャから色を取得している場所です。「g_textureからg_samplerの道具を使って(0.6, 0.6)の位置の色を取ってこい!」って命令です。この(0.6, 0.6)という座標は「UV座標」と言い、射影座標とはまた違った2Dの座標なんです。

射影座標とかUV座標とか、種類が多くて最初は覚えるのが大変ですね。

UV座標

UV座標とは、画像の左上を(0, 0)とし、画像の右下が(1, 1)の座標系です。画像のサイズは関係なしに0~1なのです。

ちなみにUnityでは、左下が(0,0)で右上が(1,1)です。混乱しそうですね。

実行結果

(0.6, 0.6)、つまり画像の真ん中ちょい右下あたりの、青っぽい色を取得して出力しています。

なんか違う

なんか思った結果と違いますね。ちゃんと画像全体をポリゴンに張り付けたいですよね。

次回は、きちんとポリゴンに画像が表示されるようにしていきたいと思います。

プログラムも増えてきたので、今回までのプロジェクトを下記からダウンロードできるようにしました。

おすすめ書籍

-C++, DirectX11, ゲームプログラミング, プログラミング
-, , , , , ,