Sign in to follow this  
RaptorJesus

C++ / HLSL Passing values to shader

Recommended Posts

RaptorJesus    122
Tryinng to implement some shaders to do basic stuff and I'm having trouble passing values to the shader I've set up. The shader works and I can edit the texture coordinates using hard coded numbers/variables using the shader, but nothing happens when I pass a value from my program to the shader and then update it inside the program. I'm calling the following code every time I render said object
[source="cpp"]
	pd3dDevice->SetVertexShader(vertexShader);
        pd3dDevice->SetPixelShader(pixelShader);

	constantTable->SetInt(pd3dDevice, "MyTestInt", testInt);
	testInt++;


        pd3dDevice->SetStreamSource(0, waterPlaneBuffer, 0, sizeof(CUSTOMVERTEX));
        pd3dDevice->SetTexture(0, waterTexture);
        pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

	//Disable Shaders
	pd3dDevice->SetVertexShader(NULL);
	pd3dDevice->SetPixelShader(NULL);






My pixel shader
[source="hlsl"]
// Pixel shader input structure
struct PS_INPUT
{
    float4 Position   : POSITION;
    float2 Texture    : TEXCOORD0;
};


// Pixel shader output structure
struct PS_OUTPUT
{
    float4 Color   : COLOR0;
};


// Global variables
sampler2D Tex0;
float time;
int MyTestInt : MYTESTINT;


// Name: Simple Pixel Shader
// Type: Pixel shader
// Desc: Fetch texture and blend with constant color
//
PS_OUTPUT ps_main( in PS_INPUT In )
{
    PS_OUTPUT Out;                             //create an output pixel

    In.Texture.y = In.Texture.y + (sin(In.Texture.x*MyTestInt)*0.01);

    Out.Color = tex2D(Tex0, In.Texture);       //do a texture lookup
    //Out.Color *= float4(0.9f, 0.8f, 0.4, 1);   //do a simple effect

    return Out;                                //return output pixel
}





I tried declaring it as int MyTestInt : MYTESTINT; int MyTestInt; Even tried pd3dDevice->SetPixelShaderConstantI(num, testInt, 1) and referring to c<num> in the shader. Not sure how to do this at all. [Edited by - RaptorJesus on March 30, 2010 4:32:20 PM]

Share this post


Link to post
Share on other sites
jbb    471
If you call this

pd3dDevice->SetPixelShaderConstantI(num, testInt, 1)

Then testInt needs to be an array of 4 ints, it's not clear from your post if you are doing this?

Share this post


Link to post
Share on other sites
RaptorJesus    122
At the moment its declared as a single int.

If I instead declare it as an array of size 4 and do something like this.

pd3dDevice->SetPixelShaderConstantI(25, testInt, 1)

Will I be able to refer to the first element of the array in the shader as c25? All I really want is to be able to edit the information in testInt and have it updated in the shader too.

Share this post


Link to post
Share on other sites
jbb    471
I believe so. That's is what I'm doing in mine although for floats and it works. I've not tried it with int though

Youd need something like

int myTestInt : register(c0);

I believe

Share this post


Link to post
Share on other sites
bobofjoe    322
If you're calling this between BeginPass() and EndPass() calls; you must call CommitChanges() before using the effect to see the effects of the change.

Er...Disregard that; you're not using the effects framework.
Anyway; it looks like you're setting the values right before you use them; and you might have to do some tricks before the changes are sent over. I'm not sure on what CommitChanges() does, but you'll have to replicate the behavior.

Share this post


Link to post
Share on other sites
jbb    471
The code got complex in my current demo but from some older test code that works I have this where i draw my model.


m_Device->SetPixelShader(m_PixelShader);
m_Device->SetVertexShader(m_VertexShader);

XMMATRIX t = m_World * m_View * m_Projection;
m_Device->SetVertexShaderConstantF(0, (const float*)&t, 4);
m_Device->SetVertexShaderConstantF(4, (const float*)&m_World, 4);
m_Device->SetVertexShaderConstantF(8, (const float*)&light.Direction, 1);
float f[] = {m_GrowAmount, 0.0f, 0.0f, 0.0f};
m_Device->SetVertexShaderConstantF(9, f, 1);
if (m_WireFrame) {
m_Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
m_Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
} else {
m_Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
m_Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
}

m_Device->BeginScene();
m_Model->draw(m_Device);
m_Device->EndScene();





And this is the start of the vertex shader.

extern float4x4 gWVP : register(c0);
extern float4x4 gWorld : register(c4);
extern float4 gLightVector : register(c8);
extern float gGrowAmount : register(c9);

struct OUT_VS
{
float4 pos : POSITION;
float4 light : COLOR;
};





This is a vertext shader parameter and float, not int. But I believe the principle is the same

Share this post


Link to post
Share on other sites
RaptorJesus    122
I just changed it to a float using your method and it does what I'm after :)

For some reason it doesnt work as an int using SetPixelShaderConstantI, but I can work with a float. Thanks.

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