Texture

キューブにテクスチャを張り付けて描画します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

TextureLoader Class

  1. Texture Cube では、キューブにテクスチャ座標を追加しました。
    残念ながらこのときはテクスチャ座標を使わずに「頂点座標+法線」で描画しています。
    今回は、キューブにテクスチャ画像を張り付けて描画してみましょう。 \(^o^)/
  2. Microsoft のサンプルプログラムでは、テクスチャ画像のロードに BasicLoader Class の LoadTexture() を使っています。
    BasicLoader は便利な Class で、テクスチャだけで無く、Shader や Mesh もロードすることが出来ます。
    また BasicShapes Class も組み込まれていて、3Dモデルを生成することも出来ます。
    所が BasicLoader を組み込もうとすると、次々と関連ファイルが現われて、訳がわからなくなります。
    そこで、テクスチャだけをロードする単純な TextureLoader Class を作成することにしました。
    TextureLoader Class では DDS(DirectX の独自形式)は使えません。
    GIF, JPEG, BMP ファイルなどを使って下さい。
    TextureLoader Class のソースコード(TextureLoader.h, TextureLoader.cpp)は Win10 TexBox を参照して下さい。
  3. プログラムの内容を少しだけ説明しましょう。
    テクスチャ画像の入力に BasicReaderWriter(DirectX の基本入出力)を使っています。
    Constructor で ID3D11Device と IWICImagingFactory2 を受け取ります。
    IWICImagingFactory2 が nullptr のときは、既定の値を設定します。
    LoadTexture() がテクスチャをロードするメソッドです。
        Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_textureSRV;
    
        TextureLoader^ loader =
            ref new TextureLoader(m_deviceResources->GetD3DDevice());
        loader->LoadTexture(L"Star.jpg", nullptr, &m_textureSRV );
    

プロジェクトの設定

  1. Texture Cube のプロジェクトをベースにします。
    Content\ のフォルダに次のファイルを格納して、プロジェクトに加えて下さい。
    BasicReaderWriter は Windows10 DirectX Library を参照して下さい。
    また Win10 TexBox にも掲載しています。
  2. Star.jpg(画像は問わない)をフォルダのルートにコピーします。
    ソリューションエクスプローラでプロジェクトに追加すると Assets\Star.jpg に登録されます。
    但し、呼び出すときはそのまま L"Star.jpg" とします。
  3. Content\Sample3DSceneRenderer.h の private: に次の行を追加します。
        Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_textureSRV;
        Microsoft::WRL::ComPtr<ID3D11SamplerState>  m_sampler;
    
  4. Content\Sample3DSceneRenderer.cpp を修正します。
    ヘッダーの追加です。
    #include "TextureLoader.h"
    
    CreateDeviceDependentResources() の最後に追加します。
    "Star.jpg" がロードされて m_textureSRV に設定されます。
        TextureLoader^ loader =
            ref new TextureLoader(m_deviceResources->GetD3DDevice());
        loader->LoadTexture(L"Star.jpg", nullptr, &m_textureSRV );
    
    Texture の次に Sampler を設定します。
        // create the sampler
        D3D11_SAMPLER_DESC samplerDesc;
        ZeroMemory(&samplerDesc, sizeof(D3D11_SAMPLER_DESC));
        samplerDesc.Filter = D3D11_FILTER_ANISOTROPIC;
        samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
        samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
        samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
        samplerDesc.MipLODBias = 0.0f;
        samplerDesc.MaxAnisotropy = 2;
        samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
        samplerDesc.BorderColor[0] = 0.0f;
        samplerDesc.BorderColor[1] = 0.0f;
        samplerDesc.BorderColor[2] = 0.0f;
        samplerDesc.BorderColor[3] = 0.0f;
        samplerDesc.MinLOD = 0;
        samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
    
        DX::ThrowIfFailed(
            m_deviceResources->GetD3DDevice()->CreateSamplerState(
                &samplerDesc, &m_sampler) );
    
  5. テクスチャを張り付ける準備が整いました。
    現在の状態で実行すると、法線ベクトルが設定されたキューブ(テクスチャ無し)が回転しながら描画されます。

テクスチャを描画

  1. いよいよキューブにテクスチャを張り付けて描画します。
    準備が整っているので、後は簡単です。
  2. Content\Sample3DSceneRenderer.cpp の Render() メソッドでテクスチャを設定します。
    m_textureSRV にはテクスチャ画像が読み込まれています。
        context->PSSetShaderResources(0, 1, m_textureSRV.GetAddressOf());
        context->PSSetSamplers(0, 1, m_sampler.GetAddressOf());
        //※この位置(DrawIndexed の直前)に追加
        context->DrawIndexed(m_indexCount, 0, 0);
    
  3. テクスチャを張り付けて描画するように Shader を書き換えます。
    SamplePixelShader.hlsl です。
    struct PixelShaderInput
    {
        float4 pos : SV_POSITION;
        float3 norm : NORMAL;
        float2 tex : TEXCOORD0;
    };
    
    float4 main(PixelShaderInput input) : SV_TARGET
    {
        float3 lightDirection = normalize(float3(1, -1, 0));
        float lightMagnitude = 0.8f * saturate(dot( input.norm, -lightDirection)) + 0.2f;
        return float4(1,1,0.2,1) * lightMagnitude;
    }
    
    テクスチャを張り付ける SampleVertexShader.hlsl です。
    cbuffer ModelViewProjectionConstantBuffer : register(b0)
    {
        matrix model;
        matrix view;
        matrix projection;
    };
    
    struct VertexShaderInput
    {
        float3 pos : POSITION;
        float3 norm : NORMAL;
        float2 tex : TEXCOORD0;
    };
    
    struct VertexShaderOutput
    {
        float4 pos : SV_POSITION;
        float3 norm : NORMAL;
        float2 tex : TEXCOORD0;
    };
    
    VertexShaderOutput main(VertexShaderInput input)
    {
        VertexShaderOutput output;
        float4 pos = float4(input.pos, 1.0f);
    
        // Transform the vertex position into projected space.
        pos = mul(pos, model);
        pos = mul(pos, view);
        pos = mul(pos, projection);
        output.pos = pos;
        output.tex = input.tex;
    
        float4 norm = float4(normalize(input.norm), 0.0f);
        norm = mul(norm, model);
        output.norm = normalize(norm.xyz);
        return output;
    }
    
  4. コンパイルして実行すると、ページ先頭の画像のようにテクスチャが張り付けられて描画されます。
    但し、テクスチャは一枚しかロードしていないので1種類だけです。

超初心者のプログラム入門(DirectX Store)