Package my effect in DX

Recommended Posts

mylrex    100
I would like to create a effect class in DX, but I don't know how to set parameters quickly acrodding their names.And I must use D3DXHANDLE. In XNA: expEffect.Parameters["Projection"].SetValue(camera.ProjectionMatrix); That's what I want above... What I mean is that how to associate D3DXHANDLE and patameters and just transfer data into shader from theri names when rendering.

Share this post

Share on other sites
MJP    19754
You can pass a string instead of a D3DXHANDLE if you want.
effect->SetVector("LightColor", &lightColor);

You can also retrieve handles and cache them.
// During initializationlightColorHandle = effect->GetParameterByName(NULL, "LightColor");// During runtimeeffect->SetVector(lightColorHandle, &lightColor);

Share this post

Share on other sites
mylrex    100
After packaging my shader class,I pass them looks like below:

Shader g_shader;
D3DXMATRIX world;
g_shader->setParemeters("gWorld",&world);

But I must search for the handleWorld by chars "gWorld",that's ineffective.
How do I avoid the search?

Share this post

Share on other sites
Jason Z    6434
MJP showed you how to do it above - you basically ask for the handle with the character based name, which returns a handle object. Then you can use the handle from that point onward to set the objects.

Share this post

Share on other sites
mylrex    100
As MJP said:
effect->SetVector("LightColor", &lightColor);
that's ineffective also,and that's why I use D3DXHANDLE.

struct Handle
{
char* name;
D3DXHANDLE handle;
}handle[MAX_NUM];

void MyShader::addParemeters(char* _p)
{
handle[i].name = _p;
handle[i].handle= effect->GetParameterByName(NULL, _p);
totalOfPar++;
}

void MyShader::setParemeters(char* _p, D3DXMATRIX* _m)
{
for(i=0;i<totalOfPar;i++)
{
if(strcmp(handle[i].name,_p))
effect->SetVector(handle[i].handle, &_m);
}
}

How can I avoid the "for" Circulation or the search?

Share this post

Share on other sites
Jason Z    6434
EDIT: sorry, I misread what you have written. So you want to set all parameters with a single call, is that the idea? If so, I think you would need to use DX10 or DX11 to use constant buffers. It sounds like you are using DX9, so I'm not sure there is a solution for that...

Share this post

Share on other sites
Nik02    4348
Actually, you can set multiple adjacent constants with a single call in D3D9 as well. Set*ShaderConstants* methods have a parameter specifying how many registers you want to set.

You'd have to figure out the offsets of the variables and put your parameters in a structure that is perfectly equivalent to the register layout that you define in HLSL. The ID3DXConstantTable object can be used to calculate the registers corresponding to given variables. Note that the Effect framework already does this for you. And since the constant tables are static after the effect creation, it is very fast to access variables by handle anyway.

You can also force your HLSL variables to use particular registers, so you don't have to do the lookup from the host program. The syntax for a constant is as follows:

float4 example : register(c0); //variable "example" uses constant register 0.float2 anotherExample: register (c1); //you get the idea......

Then you could set both of these with a single call to Set*ShaderConstantsF, since they are adjacent in the register layout.

In D3D9, you have to use separate registers for vertex and pixel shaders since the API doesn't have the notion of unified pipeline architecture. Also, integer, float and bool registers have their own logical banks. And finally, there is only one bank of constant registers per the three datatypes per shader stage. This is in contrast to D3D10 and up, where there is several general-purpose constant buffers that can store any datatype.

Share this post

Share on other sites
mylrex    100
Quote:
 Original post by Jason ZEDIT: sorry, I misread what you have written. So you want to set all parameters with a single call, is that the idea? If so, I think you would need to use DX10 or DX11 to use constant buffers. It sounds like you are using DX9, so I'm not sure there is a solution for that...

Thanks for JZ's reminder,I haven't learnt DX10 11 ,I must study hard..

Share this post

Share on other sites
mylrex    100
Quote:
 Original post by Nik02Actually, you can set multiple adjacent constants with a single call in D3D9 as well. Set*ShaderConstants* methods have a parameter specifying how many registers you want to set.You'd have to figure out the offsets of the variables and put your parameters in a structure that is perfectly equivalent to the register layout that you define in HLSL. The ID3DXConstantTable object can be used to calculate the registers corresponding to given variables. Note that the Effect framework already does this for you. And since the constant tables are static after the effect creation, it is very fast to access variables by handle anyway.You can also force your HLSL variables to use particular registers, so you don't have to do the lookup from the host program. The syntax for a constant is as follows:float4 example : register(c0); //variable "example" uses constant register 0.float2 anotherExample: register (c1); //you get the idea......Then you could set both of these with a single call to Set*ShaderConstantsF, since they are adjacent in the register layout.In D3D9, you have to use separate registers for vertex and pixel shaders since the API doesn't have the notion of unified pipeline architecture. Also, integer, float and bool registers have their own logical banks. And finally, there is only one bank of constant registers per the three datatypes per shader stage. This is in contrast to D3D10 and up, where there is several general-purpose constant buffers that can store any datatype.

Very helpful ! thank you very much! 谢谢 呵呵

Share this post

Share on other sites
Nik02    4348
I forgot to mention: Since you're using the Effect system, you might want to use ID3DXEffect::SetRawValue. It effectively wraps Set*ShaderConstantsF, and you can give it the handle (or name) of the first variable to establish the first destination register.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now