C++ / HLSL Passing values to shader

Started by
6 comments, last by MJP 14 years ago
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]
Advertisement
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?

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

[size=1]Visit my website, rawrrawr.com

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
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.
in SM2.0 and SM3.0, int registers are only used as loop counters. You can't use them as general-purpose constants.

This topic is closed to new replies.

Advertisement