Setting a Float Array for shaders

Started by
12 comments, last by GameDev.net 18 years, 4 months ago
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?
Advertisement
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.
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
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 :)

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

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]
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.

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

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
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.
_______________________________________________________________________Hoo-rah.
i still can't find a solution, does anyone know what is wrong with my code?
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

This topic is closed to new replies.

Advertisement