我一直在尋找一個好的文本方法最近,發現一個在http://www.braynzarsoft.net/Articles/index.php?p=VA&article=Easy-Font-Rendering-in-DirectX-11,這是一個很好的網站。我似乎無法讓它運行!我已經解決大部分的錯誤,但是,但是在調試,我得到HLSL錯誤:DirectX 11:文本輸出:HLSL/InputLayout麻煩
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 ]
穆斯特?我是!由於此消息是垃圾郵件像瘋了一樣,這個問題是最有可能在我的DrawText()
功能或初始化功能(如下圖),一個壞的執行發生
的InitializeGeneralResources()
功能:
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);
}
我有一個相當簡單的HLSL文件:
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;
}
(該DrawString()
功能)
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;
}
如果你做到了這一點,謝謝。我認爲這可能是因爲我的.hlsl文件可能沒有正確配置以接收紋理,我可能需要知道紋理如何與着色器進行適當的交互以生成輸出。謝謝!