Jump to content
  • Advertisement
Sign in to follow this  
Aqua Costa

[DirectX 10/HLSL] Passing a struct to the GPU

This topic is 2859 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm try to pass this struct to the GPU:


struct Light
{
Light()
{
ZeroMemory(this, sizeof(Light));
}

D3DXVECTOR3 pos;
D3DXVECTOR3 dir;
D3DXCOLOR ambient;
D3DXCOLOR diffuse;
D3DXCOLOR specular;
D3DXVECTOR3 att;
float spotPow;
float range;
int type;
};



And Ive exactly the same struct in my shader:

struct Light
{
float3 pos;
float3 dir;
float4 ambient;
float4 diffuse;
float4 spec;
float3 att;
float spotPow;
float range;
int type;
};



I give this values to my light in CPU code and I pass the light to the shader:

mLight.dir = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
mLight.ambient = D3DXCOLOR(0.4f, 0.4f, 0.4f, 1.0f);
mLight.diffuse = D3DXCOLOR(0.5f, 0.5f, 1.0f, 1.0f);
mLight.specular = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
mLight.type = PARALLEL_LIGHT;

mLightVar->SetRawValue(mLight, 0, sizeof(Light));



But the values I receive in my shader are:
Light.dir = (-1.0f, -1.0f, 0.4f)
Light.diffuse = (1.0f,1.0f,1.0f, _)


What am I doing wrong?

Share this post


Link to post
Share on other sites
Advertisement
There are certain packing rules, both in HLSL and C++. Each float3 in HLSL will actually start at the next 16-byte (float4) boundary, because the GPU is made for such aligned vectors.
Packing Rules for Constant Variables (DirectX HLSL).

Sometimes VC++ will also align structs for you, but probably not in your example. Google gave me for example the following if you want to read about it.
Structure Alignment Examples.
http://msdn.microsoft.com/en-us/library/xh3e3fd0(VS.80).aspx.
Data Alignment Considerations.

Share this post


Link to post
Share on other sites
EDIT: Ninja'd

One thing I noticed is this:

mLightVar->SetRawValue(mLight, 0, sizeof(Light));


Mustn't this be this?

mLightVar->SetRawValue((void *)&mLight, 0, sizeof(Light));


Assuming mLight is not a pointer, because you used "." to access it.

Also you should make sure that you don't get tricked by the compiler which likes to reorder structs sometimes. To force it not to do this, simply do that:

//Make sure that the struct does not get reordered by the compiler
#pragma pack(push, 1)

//Struct goes here

#pragma pack(pop)


Share this post


Link to post
Share on other sites
Quote:
Original post by mind in a box
EDIT: Ninja'd

One thing I noticed is this:

mLightVar->SetRawValue(mLight, 0, sizeof(Light));


Mustn't this be this?

mLightVar->SetRawValue((void *)&mLight, 0, sizeof(Light));


Assuming mLight is not a pointer, because you used "." to access it.


In my code mLight is a pointer, but on my post I change the code a bit to make it simpler for you to understand.

And I found a way to make it work:
As elements in HLSL are packed in 4D vectors I simply added a float after each D3DXVECTOR3 like this:

struct Light
{
Light()
{
ZeroMemory(this, sizeof(Light));
}

D3DXVECTOR3 pos;
float compPos;
D3DXVECTOR3 dir;
float compDir;
D3DXCOLOR ambient;
D3DXCOLOR diffuse;
D3DXCOLOR specular;
D3DXVECTOR3 att;
float spotPow;
float range;
int type;
};




I just dont undertsand why att, spotPow and range are packed correctly without completing them to be 4D vectors... Does anyone know why?

Share this post


Link to post
Share on other sites
Why wasting space?


struct Light
{
Light()
{
ZeroMemory(this, sizeof(Light));
}

D3DXVECTOR4 pos_spotPow; //xyz=pos, w=spotPow
D3DXVECTOR4 dir_Range; //xyz=dir, w=range
D3DXCOLOR ambient;
D3DXCOLOR diffuse;
D3DXCOLOR specular;
D3DXVECTOR4 att_WhatEver; //xyz=att, and one free :)
int type;
};


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!