Meta-programming - examples
janderson
askme at me.com
Fri Feb 16 08:47:32 PST 2007
Here's another example:
.fx shaders contain shader constants which include float(1,2,3,4),
int(1,2,3,4), textures, matrices and other constants. To access these
parameters you can use a bulky interface (i'm doing this from memory so
the syntax may be 100%):
DXHANDLE ambient; //Create handle
effect->GetHandle(ambient, "ambient");
//ect..
//Get the value.
float[4] amb = effect->GetValue(ambient, sizeof(float[4]));
//Set the value
effect->SetFloat(ambient, amb, sizeof(float[4]));
Typically, you need to write this for ever shader. This can really
start to add up when you have 100's of shaders. These values are
normally data driven from some file (ie material). Also the rendering
code for each shader is typically boilerplate. Its even worse if you
try to optimize it into some sort of state-scene-graph to minimize state
switches. You can also get things like meta data from data types which
are useful for building gui's which represent the shader.
If you could wrap all this into a mixin that pulls information out from
the shader, it would be an awesome time saver. The boilerplate C++ code
(which would take me to long to design here) would still be written
mostly in C++.
//In D
mixin(shader!(import("boilerplateShader.d"), import("shader1.fx")));
...
//Shader.fx
float4 k_a <
string UIName = "Ambient";
> = float4( 0.47f, 0.47f, 0.47f, 1.0f ); // ambient
ect...
// transformations
float4x4 World : WORLD;
float4x4 View : VIEW;
float4x4 Projection : PROJECTION;
float4x4 WorldViewProj : WORLDVIEWPROJECTION;
float4x4 WorldView : WORLDVIEW;
//...
VS_OUTPUT VS(
float3 Pos : POSITION,
float3 col : COLOR,
float3 Norm : NORMAL,
float2 Tex : TEXCOORD0)
{
return ambient;
}
float4 PS(
float4 Diff : COLOR0,
float4 Spec : COLOR1,
float2 Tex : TEXCOORD0,
float2 Tex1 : TEXCOORD1 ) : COLOR
{
float4 color = Diff + Spec;
return color;
}
technique DefaultTechnique
{
pass P0
{
// shaders
VertexShader = compile vs_1_1 VS();
PixelShader = compile ps_1_1 PS();
}
}
Then you could interact with it like:
shader1 shader = StateTree.getShader1();
shader.ambient = {1, 0, 1};
//...
foreach (shadertype shtype; shader.types)
{
AddToGui(shtype);
}
ect...
Note that this would mean, that adding/removing properties for an fx
shader compiled at run-time would not be reflected however you normally
don't care (and you can still modify the shader real-time).
-Joel
More information about the Digitalmars-d
mailing list