Sign in to follow this  
littlekid

Setting a Float Array for shaders

Recommended Posts

littlekid    229
I have read the SDK and use ConstantTable->SetFloatArray(.....) to insert the array of floats. Here is the snippet of the code
float Ambient[] = {1.0, 1.0, 1.0, 1.0};
ConstantTable->SetFloatArray(gD3DDevice, "Ambient", Ambient, 4);
Here is the vertex shader
struct VS_INPUT
{
    float4 Position   : POSITION0;
    float4 Normal     : NORMAL;
    float4 Color      : COLOR0;
    float2 Texture    : TEXCOORD0;
};

struct VS_OUTPUT
{
    float4 Position   : POSITION0;
    float4 Color      : COLOR0;
    float2 Texture    : TEXCOORD0;
};

float4x4 WorldViewProj;
float4 Ambient;

VS_OUTPUT vs_main( in VS_INPUT In )
{
    VS_OUTPUT Out;
    Out.Position = mul(In.Position, WorldViewProj);
    Out.Color    = In.Color * Ambient;
    Out.Texture  = In.Texture;
    return Out;
}
However the square that i render is forever black, no texture or anything, it is just black. How should i go about solving the problem?

Share this post


Link to post
Share on other sites
centipede    304
You are multiplying the ambient color with the vertex color. I guess you're not setting the vertex color, in which case it's black, and so the output color is also black.

EDIT: Are you using a pixel shader? If so, you should post that code here too.

Share this post


Link to post
Share on other sites
littlekid    229
Nope no pixel shader, if i don't multiply by the Ambient, then everything is normal, but i wish to set the Ambient to red, so that the object appear reddish, or another color dependings on the situation.

if i use

Out.Color = In.Color * float4(1.0, 0.0, 0.0, 1.0);

it works fine, but if i use variables, it just turn out black

Share this post


Link to post
Share on other sites
S1CA    1418
1) Does your WorldViewProj matrix work as expected?
- If so, are you updating that through the constant table as well?
- If you are, compare where in your program the update is being done with the update of the ambient parameter.

2) Does the constant table definately match the shader? i.e. is it generated from compilation at runtime or is it loaded from disk (for example).

3) Does SetFloatArray() return an error at all? - link with the debug version of D3DX to be 100% certain.

4) Are you trying to use the effect system at the same time as constant tables?.

5) I suspect this is either an order issue (e.g. changing the ambient colour /after/ the draw call, or an API call error, or


------------8<---- snip - aaaaaarghh - just spotted something:



6)
Quote:
ConstantTable->SetFloatArray(gD3DDevice, "Ambient", Ambient, 4);


Take another look at the documentation for ID3DXConstantTable::SetFloatArray. You'll notice that the second parameter is a D3DXHANDLE; this should be a **handle** to a variable **NOT** a string!

You should do:

D3DXHANDLE hAmbient = ConstantTable->GetConstantByName(NULL, "Ambient);
...
ConstantTable->SetFloatArray(device, hAmbient, Ambient, 4);


Don't make assumptions about the API based on the base type of "handles" - if the docs don't say the function takes a string; then the function doesn't take a string!.

The API will have returned an error from SetFloatArray() in the above situation though - the debug version of D3DX and checking error returns is a good thing :)

Share this post


Link to post
Share on other sites
littlekid    229
It still can't work, the WorldViewProj is set correctly.

ConstantTable->SetFloatArray(gD3DDevice, "Ambient", Ambient, 4), still fails, because it still can't pass the FAILED() macro. How do i know which error is it?

Edit: Sorry I wasn't clear i did use your method

D3DXHANDLE hHandle = ConstantTable->GetConstantByName(NULL, "Ambient");
ConstantTable->SetFloatArray(gD3DDevice, hHandle, Ambient, 4);

But it still can't work

[Edited by - littlekid on December 3, 2005 8:03:56 PM]

Share this post


Link to post
Share on other sites
S1CA    1418
1) As I mentioned, you need to pass a *handle* and not a string when referring to the variable:

D3DXHANDLE hAmbient = ConstantTable->GetConstantByName(NULL, "Ambient);
...
ConstantTable->SetFloatArray(device, hAmbient, Ambient, 4);


2) Link with d3dx9d.lib instead of d3dx9.lib; when your FAILED() macro hits, check out the Output window in your debugger (or use DebugView from www.sysinternals.com) - the reason for the failure will be reported there. If the code you posted is your exact code, then the reason will be something like "handle is invalid" because you've passed a string to a function that expects a D3DX handle.

Share this post


Link to post
Share on other sites
littlekid    229
Trying both method didn't work, even after i got the Handle and pass it in properly, ConstantTable->SetFloatArray was still failing, and i can't link with d3dx9d, when ever i try to compile, it says d3dx9d.dll is not found

Share this post


Link to post
Share on other sites
Drakex    273
S1CA - D3DXHANDLE parameters will accept either a handle acquired by a GetConstantByName() call or a string. In the DX docs, see DirectX Graphics > Reference > Effect Reference > Effect Format > Handles:

Quote:
The handles that you pass into functions such as GetParameter[ByName|Element|BySemantic] or GetAnnotation[ByName] can be in three forms as follows:

1. Handles that were returned by functions such as GetParameter[ByName|Element|BySemantic].

2.Strings such as MyVariableName, MyTechniqueName, or MyArray[0].


I pass strings in for D3DXHANDLE parameters all the time.

Share this post


Link to post
Share on other sites
vinartrulz    122
hi
i am not any expert in this,but i think therez some problem with ur constant table.Why dont you just try to pass a float value(not an array) and see whether its working fine

Share this post


Link to post
Share on other sites
jollyjeffers    1570
Quote:
Original post by littlekid
i still can't find a solution, does anyone know what is wrong with my code?

I haven't seen it in this thread yet, but something Simon suggested - check the debug output. It's very good at elaborating on errors [smile]

If you're not familiar with the DX debug's then check out the link in my signiture.

You should also try something like:

if( FAILED( ... ) )
{
OutputDebugString( L"Error occured whilst ...\n" );
}


as that'll not only give you a line to break-point on, but also a convenient message in your debug output to search for. If you're using the debug runtimes, then whatever appears above that line in the debug output is likely to be the reason it failed.

Also, given that the ID3DXConstantTable is just a thin wrapper over the device's constant setting/getting interface, are you definitely sure that something else isn't overwriting the values you're setting?

hth
Jack

Share this post


Link to post
Share on other sites
littlekid    229
however if its weird i don't understand, if i use:

D3DXVECTOR4 Ambient(1.0, 1.0, 1.0, 1.0);
ConstantTable->SetVector(gD3DDevice, "Ambient", &Ambient);

Its works perfectly ok

Edit: thanks for teaching me how to use the debugger, yup i follow the method of:

if (FAILED(...))
MessageBox(....);

Thats why i know the SetFloatArray failed

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
err people just asking does it matters for the version of the SDK? maybe it is not supported or ready yet?

Share this post


Link to post
Share on other sites

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

Sign in to follow this