关于C+;中DirectX9中使用的.fx文件和着色器的一般混淆+;-你到底是如何与应用程序建立连接的?

关于C+;中DirectX9中使用的.fx文件和着色器的一般混淆+;-你到底是如何与应用程序建立连接的?,directx,effects,hlsl,Directx,Effects,Hlsl,基本上,我不太确定如何正确使用DX中的Set和Get参数方法来使用.fx文件。我的意思是,我在任何地方都找不到好的教程。我甚至有一本关于D3D9的书,虽然我得到了大部分,我仍然无法使用效果文件。更糟糕的是,microsoft提供的DirectX示例中包含了microsoft提供的一些DX实用程序类和其他各种不必要的复杂内容,我无法通过2k行代码完全理解。我的意思是我得到了基本想法(加载、开始、循环、结束),但是有谁能给我指出一个关于一些简单例子的很好的教程吗?我不明白的主要问题是如何使用效果参数

基本上,我不太确定如何正确使用DX中的Set和Get参数方法来使用.fx文件。我的意思是,我在任何地方都找不到好的教程。我甚至有一本关于D3D9的书,虽然我得到了大部分,我仍然无法使用效果文件。更糟糕的是,microsoft提供的DirectX示例中包含了microsoft提供的一些DX实用程序类和其他各种不必要的复杂内容,我无法通过2k行代码完全理解。我的意思是我得到了基本想法(加载、开始、循环、结束),但是有谁能给我指出一个关于一些简单例子的很好的教程吗?我不明白的主要问题是如何使用效果参数:(

你能更具体一点你遇到问题的地方吗

API for Effect参数的基本思想是加载.fx文件,然后使用
ID3DXEffect::GetParameterByName()
GetParameterBySemantic()
检索运行时要修改的参数的
D3DXHANDLE
。然后在渲染循环中,可以使用
ID3DXEffect::SetXXX()
函数族设置这些参数的值(使用哪一个函数取决于正在设置的参数的类型,例如Float、Vector、Matrix),传递加载效果时检索到的
D3DXHANDLE

使用
D3DXHANDLE
s而不直接使用参数名称字符串的原因是性能-它可以节省在渲染循环中进行大量字符串比较以查找参数的时间

关于如何使用它的一个简单示例是在.fx文件中定义名为
diffuseTex
texture2D
参数。加载.fx文件时,请使用

D3DXHANDLE diffusetexthandle=effect->GetParameterByName(NULL,“diffuseTex”);

然后在渲染循环中,为使用绘制的每个模型设置适当的漫反射纹理

LPDIRECT3DTEXTURE9 diffuseTexturePtr=GetMeTheRightTexturePlease();

ID3DXEffect::SetTexture(DiffuseTextHandle,DiffuseTexturePter);

这是我第一次学习如何在DirectX9中使用HLSL着色器时写的参考资料。也许它会有所帮助

在应用程序中:
声明所需的变量:

ID3DXEffect*                shader;

加载.fx文件:

D3DXCreateEffectFromFile(   d3dDevice,
                            _T("filepath.fx"),
                            0,
                            0,
                            0,
                            0,
                            &shader,
                            0
                        );

清理效果对象(有些人使用安全释放宏):


使用着色器渲染某些内容:

void Application::Render()
{
    unsigned passes = 0;
    shader->Begin(&passes,0);
    for(unsigned i=0;i<passes;++i)
    {
        shader->BeginPass(i);

        // Set uniforms
        shader->SetMatrix("gWorld",&theMatrix);
        shader->CommitChanges();    // Not necessary if SetWhatevers are done OUTSIDE of a BeginPass/EndPass pair.

        /* Insert rendering instructions here */
        // BEGIN EXAMPLE:

            d3dDevice->SetVertexDeclaration(vertexDecl);
            d3dDevice->SetStreamSource(0,vertexBuffer,0,sizeof(VERT));

            d3dDevice->SetIndices(indexBuffer);

            d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,numVerts,0,8);

        // END EXAMPLE

        shader->EndPass();
    }
    shader->End();
}

定义像素着色器输入结构(顶点着色器输出):


定义顶点着色器:

PS_INPUT    mainVS  (VS_INPUT input)
{
    PS_INPUT output;

    /* Insert shader instructions here */

    return output;
}

定义像素着色器:

float4      mainPS  (PS_INPUT input)    : COLOR
{
    /* Insert shader instructions here */

    return float4(resultColor,1.0f);
}

定义一种技术:

technique myTechnique
{
    // Here is a quick sample
    pass FirstPass
    {
        vertexShader = compile vs_3_0 mainVS();
        pixelShader  = compile ps_3_0 mainPS();

        // Setting a few of the many D3D renderstates via the effect framework
        ShadeMode = FLAT; // flat color interpolation across triangles
        FillMode = SOLID; // no wireframes, no point drawing.
        CullMode = CCW; // cull any counter-clockwise polygons.
    }
}

是的,所以基本上diffuseTexturePtr可以是我的模型的纹理,基本上效果是这样作用于我的模型的外观的?是的,效果参数允许你在不同的模型上使用相同的基本效果,具有不同的值,比如纹理、颜色、镜面反射/光泽因子或者你的.fx文件作为可配置pa公开的任何其他内容rameter。因此,您可能有一个spaceship.fx文件,并使用不同的参数使用相同的效果渲染多个不同的飞船模型。这很好!但是,我对函数本身感到困惑。当您有顶点着色器时,您不需要知道周围的位置以正确设置顶点吗?如何做到这一点?顶点passed in将位于对象的局部空间。着色器顶部的制服(世界、视图、投影等)可用于变换它们,它们来自要绘制的对象和正在查看它的摄影机。有关更多详细信息,请查阅“顶点变换管道”或几乎任何着色器食谱或教程。
struct PS_INPUT
{
    float4 transformed_pos          : POSITION0;
    float4 transformed_nrm          : NORMAL0;
    float4 color                    : COLOR0;
    float2 uv_coords                : TEXCOORD0;
};
PS_INPUT    mainVS  (VS_INPUT input)
{
    PS_INPUT output;

    /* Insert shader instructions here */

    return output;
}
float4      mainPS  (PS_INPUT input)    : COLOR
{
    /* Insert shader instructions here */

    return float4(resultColor,1.0f);
}
technique myTechnique
{
    // Here is a quick sample
    pass FirstPass
    {
        vertexShader = compile vs_3_0 mainVS();
        pixelShader  = compile ps_3_0 mainPS();

        // Setting a few of the many D3D renderstates via the effect framework
        ShadeMode = FLAT; // flat color interpolation across triangles
        FillMode = SOLID; // no wireframes, no point drawing.
        CullMode = CCW; // cull any counter-clockwise polygons.
    }
}