Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

DirectXでリソースファイルから画像を描画する

DirectXでゲームを作っているんですが、大体のゲームはゲームフォルダ内に著作権保護の理由などで画像ファイルや音楽ファイルなどの素材が入っていません。
私も自分の素材を直接ゲームフォルダに置くのは抵抗があります。
そこでリソースファイルというものに行き着きました。
ファイルをアプリケーションファイルに埋め込めるそうなのですが、画像などを追加する方法はわかりました。
しかし、DirectXを用いて実際に画像を表示する方法がわか入りません。
誰か教えていただけると幸いです。

開発環境は、
OS WindowsXP SP3
Build VisualStudio2010Express
ResourceEditor ResEdit
です。

0 likes

1Answer

FindResourceでリソースを探したあとにLoadResourceで読み込んで、LockResourceでリソースデータへのポインタを得ればそこから先は普通のファイルと同じようにフォーマットごとにデコードしてDirectXでテクスチャとして準備すれば扱えると思います。
https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-findresourcea
https://docs.microsoft.com/ja-jp/windows/win32/api/libloaderapi/nf-libloaderapi-loadresource
https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-lockresource

画像データをDirectXで描画するのは、DirectXのバージョンによって方法がちょっと変わるのでこの情報だけだとちょっと回答できないです(WindowsXPだとDirectX9かなとは思いますが)

ちなみになんですが、実行ファイルのリソース領域にデータを置いたところで普通に引っこ抜けてしまうので、本気で見えなくしたいならリソース領域におくというよりは暗号化や難読化を施したほうがよいかなと思います。

1Like

Comments

  1. @MZK_Nal0104

    Questioner

    ご回答有難うございます。
    開発環境を詳しく書きます
    OS:WindowsXP SP3
    DirectX:DirectX9.0c
    VisualStudio:VisualStudio2010

    本格的に隠したいというよりは、
    ゲームフォルダ内を整理したいという感じです。
  2. DirectX9だと、ちょうどおあつらえむきの関数がD3DXにあるみたいです。
    http://marupeke296.com/DXG_CreateTextureMethod.html
    ここにあるD3DXCreateTextureFromResourceを使うと、リソース領域の画像データから一発でIDirect3DTexture9を生成することができます。この関数は見た感じFindResource~LockResourceまでも勝手にやってくれるみたいです。

    DirectX9では近年のAPIとは違って、IDirect3DTexture9さえできればあとはそれをそのまま `IDirect3DDevice9::SetTexture` で設定するだけでいい感じに平面メッシュに貼り付けて描画してくれるみたいです。
    ただいくらいい感じに貼り付けてくれるとはいってもUV値が設定されてなければ正しく貼り付けられないので、頂点データに正しくUV値を入れて上げる必要があります。
    今どのような感じで頂点データを用意しているかはわかりませんが、DirectX9ならほぼ`IDirect3DDevice9::SetFVF` を使ってると思うのでD3DFVF_TEX0を追加で含むようにしてあげればUV値が認識されるはずです。
  3. @MZK_Nal0104

    Questioner

    D3DXCreateTextureFromResourceがうまく画像を読み込んでくれません。
    HRESULT hres = D3DXCreateTextureFromResource(......);
    if (hres == NULL){return 0;}
    のようにエラーの際に処理を止めているのですが、問題なく通過します。
    しかし実際に描画するとテクスチャのない白いポリゴンが表示されます。
    なぜでしょうか、ResEditがうまく画像をresource.rcに追加していないのでしょうか?
  4. この使い方ははじめて見たんですが、HRESULTの取り扱い方ってこれであってましたっけ?
  5. @MZK_Nal0104

    Questioner

    はいあってると思います。
    それか
    if(FAILED(D3DXCreateTextureFromResource(......))){return 0;}
    みたいにすればいいと思います。
  6. == NULL と FAILED(...) って全然違くて、前者は比較対象が間違ってるので上のコードは if (FAILED(hres)){return 0;} が正しいです。
    で、こうすると意味が正反対になるはずなので、つまりテクスチャの作成に失敗しています。
    リソース名とか確認してみると良いかもです。
  7. @MZK_Nal0104

    Questioner

    ご指摘ありがとうございます。
    エラー確認の方法を変えてみましたが、やはりPNGを読み込めていないみたいです。
    ダイアログが表示できるのでリソースの読み込みはできています。
    IDなども一語一句間違っていません。
    何が行けないのでしょうか...
  8. D3DXCreateTextureFromResourceの返り値は何が帰ってきていますか?printfなりOutputDebugStringなりで出力してみるとそれがヒントになるかもです。
    あとはリソースのタイプが間違えているとかですかね。リソースファイルの中身がわからないのでここは完全に勘なんですが、ドキュメントを見た感じだと、PNGファイルの場合はRT_RCDATAで入れないといけないみたいです。
  9. @MZK_Nal0104

    Questioner

    NULLが返ってきているみたいです。
    IDR_IMAGE RT_RCDATA "test.png"
    のようにしましたがダメみたいです。
  10. 返り値はそこじゃなくて
    HRESULT hres = D3DXCreateTextureFromResource(......);
    の hres の値が何になっているかです……
  11. @MZK_Nal0104

    Questioner

    ブレークポイントをリソースの読み込みの直後に設定したところ
    hres -2005529767 HRESULT
    のようになっています。
    返信が遅くなりすみません。
  12. @MZK_Nal0104

    Questioner

    ありがとうございます!!!!
    行けました!

Your answer might help someone💌