DirectX 11: Text output: HLSL/ InputLayout troubles - c++

I've been search for a good text methodolgy recently and found one at http://www.braynzarsoft.net/Articles/index.php?p=VA&article=Easy-Font-Rendering-in-DirectX-11 , which is a good site. I can't seem to get it to run! I've resolved most of the errors but, however on debug, I get HLSL errors:
D3D11: ERROR: ID3D11DeviceContext::Draw: The Vertex Shader expects application provided input data (which is to say data other than hardware auto-generated values such as VertexID or InstanceID). Therefore an Input Assembler object is expected, but none is bound. [ EXECUTION ERROR #349: DEVICE_DRAW_INPUTLAYOUT_NOT_SET ]
Creeped? I am! Since this message is spamming like mad, the issue is most likely happening in my DrawText() function or a bad implementation in the initialize function (Below)
The InitializeGeneralResources() function:
void InfiniteText::InitializeGeneralResources(){
float textureWidth=1024.0f;
UINT numLetters=32;
D3DX11CompileFromFile(L"Font.hlsl", NULL, NULL, "FONT_VS", "vs_5_0",0,0,0,&FontvsBuffer,0,0);
D3DX11CompileFromFile(L"Font.hlsl", NULL, NULL, "FONT_PS", "ps_5_0",0,0,0,&FontpsBuffer,&ppErrorMsgs,0);
iD3D.Device->CreateVertexShader(FontvsBuffer->GetBufferPointer(),FontvsBuffer->GetBufferSize(), NULL, &Fontvs);
iD3D.Device->CreatePixelShader(FontpsBuffer->GetBufferPointer(),FontpsBuffer->GetBufferSize(), NULL, &Fontps);
ID3D11InputLayout* InLayout;
D3D11_INPUT_ELEMENT_DESC IEDesc[]={
{"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0},
{"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0},
};
UINT NumElements = ARRAYSIZE(IEDesc);
iD3D.Device->CreateInputLayout(IEDesc,NumElements,FontvsBuffer->GetBufferPointer(),FontvsBuffer->GetBufferSize(),&InLayout);
iD3D.DeviceContext->IASetInputLayout(InLayout);
D3D11_SAMPLER_DESC FontSamplerDesc;
FontSamplerDesc.MaxAnisotropy=1;
FontSamplerDesc.AddressU=D3D11_TEXTURE_ADDRESS_WRAP;
FontSamplerDesc.AddressV=D3D11_TEXTURE_ADDRESS_WRAP;
FontSamplerDesc.AddressW=D3D11_TEXTURE_ADDRESS_WRAP;
FontSamplerDesc.Filter=D3D11_FILTER_MIN_MAG_MIP_LINEAR;
FontSamplerDesc.MipLODBias=0.0f;
D3DX11CreateShaderResourceViewFromFile(iD3D.Device, L"Font.dds", NULL, NULL, &FontSRV, NULL);
iD3D.Device->CreateSamplerState(&FontSamplerDesc, &FontSRVSampler);
D3D11_BUFFER_DESC Vbufferdescription;
ZeroMemory(&Vbufferdescription, sizeof(Vbufferdescription));
Vbufferdescription.BindFlags=D3D11_BIND_VERTEX_BUFFER;
Vbufferdescription.Usage=D3D11_USAGE_DYNAMIC;
Vbufferdescription.CPUAccessFlags=D3D11_CPU_ACCESS_WRITE;
Vbufferdescription.ByteWidth=sizeof(VertexText)*6*numLetters;
Vbufferdescription.MiscFlags=0;
iD3D.Device->CreateBuffer(&Vbufferdescription, NULL, &FontVertexBuffer);
}
I have a rather simple HLSL file:
cbuffer ConstantBuffer:register( b0 )
{
float4x4 WVP;
}
struct VOut
{
float4 position : SV_POSITION;
float2 TexCoord : TEXCOORD0;
};
VOut FONT_VS(float4 position : POSITION, float2 TexCoord : TEXCOORD)
{
VOut output;
output.position = mul(position, WVP);
output.TexCoord = TexCoord;
return output;
}
float2 FONT_PS(float4 position : SV_POSITION, float2 TexCoord : TEXCOORD0) : SV_TARGET
{
return TexCoord;
}
(The DrawString() function)
bool InfiniteText::DrawString(char* Text, float xPos, float yPos){
int letterSize = sizeof(VertexText)*6;
int textSize = strlen(Text);
if(textSize > numLetters)
textSize=numLetters;
float cScreenWidth = 32.0f/iD3D.cWidth;
float cScreenHeight= 32.0f/iD3D.cHeight;
float TexelWidth= 32.0f/textureWidth;
D3D11_MAPPED_SUBRESOURCE MappedSub;
iD3D.DeviceContext->Map(FontVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedSub);
VertexText* Sprite = (VertexText*)MappedSub.pData;
const int indexA = static_cast<int>('A');
const int indexZ = static_cast<int>('Z');
for(int i=0; i<textSize;i++){
float thisStartX=xPos+(cScreenWidth*static_cast<char>(i));
float thisEndX=thisStartX + cScreenWidth;
float thisStartY=yPos;
float thisEndY=thisStartY + cScreenHeight;
Sprite[0].Translation=XMFLOAT3(thisEndX,thisEndY,1.0f);
Sprite[1].Translation=XMFLOAT3(thisEndX,yPos,1.0f);
Sprite[2].Translation=XMFLOAT3(thisStartX,yPos,1.0f);
Sprite[3].Translation=XMFLOAT3(thisStartX,yPos,1.0f);
Sprite[4].Translation=XMFLOAT3(thisStartX,thisEndY,1.0f);
Sprite[5].Translation=XMFLOAT3(thisEndX,thisEndY,1.0f);
UINT TexLookup=0;
UINT Letter= static_cast<int>(Text[i]);
if (Letter < indexA || Letter > indexZ){
TexLookup=(indexA - indexZ) +1;
}
else{
TexLookup=(Letter-indexA);
}
float texStart = 0.0f + (TexelWidth*static_cast<float>(TexLookup));
float TexEnd = texStart + TexelWidth;
Sprite[0].TextureCoord = XMFLOAT2(TexEnd,0.0f);
Sprite[1].TextureCoord = XMFLOAT2(TexEnd,1.0f);
Sprite[2].TextureCoord = XMFLOAT2(texStart,1.0f);
Sprite[3].TextureCoord = XMFLOAT2(texStart,1.0f);
Sprite[4].TextureCoord = XMFLOAT2(texStart,0.0f);
Sprite[5].TextureCoord = XMFLOAT2(TexEnd,0.0f);
Sprite= Sprite + 6;
}
iD3D.DeviceContext->Unmap(FontVertexBuffer,0); //MAP END
UINT stride=sizeof(VertexText);
UINT offset=0;
iD3D.DeviceContext->VSSetShader(iText.Fontvs,0,0);
iD3D.DeviceContext->PSSetShader(iText.Fontps,0,0);
//Projection=XMMatrixPerspectiveFovLH(XM_PIDIV2, 1.0, 0.0f, 1000.0f);
Projection=iD3D.mProjection;
iD3D.WorldCB.mWorldVP=XMMatrixTranspose(Projection);
iD3D.DeviceContext->UpdateSubresource(iD3D.MatrixBuffer, 0, NULL, &iD3D.WorldCB, 0, 0);
iD3D.DeviceContext->VSSetConstantBuffers(0,1,&iD3D.MatrixBuffer);
iD3D.DeviceContext->IASetVertexBuffers(0,1, &iText.FontVertexBuffer, &stride, &offset);
iD3D.DeviceContext->PSSetShaderResources(0,1, &iText.FontSRV);
iD3D.DeviceContext->PSSetSamplers(0,1,&iText.FontSRVSampler);
iD3D.DeviceContext->IASetPrimitiveTopology( D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
iD3D.DeviceContext->Draw(6*textSize,0);
return true;
}
If you made it this far, thank you. I think that it might be that my .hlsl file might not be configured properly to receive textures, and I might need to know how textures interface properly with the shader to produce the output. Thanks!

The HLSL was not written correctly to include Texture2D x: register( t0 ) or SamplerState x : register( s0 ), taking in necessary resources for the texture. Another problem has surfaced, but this question has been solved.

Related

Can't compile HLSL Hull shader code

Here's a simple hull shader code that i made, to try to understand tessellation.
I just can't find anything wrong with this code, but the compile function always return false. Here's my code:
My input and output structures:
[domain("tri")] // indicates a triangle patch (3 verts)
[partitioning("fractional_odd")] // fractional avoids popping
// vertex ordering for the output triangles
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
// name of the patch constant hull shader
[patchconstantfunc("ConstantsHS")]
//[maxtessfactor(7.0)]
cbuffer TessellationBuffer
{
float tessellationAmount;
float3 padding;
};
struct VS_CONTROL_POINT_OUTPUT
{
float3 vWorldPos : POSITION;
float2 vTexCoord : TEXCOORD0;
float3 vNormal : NORMAL0;
};
struct HS_CONTROL_POINT_OUTPUT
{
float3 vWorldPos : POSITION;
float2 vTexCoord : TEXCOORD0;
float3 vNormal : NORMAL0;
};
struct HS_CONSTANT_DATA_OUTPUT
{
float Edges[3] : SV_TessFactor;
float Inside : SV_InsideTessFactor;
};
My functions:
HS_CONTROL_POINT_OUTPUT HS(InputPatch<VS_CONTROL_POINT_OUTPUT, 3> inputPatch, uint uCPID : SV_OutputControlPointID, uint patchId : SV_PrimitiveID )
{
HS_CONTROL_POINT_OUTPUT Output;
Output.vWorldPos = inputPatch[uCPID].vWorldPos;
Output.vTexCoord = inputPatch[uCPID].vTexCoord;
Output.vNormal = inputPatch[uCPID].vNormal;
return Output;
};
HS_CONSTANT_DATA_OUTPUT ConstantsHS(InputPatch<VS_CONTROL_POINT_OUTPUT, 3> inputPatch, uint PatchID : SV_PrimitiveID )
{
HS_CONSTANT_DATA_OUTPUT Output;
Output.Edges[0] = tessellationAmount;
Output.Edges[1] = tessellationAmount;
Output.Edges[2] = tessellationAmount;
Output.Inside = tessellationAmount;
return Output;
};
Thanks for any help.
The attributes have to be set on the entry point like below, then your hull shader is valid :
[domain("tri")] // indicates a triangle patch (3 verts)
[partitioning("fractional_odd")] // fractional avoids popping
// vertex ordering for the output triangles
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
// name of the patch constant hull shader
[patchconstantfunc("ConstantsHS")]
//[maxtessfactor(7.0)]
HS_CONTROL_POINT_OUTPUT HS(InputPatch<VS_CONTROL_POINT_OUTPUT, 3> inputPatch, uint uCPID : SV_OutputControlPointID, uint patchId : SV_PrimitiveID )
On a side note, The command line tool FXC.exe would have print an error message that would have put you in the right direction : error X3000: syntax error: unexpected token 'cbuffer'
And i am unsure of what function you are referring to, D3DCompile return a HRESULT, not a boolean, and it also output a blob for you with the error messages in case of failure.

Shaders and Directx11 compilation in c++

I am trying to create a Directx 11 program using c++ . The code used to work before I added Normal to the code .Now it doesnt compile the shader at all .It keeps giving me access Violation 0X0000 Error.
I tried using d3dErrorBlolb but wasnt very helpful.The problem seems to lie in this part of the code.
void InitPipeline(HWND hwnd)
{
ID3D10Blob * BVS = 0,*BPS = 0;
ID3D10Blob * BErrorVS,*BErrorPs;
HRESULT hr1 = D3DX11CompileFromFile(L"Test.fx",0,0,"VS","vs_4_0",0,0,0,&BVS,&BErrorVS,0);
HRESULT hr = D3DX11CompileFromFile(L"Test.fx",0,0,"PS","ps_4_0",0,0,0,&BPS,&BErrorPs,0);
if(FAILED(hr))
{
printf("Error %08X %5s\n",hr,(char*)BErrorVS);
MessageBox(hwnd,L"Pixel shader not created ",L"",0);
}
if(FAILED(hr1))
{ MessageBox(hwnd,L"Vertex shader not created ",L"",0);}
dev->CreateVertexShader(BVS->GetBufferPointer(),BVS->GetBufferSize(),0,&BoxVShader);
dev->CreatePixelShader(BPS->GetBufferPointer(),BPS->GetBufferSize(),0,&BoxPixelShader);
// create the input layout object
D3D11_INPUT_ELEMENT_DESC ied[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}
// {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0}
};
//SecureZeroMemory(&Bin);
dev->CreateInputLayout(ied,2,BVS->GetBufferPointer(),BVS->GetBufferSize(),&BInputLayout);
devcon->VSSetShader(BoxVShader,0,0);
devcon->PSSetShader(BoxPixelShader,0,0);
devcon->IASetInputLayout(BInputLayout);
}
The Test.fx file
ecbuffer ConstantBuffer:register(b0)
{
matrix world;
matrix view;
matrix project;
float3[2] LightDir;
float4[2] LightColor;
}
struct Vout{
float4 pos:SV_POSITION;
float4 normal : NORMAL;
};
Vout VS(float3 pos:POSITION,float3 Norm:NORMAL)
{
Vout vo = (Vout)0;
vo.pos = mul(float4(pos,1),world);
vo.pos = mul(vo.pos,view);
vo.pos = mul(vo.pos,project);
vo.normal = mul(float4(Norm,1),world);
return vo;
}
float4 PS(float4 pos:SV_POSITION,float4 normal:NORMAL):SV_TARGET
{
float4 col;
for(int i=0; i < 2;++i)
{
col += saturate(dot(normal,LightDir[i])) * LightColor[i] ;
}
return col;
}
Can anyone please be kind enough to help me out...
If possible please do explain why this keeps happening always..What am I doing wrong here
Please do help me.I desperately need to solve this problem....
Thank you...
While compiling HLSL at runtime is nice for learning and iteration, it's actually a lot easier to debug the HLSL by compiling it with the command-line:
fxc test.fx /Tvs_4_0 /EVS and fxc test.fx /Tps_4_0 /EPS
The second fails because you failed to set the initial value for col in the Pixel Shader:
test.fx(40,25-47): warning X3206: 'dot': implicit truncation of vector type
test.fx(40,9-64): error X4000: variable 'col' used without having been completely initialized
compilation failed; no code produced
The fix is trivial:
float4 PS(float4 pos:SV_POSITION,float4 normal:NORMAL):SV_TARGET
{
float4 col = 0;
for(int i=0; i < 2;++i)
{
col += saturate(dot(normal,LightDir[i])) * LightColor[i] ;
}
return col;
}
You are getting an AV because you have the wrong handling of the failed compiler output, you forgot to initialize both BErrorVS and BErrorPS to null, and you are trying to output BErrorVS when the VS succeeded, but the PS failed. It should be:
if(FAILED(hr))
{
printf("Error %08X %5s\n",hr,(char*)BErrorPS->GetBufferPointer());
MessageBox(hwnd,L"Pixel shader not created ",L"",0);
}
Also you should remember that BErrorVS and BErrorPS can be set to a non-null value even if SUCCEEDED(hr)) since it can be reporting only non-fatal warnings.
See HLSL, FXC, and D3DCompile

DirectX 11 Compute Shader 5 loop

I have the following compute shader code for computing depth of field. However, very unusually, the loop executes just once, even if g_rayCount is 10. Please have a look in the main function raycastercs where the for loop lies.
//--------------------------------------------------------------------------------------
// Compute Shader
//-------------------------------------------------------------------------------------
SamplerState SSLinear
{
Filter = Min_Mag_Linear_Mip_Point;
AddressU = Border;
AddressV = Border;
AddressW = Border;
};
float3 CalculateDoF(uint seedIndex, uint2 fragPos)
{
;
}
[numthreads(RAYCASTER_THREAD_BLOCK_SIZE, RAYCASTER_THREAD_BLOCK_SIZE, 1)]
void RaycasterCS(in uint3 threadID: SV_GroupThreadID, in uint3 groupID: SV_GroupID, in uint3 dispatchThreadID :SV_DispatchThreadID)
{
uint2 fragPos = groupID.xy * RAYCASTER_THREAD_BLOCK_SIZE + threadID.xy;
float4 dstColor = g_texFinal[fragPos];
uint seedIndex = dispatchThreadID.x * dispatchThreadID.y;
float3 final = float3(0, 0, 0);
float color = 0;
[loop][allow_uav_condition]
for (int i = 0; i < g_rayCount; ++i);
{
float3 dof = CalculateDoF(seedIndex, fragPos);
final += dof;
}
final *= 1.0f / ((float) g_rayCount);
g_texFinalRW[fragPos] = float4(final, 1);
}
//--------------------------------------------------------------------------------------
technique10 Raycaster
{
pass RaycastDefault
{
SetVertexShader(NULL);
SetGeometryShader(NULL);
SetPixelShader(NULL);
SetComputeShader(CompileShader(cs_5_0, RaycasterCS()));
}
}
Remove the semicolon at the end of the for statement
for (int i = 0; i < g_rayCount; ++i) // removed semicolon
{
float3 dof = CalculateDoF(seedIndex, fragPos);
final += dof;
}
As I guess you know, the semicolon was just running an empty for loop, then the code in braces was thereafter executed just once.

GLSL linker error(Sampler needs to be a uniform (global or parameter to main))

we have a GLSL fragment shader :
but the problem is in this code
vec4 TFSelection(StrVolumeColorMap volumeColorMap , vec4 textureCoordinate)
{
vec4 finalColor = vec4(0.0);
if(volumeColorMap.TransferFunctions[0].numberOfBits == 0)
{
return texture(volumeColorMap.TransferFunctions[0].TransferFunctionID,textureCoordinate.x);
}
if(textureCoordinate.x == 0)
return finalColor;
float deNormalize = textureCoordinate.x *65535/*255*/;
for(int i = 0; i < volumeColorMap.TransferFunctions.length(); i++)
{
int NormFactor = volumeColorMap.TransferFunctions[i].startBit + volumeColorMap.TransferFunctions[i].numberOfBits;
float minval = CalculatePower(2, volumeColorMap.TransferFunctions[i].startBit);
if(deNormalize >= minval)
{
float maxval = CalculatePower(2, NormFactor);
if(deNormalize <maxval)
{
//float tempPower = CalculatePower(2 , NormFactor);
float coord = deNormalize /maxval/*tempPower*/;
return texture(volumeColorMap.TransferFunctions[i].TransferFunctionID,coord);
}
}
}
return finalColor;
}
when we compile and link shader this message logs:
Sampler needs to be a uniform (global or parameter to main), need to
inline function or resolve conditional expression
with a simple change like maybe the shader link successfully like changing
float `coord = deNormalize /maxval
to
float coord = deNormalize .`
driver:nvidia 320.49

CgFx compiler error "Unknown state 'VertexShader'"

I' have the following CgFx file:
struct VertIn {
float4 pos : POSITION;
float4 color : COLOR0;
};
struct VertOut {
float4 pos : POSITION;
float4 color : COLOR0;
};
VertOut vert(VertIn IN) {
VertOut OUT;
OUT.pos = IN.pos;
OUT.color = IN.color;
OUT.color.z = 0.0f;
return OUT;
}
struct FragIn {
float4 color: COLOR;
};
struct FragOut {
float4 color : COLOR;
};
FragOut frag(FragIn IN) {
FragOut OUT;
OUT.color = IN.color;
OUT.color.y = 0.0f;
return OUT;
}
struct GeomIn {
float4 position : POSITION;
float4 color : COLOR0;
};
TRIANGLE void geom(AttribArray<GeomIn> IN) {
for(int i=0; i<IN.length; i++) {
emitVertex(IN[i]);
}
}
technique technique0 {
pass p0 {
VertexShader = compile gp4vp vert(); //line 47
FragmentShader = compile gp4fp frag(); //line 48
GeometryShader = compile gp4gp geom(); //line 49
}
}
when using cgc to verify the 3 shaders, they all compile fine.
but when I try to compile the whole effect using:
context=cgCreateContext();
effect=cgCreateEffectFromFile(context, "my_shader.cgfx", NULL);
if(!effect) {
printf(ygl.cgGetLastErrorString(NULL));
printf(cgGetLastListing(context));
}
then I get the following errors:
CG ERROR : The compile returned an error.
my_shader.cgfx(47) : error C8001: Unknown state 'VertexShader'
my_shader.cgfx(48) : error C8001: Unknown state 'FragmentShader'
my_shader.cgfx(49) : error C8001: Unknown state 'GeometryShader'
What do I do wrong?
After creating your context, you need to call
cgGLRegisterStates(handle);
where handle is your CG context handle. This will register things like VertexShader, PixelShader, FillMode, etc. I'm not sure why those aren't registered by default, but there you have it.
well, solved it, but don't know how. I think the compiler didn't expect CgFx because i did load a cg profile earlier, so it tried to use that one. but not sure.