Search code examples
c++direct3d10

How to do texture blending in Direct3D 10?


So far I've found out that you need to create a ID3D10BlendState object, call CreateBlendState() with a D3D10_BLEND_DESC struct, and call OMSetBlendState(). But I don't know how to call the Draw() functions and how to Apply() the textures. I have lightmap textures that I need to be blended with normal textures. Do I need multiple texture coordinates for the vertices? Do I need to draw each poly twice, once for the texture and once for the lightmap? I also don't really want to use texture arrays.

Thanks in advance.


Solution

  • There's no reason to use DirectX 10. DirectX 11 fully supplants it on all the same platforms (Windows Vista SP2 or later all support DirectX 11), and supports a wider range of video hardware. In addition, the only place to find DirectX 10 samples and utility code is in the legacy DirectX SDK. For DirectX 11, there are numerous open-source replacements for the old deprecated D3DX library, as well as samples.

    Direct3D 10 and later all use programmable shaders rather than the legacy 'fixed function' pipeline. Therefore, the way you'd implement light mapping is in a pixel shader written in HLSL:

    Texture2D<float4> Texture  : register(t0);
    Texture2D<float4> Texture2 : register(t1);
    
    sampler Sampler  : register(s0);
    sampler Sampler2 : register(s1);
    
    float4 PSDualTextureNoFog(PSInputTx2NoFog pin) : SV_Target0
    {
        float4 color = Texture.Sample(Sampler, pin.TexCoord);
        float4 overlay = Texture2.Sample(Sampler2, pin.TexCoord2);
    
        color.rgb *= 2; 
        color *= overlay * pin.Diffuse;
    
        return color;
    }
    

    You'd build this offline with FXC and then bind it at run-time along with a vertex shader. Typically for light-maps you'd use two texture coordinate sets in the input layout:

    const D3D11_INPUT_ELEMENT_DESC VertexPositionDualTexture::InputElements[] =
    {
        { "SV_Position", 0, DXGI_FORMAT_R32G32B32_FLOAT,    0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD",    0, DXGI_FORMAT_R32G32_FLOAT,       0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD",    1, DXGI_FORMAT_R32G32_FLOAT,       0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };
    

    A good place to start with C++ coding for DirectX 11 is the DirectX Tool Kit. It includes the DualTextureEffect which uses the shader above.