I’ve been looking into the DX utility library, and it has a nice way of constructing vertex/pixel shaders, with things called ‘effects’. They’re basically shader files which can define multiple ways of achieving a particular effect (such as diffuse+specular bumpmapping in 2 or 4 texture units).
I think glu should be expanded to include something like this.
What do you think?
Here’s an example of an effect that can add to 2 textures together with or without 2 texture units:-
Step 1: Define an effects file…
//
// Sample Effect
// This effect adds two textures, using single pass or multipass technique.
//texture tex0;
texture tex1;
// Single pass
technique t0
{
pass p0
{
Texture[0] = ;
Texture[1] = ;ColorOp[0] = SelectArg1; ColorArg1[0] = Texture; ColorOp[1] = Add; ColorArg1[1] = Texture; ColorArg2[1] = Current; ColorOp[2] = Disable; }
}
// Multipass
technique t1
{
pass p0
{
Texture[0] = ;ColorOp[0] = SelectArg1; ColorArg1[0] = Texture; ColorOp[1] = Disable; } pass p1 { AlphaBlendEnable = True; SrcBlend = One; DestBlend = One; Texture[0] = <tex1>; ColorOp[0] = SelectArg1; ColorArg1[0] = Texture; ColorOp[1] = Disable; }
}
Step 2: Load the Effect File
{
HRESULT hr;
D3DXTECHNIQUE_DESC technique;
ID3DXEffect m_pEffect;// Assumes that m_pd3dDevice has been initialized if(FAILED(hr = D3DXCreateEffectFromFile(m_pd3dDevice, "effect.fx", &m_pEffect, NULL))) return hr; if(FAILED(hr = FindNextValidTechnique(NULL, &technique))) return hr; m_pEffect->SetTechnique(technique.Index); m_pEffect->SetTexture("tex0", m_pTexture0); m_pEffect->SetTexture("tex1", m_pTexture1);
}
Once the effect file is created, ID3DXEffect::FindNextValidTechnique returns a technique that has been validated on the hardware.
Step 3: Render the Effect
{
HRESULT hr;
UINT uPasses;if(FAILED(hr = m_pd3dDevice->SetStreamSource(0, m_pVB, sizeof(CUSTOMVERTEX_POS_NORM_COLOR1_TEX1)))) return hr; m_pEffect->Begin(&uPasses, 0 );
// The 0 specifies that ID3DXEffect::Begin and ID3DXEffect::End will
// save and restore all state modified by the effect.for(UINT uPass = 0; uPass < uPasses; uPass++) { // Set the state for a particular pass in a technique m_pEffect->Pass(uPass); m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, dwNumSphereVerts - 2); } m_pEffect->End();
}