none
DirectX / テクスチャを貼り付けたメッシュと,色指定のメッシュを同時に表示させたい RRS feed

  • 質問

  • お世話になります。よろしくお願いいたします。

    VB2008+DirectX9.0cで3次元図を作成するアプリケーションを開発しています。

    Dim Vdata_C(n) As Direct3D.CustomVertex.PositionNormalColored

    として座標と色のデータを格納して作図すると下図のようになるアプリケーションを開発しました。

    上図の青いメッシュにテクスチャを貼り付けるため,青いメッシュだけを

    Dim Vdata_T(n) As Direct3D.CustomVertex.PositionNormalTextured

    として座標とテクスチャ上の位置を格納してテクスチャを貼って作図すると,下図のようになってしまいます。

    上図のピンク色のメッシュ(実際にはこのようなメッシュが10個以上あったりします。テクスチャを貼るメッシュは1枚だけです)の表示を変えずに青いメッシュにテクスチャを貼りたいのですが,

    (1)DirectX9.0cではこれは可能でしょうか。

    (2)可能な場合は,そのための勘所をご教示ください。

    (3)できない場合は,DirectX11ではできるでしょうか。

    以上,ご助力頂ければ幸いです。返信は来週月曜日以降になります。

    2016年7月22日 6:39

回答

  • 開発環境の情報およびソースコードをきちんと開示してください。
    多分Managed DirectXを使っているのだと思いますが、プログラマブルシェーダーは使わずに固定機能シェーダーを使っているのでしょうか? いずれにせよ、メッシュサブセットをレンダリングする際に、頂点データに合わせた頂点フォーマット(FVF)もしくは頂点宣言をデバイスに正しくセットしてからドローコールしていますか?
    ちなみに3Dグラフィックスを描画することをRendering(レンダリング)と呼びますが、「作図」とは言いません。普段から分野ごとの正しい用語や共通語を使うように心がけておけば、意思疎通を図ったり、情報収集したりするときに困りません。
    2016年7月24日 22:23

すべての返信

  • 開発環境の情報およびソースコードをきちんと開示してください。
    多分Managed DirectXを使っているのだと思いますが、プログラマブルシェーダーは使わずに固定機能シェーダーを使っているのでしょうか? いずれにせよ、メッシュサブセットをレンダリングする際に、頂点データに合わせた頂点フォーマット(FVF)もしくは頂点宣言をデバイスに正しくセットしてからドローコールしていますか?
    ちなみに3Dグラフィックスを描画することをRendering(レンダリング)と呼びますが、「作図」とは言いません。普段から分野ごとの正しい用語や共通語を使うように心がけておけば、意思疎通を図ったり、情報収集したりするときに困りません。
    2016年7月24日 22:23
  • 解決しました。「VB2005ユーザーのためのDirect3D入門」という書籍のサンプルプログラムを使っていますので、書籍の著作権を侵さない程度にソースコードを開示したいと思います。

    まず、色指定とテクスチャでは,先日提示したとおり,以下のようにVdataの宣言を変えます。

    Dim Vdata_C(n) As Direct3D.CustomVertex.PositionNormalColored
    ↓
    Dim Vdata_T(n) As Direct3D.CustomVertex.PositionNormalTextured

    値の代入はこのように変わります。***には適切な値を入れてください。

    With Vdata_C(i)
        .X = ***
        .Y = ***
        .Z = ***
        .Color = ***
    End With
    ↓
    With Vdata_T(i)
        .X = ***
        .Y = ***
        .Z = ***
        .Tu = ***
        .Tv = ***
    End With

    メッシュの実体の作成時は次のようになります。

    imMesh(i) = New Direct3D.Mesh(***, ***, 0, Direct3D.CustomVertex.PositionNormalColored.Format, D3DDevice)
    ↓
    imMesh(i) = New Direct3D.Mesh(***, ***, 0, Direct3D.CustomVertex.PositionNormalTextured.Format, D3DDevice)

    上記までは質問時点で分かっていました。以下のやり方が分かっていませんでした。添字が3のメッシュにテクスチャを貼り付ける場合のサンプルです。

    Dim t As Direct3D.Texture = Nothing
    Dim oldm As Direct3D.Material = D3DDevice.Material ''現在のマテリアルの保存
    Dim m As Direct3D.Material
    
    For i As Integer = 0 To imMesh.Length - 1
        If i = 3 Then
            ''マテリアルの更新
            If gTextureProp.Inei = 0 Then
                ''テクスチャに陰影を付けたくないとき
                m.Diffuse = Color.White
                m.Ambient = Color.Black
                m.Emissive = Color.White
            Else
                ''テクスチャに陰影を付けたいとき
                m.Diffuse = Color.White
                m.Ambient = Color.White
                m.Emissive = Color.Black
            End If
            D3DDevice.Material = m
            ''テクスチャを貼り付ける
            t = Direct3D.TextureLoader.FromFile(D3DDevice, f)
            D3DDevice.SetTexture(0, t)
        End If
    
        ''メッシュを描く
        imMesh(i).DrawSubset(0)
    
        If i = 3 Then
            ''tをDisposeしないとメモリーリークする
            t.Dispose()
            t = Nothing
            ''テクスチャをはがす
            D3DDevice.SetTexture(0, Nothing)
            ''マテリアルの復元
            D3DDevice.Material = oldm
        End If
    Next i
    sygh様にご教示頂いた「メッシュサブセットをレンダリングする際に」という言葉を頼りにここまで来ましたので、回答としてマークさせて頂きます。ありがとうございました。

    古い開発環境でのことですので、あまり皆様のお役には立たないかもしれませんが、折角ですので投稿させていいただきます。

    2016年7月27日 0:51