I am setting an HLSL effect variable in the following way in a number of places.
extern ID3D10EffectVectorVariable* pColour;
pColour = pEffect->GetVariableByName("Colour")->AsVector();
pColour->SetFloatVector(temporaryLines[i].colour);
In one of the places it is set in a loop, each line in the vector temporaryLines has a D3DXCOLOR variable associated with it. The most annoying thing about this problem is that it actually works on rare occasions, but most of the time it doesn’t. Are there any known issues with this kind of code?
Here it works:
void GameObject::Draw(D3DMATRIX matView, D3DMATRIX matProjection)
{
device->IASetInputLayout(pVertexLayout);
mesh.SetTopology();//TODO should not be done multiple times
// select which vertex buffer and index buffer to display
UINT stride = sizeof(VERTEX);
UINT offset = 0;
device->IASetVertexBuffers(0, 1, mesh.PBuffer(), &stride, &offset);
device->IASetIndexBuffer(mesh.IBuffer(), DXGI_FORMAT_R32_UINT, 0);
pColour->SetFloatVector(colour);
// create a scale matrix
D3DXMatrixScaling(&matScale, scale.x, scale.y, scale.z);
// create a rotation matrix
D3DXMatrixRotationYawPitchRoll(&matRotate, rotation.y, rotation.x, rotation.z);
// create a position matrix
D3DXMatrixTranslation(&matTranslation, position.x, position.y, position.z);
// combine the matrices and render
matFinal =
matScale *
matRotate *
matTranslation *
matView * matProjection;
pTransform->SetMatrix(&matFinal._11);
pRotation->SetMatrix(&matRotate._11); // set the rotation matrix in the effect
pPass->Apply(0);
device->DrawIndexed(mesh.Indices(), 0, 0); //input specific
}
Here is occasionally works:
void BatchLineRenderer::RenderLines(D3DXMATRIX matView, D3DXMATRIX matProjection)
{
device->IASetInputLayout(pVertexLayout);
device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP);
// select which vertex buffer and index buffer to display
UINT stride = sizeof(LINE);
UINT offset = 0;
device->IASetVertexBuffers(0, 1, &pBuffer, &stride, &offset);
device->IASetIndexBuffer(iBuffer, DXGI_FORMAT_R32_UINT, 0);
allLines = temporaryLines.size();
for(int i = 0; i < allLines; i++)
{
pColour->SetFloatVector(temporaryLines[i].colour); // in the line loop too?
// combine the matrices and render
D3DXMATRIX matFinal =
temporaryLines[i].scale *
temporaryLines[i].rotation *
temporaryLines[i].position *
matView * matProjection;
pTransform->SetMatrix(&matFinal._11);
pRotation->SetMatrix(&temporaryLines[i].rotation._11); // set the rotation matrix in the effect
pPass->Apply(0);
device->DrawIndexed(2, 0, 0);
}
temporaryLines.clear();
}
the effect file:
float4x4 Transform; // a matrix to store the transform
float4x4 Rotation; // a matrix to store the rotation transform
float4 LightVec = {0.612f, 0.3535f, 0.612f, 0.0f}; // the light's vector
float4 LightCol = {1.0f, 1.0f, 1.0f, 1.0f}; // the light's color
float4 AmbientCol = {0.3f, 0.3f, 0.3f, 1.0f}; // the ambient light's color
float4 Colour;
// a struct for the vertex shader return value
struct VSOut
{
float4 Col : COLOR; // vertex normal
float4 Pos : SV_POSITION; // vertex screen coordinates
};
// the vertex shader
VSOut VS(float4 Norm : NORMAL, float4 Pos : POSITION)
{
VSOut Output;
Output.Pos = mul(Pos, Transform); // transform the vertex from 3D to 2D
Output.Col = AmbientCol; // set the vertex color to the input's color
float4 Normal = mul(Norm, Rotation);
Output.Col += saturate(dot(Normal, LightVec)) * LightCol * Colour; // add the diffuse and passed in light
return Output; // send the modified vertex data to the Rasterizer Stage
}
// the pixel shader
float4 PS(float4 Col : COLOR) : SV_TARGET
{
return Col; // set the pixel color to the color passed in by the Rasterizer Stage
}
// the primary technique
technique10 Technique_0
{
// the primary pass
pass Pass_0
{
SetVertexShader(CompileShader(vs_4_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_4_0, PS()));
}
}
So the Colour HLSL variable has not been defined inside a ConstantBuffer, just a normal shader variable.
Perhaps the variable should rather be defined in a Constant buffer, updateblae per frame? Similar to how the world and view matrices should be defined in. At least then the GPU knows you want to update the colour variable each time you render. (As you are updating the value before you draw).
Another point I would consider is to get the pointer to the technique desc everytime before the draw call (or pass through loop),
and not reuse it, seems to also make a difference.