February 12, 2007
janderson wrote:
> A couple of people have been asking questions about pseudo-real-life examples for the new compile time code aspects of D.  I ask this question for my interest as well.
> 
> Assuming that we have a good mechanism to process the input how could compile time code improve your every-day proficiency?

What about string enums, this could be done with reflection however you could do something like this now:

mixin(
Enum!("Colours",
"Red",
"Blue",
"Green"
));

//Or flags
mixin(
Flags!("Colours",
"Red",
"Blue",
"Green"
));

Colours c;
...
char[] str = ToString(c);

-Joel
February 16, 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
1 2 3
Next ›   Last »