3

Well basically,I'm not quite sure how to properly use the Set and Get Parameter methods in DX to use the .fx files.I mean I can't find a good tutorial anywhere.I even had a book about D3D9 and while I got most of it,I'm still unable to use effect files.What's worse is the DirectX Samples provided by microsoft are packed with some DX Utility classes by microsoft and all sorts of other needless complications and I can't quite get it trough the 2k lines of code.I mean I get the basic idea(load,begin,loop with passes,end),but can anyone please point me out to a good tutorial on some simple example.The main thing I don't understand is how to work with the effect parameters :(

Vio Lence
  • 49
  • 1
  • 3

2 Answers2

3

Here is a reference sheet I wrote back when I was first learning how to use HLSL shaders in DirectX9. Perhaps it will be of assistance.

IN THE APPLICATION:
Declare needed variables:

ID3DXEffect*                shader;


Load the .fx file:

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


Clean up the effect object (some people use a SAFE_RELEASE macro):

if(shader)
    shader->Release();
shader = nullptr;


Use the shader to render something:

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();
}


IN THE .FX FILE:
Declare the uniforms (variables you want to set from within the application):

float4x4    gWorld      : WORLD;
float4x4    gViewProj   : VIEWPROJECTION;
float       gTime       : TIME;

Texture2D   gDiffuseTexture;                // requires a matching sampler
sampler gDiffuseSampler = sampler_state     // here's the matching sampler
{
    Texture = <gDiffuseTexture>;
    FILTER = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};


Define the vertex shader input structure:

struct VS_INPUT     // make this match the vertex structure in Application
{
    float3 untransformed_pos        : POSITION0;
    float3 untransformed_nrm        : NORMAL0;
    float4 color                    : COLOR0;
    float2 uv_coords                : TEXCOORD0;
};


Define the pixel shader input structure (vertex shader output):

struct PS_INPUT
{
    float4 transformed_pos          : POSITION0;
    float4 transformed_nrm          : NORMAL0;
    float4 color                    : COLOR0;
    float2 uv_coords                : TEXCOORD0;
};


Define a vertex shader:

PS_INPUT    mainVS  (VS_INPUT input)
{
    PS_INPUT output;

    /* Insert shader instructions here */

    return output;
}


Define a pixel shader:

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

    return float4(resultColor,1.0f);
}


Define a technique:

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.
    }
}
derpface
  • 1,611
  • 1
  • 10
  • 20
  • This is great! However, I am confused about the functions itself. When you have a vertex shader, don't you need to know the positions around you to set the vertex correctly? How do you do that? – Mathew Kurian Sep 27 '13 at 13:30
  • The vertices passed in will be in the object's local space. The uniforms at the top of the shader (world, view, projection, etc.) can be used to transform them, and they come from both the object to be drawn and the camera that's viewing it. For more details, look up "vertex transformation pipeline" or pick up pretty much any shader cookbook or tutorial. – derpface Sep 28 '13 at 16:43
1

Can you be a bit more specific about where you're having problems?

The basic idea with the API for Effect parameters is to load your .fx file and then use ID3DXEffect::GetParameterByName() or GetParameterBySemantic() to retrieve a D3DXHANDLE to the parameters you want to modify at runtime. Then in your render loop you can set the values for those parameters using the ID3DXEffect::SetXXX() family of functions (which one you use depends on the type of the parameter you are setting, e.g. Float, Vector, Matrix), passing the D3DXHANDLE you retrieved when you loaded the effect.

The reason you work with D3DXHANDLEs and not directly with parameter name strings is performance - it saves doing lots of string compares in your render loop to look up parameters.

A simple example of how you might use this is defining a texture2D parameter called diffuseTex in your .fx file. When you load the .fx file, use

D3DXHANDLE diffuseTexHandle = effect->GetParameterByName(NULL, "diffuseTex");

and then in your render loop set the appropriate diffuse texture for each model you draw using

LPDIRECT3DTEXTURE9 diffuseTexturePtr = GetMeTheRightTexturePlease(); ID3DXEffect::SetTexture(diffuseTexHandle, diffuseTexturePtr);

mattnewport
  • 13,728
  • 2
  • 35
  • 39
  • yeah,so basically diffuseTexturePtr can be my model's texture and basically the effect works on my model's appereance this way? – Vio Lence Feb 01 '12 at 12:18
  • Yes, effect parameters allow you to use the same basic effect on different models with different values for things like textures, colors, specular / gloss factors or whatever else your .fx file exposes as a configurable parameter. So you might have a spaceship.fx file and render multiple different spaceship models using the same Effect with different parameters. – mattnewport Feb 01 '12 at 21:54