To expand from my previous question, I must add I can't correctly map my C++ structs to a corresponding cbuffer
inside the pixel shader. When outputing random colors defined in the struct C++ side, it happens I get wrong results i.e. an XMFLOAT4(0,0,0,1.0)
would give me a red color (?).
So here is a code sample :
__declspec(align(16)) struct SceneParams {
bool DEAOEnabled;
XMFLOAT4 DEAOColor;
double DEAOPow;
bool lightEnabled;
XMFLOAT4 lightColor;
XMFLOAT3 lightDirection;
bool lightMultiply;
double lightMultiplyFactor;
bool ambiantLightEnabled;
XMFLOAT4 ambiantLightColor;
bool HSEnabled;
int HSSpread;
bool fogEnabled;
XMFLOAT4 fogColor;
double fogDistanceMax;
bool glowEnabled;
XMFLOAT4 glowColor;
double glowRadius;
XMFLOAT4 skyColor;
bool skyBoxEnabled;
//uniform sampler2D skyBoxTexture;
int skyBoxScheme0; // top
int skyBoxScheme1; // left
int skyBoxScheme2; // front
int skyBoxScheme3; // right
int skyBoxScheme4; // back
int skyBoxScheme5; // bottom
int skyBoxRotate;
double skyBoxRotateSpeed;
XMFLOAT3 skyBoxRotateAround;
bool orbitTrapsEnabled;
int orbitTrapsId;
XMFLOAT4 objectColor;
SceneParams(
bool DEAOEnabled,
XMFLOAT4 DEAOColor,
double DEAOPow,
bool lightEnabled,
XMFLOAT4 lightColor,
XMFLOAT3 lightDirection,
bool lightMultiply,
double lightMultiplyFactor,
bool ambiantLightEnabled,
XMFLOAT4 ambiantLightColor,
bool HSEnabled,
int HSSpread,
bool fogEnabled,
XMFLOAT4 fogColor,
double fogDistanceMax,
bool glowEnabled,
XMFLOAT4 glowColor,
double glowRadius,
XMFLOAT4 skyColor,
bool skyBoxEnabled,
//uniform sampler2D skyBoxTexture,
int skyBoxScheme0, // top
int skyBoxScheme1, // left
int skyBoxScheme2, // front
int skyBoxScheme3, // right
int skyBoxScheme4, // back
int skyBoxScheme5, // bottom
int skyBoxRotate,
double skyBoxRotateSpeed,
XMFLOAT3 skyBoxRotateAround,
bool orbitTrapsEnabled,
int orbitTrapsId,
XMFLOAT4 objectColor
) : DEAOEnabled{ DEAOEnabled }, DEAOColor{ DEAOColor }, DEAOPow{ DEAOPow }, lightEnabled{ lightEnabled }, lightColor{ lightColor }, lightDirection{ lightDirection },
lightMultiply{ lightMultiply }, lightMultiplyFactor{ lightMultiplyFactor }, ambiantLightEnabled{ ambiantLightEnabled }, ambiantLightColor{ ambiantLightColor },
HSEnabled{ HSEnabled }, HSSpread{ HSSpread }, fogEnabled{ fogEnabled }, fogColor{ fogColor }, fogDistanceMax{ fogDistanceMax }, glowEnabled{ glowEnabled },
glowColor{ glowColor }, glowRadius{ glowRadius }, skyColor{ skyColor }, skyBoxEnabled{ skyBoxEnabled }, skyBoxScheme0{ skyBoxScheme0 },
skyBoxScheme1{ skyBoxScheme1 }, skyBoxScheme2{ skyBoxScheme2 }, skyBoxScheme3{ skyBoxScheme3 }, skyBoxScheme4{ skyBoxScheme4 }, skyBoxScheme5{ skyBoxScheme5 },
skyBoxRotate{ skyBoxRotate }, skyBoxRotateSpeed{ skyBoxRotateSpeed }, skyBoxRotateAround{ skyBoxRotateAround }, orbitTrapsEnabled{ orbitTrapsEnabled },
orbitTrapsId{ orbitTrapsId }, objectColor{ objectColor } {}
SceneParams() {}
};
...
// create a scene params object
...
constantBufferDesc.ByteWidth = sizeof(SceneParams);
hr = g_d3dDevice->CreateBuffer(&constantBufferDesc, nullptr, &g_d3dConstantBuffers[CB_Scene_Params]);
g_d3dDeviceContext->PSSetConstantBuffers(4, 1, &g_d3dConstantBuffers[CB_Scene_Params]);
g_d3dDeviceContext->UpdateSubresource(g_d3dConstantBuffers[CB_Scene_Params], 0, nullptr, &g_SceneParams, 0, 0);
With HLSL :
cbuffer sceneParams : register(b4) {
bool DEAOEnabled;
float4 DEAOColor;
double DEAOPow;
bool lightEnabled;
float4 lightColor;
float3 lightDirection;
bool lightMultiply;
double lightMultiplyFactor;
bool ambiantLightEnabled;
float4 ambiantLightColor;
bool HSEnabled;
int HSSpread;
bool fogEnabled;
float4 fogColor;
double fogDistanceMax;
bool glowEnabled;
float4 glowColor;
double glowRadius;
float4 skyColor;
bool skyBoxEnabled;
//uniform sampler2D skyBoxTexture;
int skyBoxScheme0; // top
int skyBoxScheme1; // left
int skyBoxScheme2; // front
int skyBoxScheme3; // right
int skyBoxScheme4; // back
int skyBoxScheme5; // bottom
int skyBoxRotate;
double skyBoxRotateSpeed;
float3 skyBoxRotateAround;
bool orbitTrapsEnabled;
int orbitTrapsId;
float4 objectColor;
}
I changed my cbuffer
float
s to double
s to match the C++ struct but to no avail. What's wrong with the way I did the mapping ?
Additionnaly, here is a byte-size dump of the struct members :
std::cout << sizeof(p.DEAOEnabled) << std::endl;
std::cout << sizeof(p.DEAOColor) << std::endl;
std::cout << sizeof(p.DEAOPow) << std::endl;
std::cout << sizeof(p.lightEnabled) << std::endl;
std::cout << sizeof(p.lightColor) << std::endl;
std::cout << sizeof(p.lightDirection) << std::endl;
std::cout << sizeof(p.lightMultiply) << std::endl;
std::cout << sizeof(p.lightMultiplyFactor) << std::endl;
std::cout << sizeof(p.ambiantLightEnabled) << std::endl;
std::cout << sizeof(p.ambiantLightColor) << std::endl;
std::cout << sizeof(p.HSEnabled) << std::endl;
std::cout << sizeof(p.HSSpread) << std::endl;
std::cout << sizeof(p.fogEnabled) << std::endl;
std::cout << sizeof(p.fogColor) << std::endl;
std::cout << sizeof(p.fogDistanceMax) << std::endl;
std::cout << sizeof(p.glowEnabled) << std::endl;
std::cout << sizeof(p.glowColor) << std::endl;
std::cout << sizeof(p.glowRadius) << std::endl;
std::cout << sizeof(p.skyColor) << std::endl;
std::cout << sizeof(p.skyBoxEnabled) << std::endl;
std::cout << sizeof(p.skyBoxScheme[0]) << std::endl;
std::cout << sizeof(p.skyBoxScheme[1]) << std::endl;
std::cout << sizeof(p.skyBoxScheme[2]) << std::endl;
std::cout << sizeof(p.skyBoxScheme[3]) << std::endl;
std::cout << sizeof(p.skyBoxScheme[4]) << std::endl;
std::cout << sizeof(p.skyBoxScheme[5]) << std::endl;
std::cout << sizeof(p.skyBoxRotate) << std::endl;
std::cout << sizeof(p.skyBoxRotateSpeed) << std::endl;
std::cout << sizeof(p.skyBoxRotateAround) << std::endl;
std::cout << sizeof(p.orbitTrapsEnabled) << std::endl;
std::cout << sizeof(p.orbitTrapsId) << std::endl;
std::cout << sizeof(p.objectColor) << std::endl;
Which outputs :
1
16
8
1
16
12
1
8
1
16
1
4
1
16
8
1
16
8
16
1
4
4
4
4
4
4
1
8
12
1
4
16
Here is the compiler layout :
1> +---
1> 0 | DEAOEnabled
1> | <alignment member> (size=3)
1> 4 | XMFLOAT4 DEAOColor
1> | <alignment member> (size=4)
1> 24 | DEAOPow
1> 32 | lightEnabled
1> | <alignment member> (size=3)
1> 36 | XMFLOAT4 lightColor
1> 52 | XMFLOAT3 lightDirection
1> 64 | lightMultiply
1> | <alignment member> (size=7)
1> 72 | lightMultiplyFactor
1> 80 | ambiantLightEnabled
1> | <alignment member> (size=3)
1> 84 | XMFLOAT4 ambiantLightColor
1> 100 | HSEnabled
1> | <alignment member> (size=3)
1> 104 | HSSpread
1> 108 | fogEnabled
1> | <alignment member> (size=3)
1> 112 | XMFLOAT4 fogColor
1> 128 | fogDistanceMax
1> 136 | glowEnabled
1> | <alignment member> (size=3)
1> 140 | XMFLOAT4 glowColor
1> | <alignment member> (size=4)
1> 160 | glowRadius
1> 168 | XMFLOAT4 skyColor
1> 184 | skyBoxEnabled
1> | <alignment member> (size=3)
1> 188 | skyBoxScheme0
1> 192 | skyBoxScheme1
1> 196 | skyBoxScheme2
1> 200 | skyBoxScheme3
1> 204 | skyBoxScheme4
1> 208 | skyBoxScheme5
1> 212 | skyBoxRotate
1> 216 | skyBoxRotateSpeed
1> 224 | XMFLOAT3 skyBoxRotateAround
1> 236 | orbitTrapsEnabled
1> | <alignment member> (size=3)
1> 240 | orbitTrapsId
1> 244 | XMFLOAT4 objectColor
1> | <alignment member> (size=4)
1> +---
/d1reportSingleClassLayout<name>
a useful command-line switch if using VS. You can add it to your project options via the "Additional Compiler Options" section of the C++ properties of your project. Replace "<name>" with a type name (e.g., /d1reportSingleClassLayoutSceneParams) and compile; the compiler's interpretation of the class layout will be printed to the output window, including pad bytes. \$\endgroup\$**ptrptr
instead of*ptr
to myUpdateSubresource()
forpSrcData
:/ Problem solved. :) \$\endgroup\$