Условный оператор в проходе HLSL - PullRequest
0 голосов
/ 03 января 2012

Согласно

http://msdn.microsoft.com/en-us/library/windows/desktop/bb509610(v=vs.85).aspx

HLSL поддерживает условный оператор (начиная с версии 2.0? Я использую 4_0)

Мне нужно установить состояние смешивания перед каждым вызовом Draw,В файле FX я делаю это:

BlendState BlendNone
{
    AlphaToCoverageEnable = FALSE;
    BlendEnable[0] = FALSE;
};
BlendState BlendSrcAlphaOne
{
    BlendEnable[0] = TRUE;
    SrcBlend = SRC_ALPHA;
    DestBlend = INV_SRC_ALPHA;
    BlendOp = ADD;
    RenderTargetWriteMask[0] = 0x0F;
};
BlendState BlendSrcAlphaOneMinusSrcAlpha
{
    BlendEnable[0] = TRUE;
    SrcBlend = SRC_ALPHA;
    DestBlend = ONE;
    BlendOp = ADD;
    RenderTargetWriteMask[0] = 0x0F;
};
int g_Blend;

technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( CompileShader( gs_4_0, GS() ) );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );

        SetRasterizerState(rsCullNone);
        SetDepthStencilState( EnableDepth, 0 );

        if (g_Blend == 0)
        {
            SetBlendState( BlendNone, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        }
        else if (g_Blend == 1)
        {
            SetBlendState( BlendSrcAlphaOne, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        }
        else if (g_Blend == 2)
        {
            SetBlendState( BlendSrcAlphaOneMinusSrcAlpha, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        }
    }
}

Это не компилируется с ошибкой: ошибка X3000: синтаксическая ошибка: неожиданный токен 'if'

Если я переместить весь блок вотдельная функция типа:

void setBlend()
{
        if (g_Blend == 0)
        {
            SetBlendState( BlendNone, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        }
        else if (g_Blend == 1)
        {
            SetBlendState( BlendSrcAlphaOne, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        }
        else if (g_Blend == 2)
        {
            SetBlendState( BlendSrcAlphaOneMinusSrcAlpha, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        }
}

technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( CompileShader( gs_4_0, GS() ) );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );

        SetRasterizerState(rsCullNone);
        SetDepthStencilState( EnableDepth, 0 );

        setBlend();
    }
}

не компилируется с ошибкой: ошибка X3000: этот FX API недоступен в этой части вашей программы (SetBlendState)

Так что, если поддерживается вHLSL?

1 Ответ

2 голосов
/ 04 января 2012

Хорошо, после множества попыток и чтения http://msdn.microsoft.com/en-us/library/windows/desktop/bb205052(v=vs.85).aspx#Blend

Это компилируется:

BlendState blendStates[3]
{
    {
        AlphaToCoverageEnable = FALSE;
        BlendEnable[0] = FALSE;
    },
    {
        BlendEnable[0] = TRUE;
        SrcBlend = SRC_ALPHA;
        DestBlend = INV_SRC_ALPHA;
        BlendOp = ADD;
        RenderTargetWriteMask[0] = 0x0F;
    },
    {
        BlendEnable[0] = TRUE;
        SrcBlend = SRC_ALPHA;
        DestBlend = ONE;
        BlendOp = ADD;
        RenderTargetWriteMask[0] = 0x0F;
    }
};
int g_Blend;

technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( CompileShader( gs_4_0, GS() ) );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );

        SetRasterizerState(rsCullNone);
        SetDepthStencilState( EnableDepth, 0 );

        SetBlendState( blendStates[g_Blend], float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    }
}

SetBlendState не является строго вызовом функции, и условные операторы не допускаются внутри прохода {}. Однако разрешено передавать массив объектов состояния с индексом, а не только объекты состояния.

...