class FontManager
{
private:
ID3D11SamplerState* pSamplerState;
ID3D11VertexShader* pVertexShader;
ID3D11PixelShader* pPixelShader;
ID3D11InputLayout* pLayout;
ID3D11Buffer* pConstantBuffer;
ID3D11Buffer* pVertexBuffer;
ID3D11Buffer* pInstanceBuffer;
ID3D11Buffer* pIndexBuffer;
struct FontVertex
{
D3DXVECTOR2 pPosition;
D3DXVECTOR2 pTexture;
};
struct GlyphInstance
{
D3DXMATRIX pTransform;
D3DXVECTOR4 pColor;
struct DrawRect
{
float fXpos;
float fYpos;
float fWidth;
float fHeight;
}pDrawRect;
};
public:
FontManager(ID3D11Device* pDevice)
{
Create(pDevice);
}
~FontManager()
{
Destroy();
}
BOOL Create(ID3D11Device* pDevice)
{
ID3D10Blob* pErrorMessage;
ID3D10Blob* pVertexShaderBuffer;
ID3D10Blob* pPixelShaderBuffer;
D3D11_BUFFER_DESC pConstantBufferDesc;
D3D11_SAMPLER_DESC pSamplerDesc;
if(FAILED(D3DX11CompileFromFile(L"Shaders\\Text.hlsl",NULL,NULL,"SpriteVS","vs_5_0",D3D10_SHADER_ENABLE_STRICTNESS,0,NULL,&pVertexShaderBuffer,&pErrorMessage,NULL)))
{
if(pErrorMessage)
ShaderError(pErrorMessage,NULL,L"Shaders\\Text.hlsl");
else
MessageBox(NULL,L"Shaders\\Text.hlsl",L"Missing Shader File",MB_OK);
return FALSE;
}
if(FAILED(D3DX11CompileFromFile(L"Shaders\\Text.hlsl",NULL,NULL,"SpritePS","ps_5_0",D3D10_SHADER_ENABLE_STRICTNESS,0,NULL,&pPixelShaderBuffer,&pErrorMessage,NULL)))
{
if(pErrorMessage)
ShaderError(pErrorMessage,NULL,L"Shaders\\Text.hlsl");
else
MessageBox(NULL,L"Shaders\\Text.hlsl",L"Missing Shader File",MB_OK);
return false;
}
if(FAILED(pDevice->CreateVertexShader(pVertexShaderBuffer->GetBufferPointer(),pVertexShaderBuffer->GetBufferSize(),NULL,&pVertexShader)))
return FALSE;
if(FAILED(pDevice->CreatePixelShader(pPixelShaderBuffer->GetBufferPointer(),pPixelShaderBuffer->GetBufferSize(),NULL,&pPixelShader)))
return FALSE;
D3D11_INPUT_ELEMENT_DESC pFontLayout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TRANSFORM", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
{ "TRANSFORM", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 16, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
{ "TRANSFORM", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 32, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
{ "TRANSFORM", 3, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 48, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 64, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
{ "SOURCERECT", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 80, D3D11_INPUT_PER_INSTANCE_DATA, 1 }
};
unsigned int nElements = ARRAY(pFontLayout);
if(FAILED(pDevice->CreateInputLayout(pFontLayout,nElements,pVertexShaderBuffer->GetBufferPointer(),pVertexShaderBuffer->GetBufferSize(),&pLayout)))
return FALSE;
pVertexShaderBuffer->Release();
pPixelShaderBuffer->Release();
FontVertex pFontQuad[] =
{
{D3DXVECTOR2(0.0f, 0.0f),D3DXVECTOR2(0.0f, 0.0f)},
{D3DXVECTOR2(1.0f, 0.0f),D3DXVECTOR2(1.0f, 0.0f)},
{D3DXVECTOR2(1.0f, 1.0f),D3DXVECTOR2(1.0f, 1.0f)},
{D3DXVECTOR2(0.0f, 1.0f),D3DXVECTOR2(0.0f, 1.0f)}
};
D3D11_BUFFER_DESC pVertexBufferDesc, pInstanceBufferDesc, pIndexBufferDesc;
D3D11_SUBRESOURCE_DATA pVertexData, pIndexData;
pVertexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
pVertexBufferDesc.ByteWidth = sizeof(FontVertex) * 4;
pVertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
pVertexBufferDesc.CPUAccessFlags = 0;
pVertexBufferDesc.MiscFlags = 0;
pVertexBufferDesc.StructureByteStride = 0;
pVertexData.pSysMem = pFontQuad;
pVertexData.SysMemPitch = 0;
pVertexData.SysMemSlicePitch = 0;
if(FAILED(pDevice->CreateBuffer(&pVertexBufferDesc,&pVertexData,&pVertexBuffer)))
return FALSE;
pInstanceBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
pInstanceBufferDesc.ByteWidth = sizeof(GlyphInstance) * 1024;
pInstanceBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
pInstanceBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
pInstanceBufferDesc.MiscFlags = 0;
pInstanceBufferDesc.StructureByteStride = 0;
if(FAILED(pDevice->CreateBuffer(&pInstanceBufferDesc,NULL,&pInstanceBuffer)))
return FALSE;
UINT pFontQuadLayout[] = {0, 1, 2, 3, 0, 2};
pIndexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
pIndexBufferDesc.ByteWidth = sizeof(UINT) * 6;
pIndexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
pIndexBufferDesc.CPUAccessFlags = 0;
pIndexBufferDesc.MiscFlags = 0;
pIndexBufferDesc.StructureByteStride = 0;
pIndexData.pSysMem = pFontQuadLayout;
pIndexData.SysMemPitch = 0;
pIndexData.SysMemSlicePitch = 0;
if(FAILED(pDevice->CreateBuffer(&pIndexBufferDesc,&pIndexData,&pIndexBuffer)))
return FALSE;
pConstantBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
pConstantBufferDesc.ByteWidth = sizeof(D3DXVECTOR4);
pConstantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
pConstantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
pConstantBufferDesc.MiscFlags = 0;
pConstantBufferDesc.StructureByteStride = 0;
if(FAILED(pDevice->CreateBuffer(&pConstantBufferDesc,NULL,&pConstantBuffer)))
return FALSE;
pSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
pSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
pSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
pSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
pSamplerDesc.MipLODBias = 0.0f;
pSamplerDesc.MaxAnisotropy = 1;
pSamplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
pSamplerDesc.BorderColor[0] = 0;
pSamplerDesc.BorderColor[1] = 0;
pSamplerDesc.BorderColor[2] = 0;
pSamplerDesc.BorderColor[3] = 0;
pSamplerDesc.MinLOD = 0;
pSamplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
if(FAILED(pDevice->CreateSamplerState(&pSamplerDesc,&pSamplerState)))
return FALSE;
return TRUE;
}
void Destroy()
{
pSamplerState->Release();
pVertexShader->Release();
pPixelShader->Release();
pLayout->Release();
pConstantBuffer->Release();
pVertexBuffer->Release();
pInstanceBuffer->Release();
pIndexBuffer->Release();
}
void Render(ID3D11DeviceContext* pDeviceContext, ID3D11ShaderResourceView* pTexture, const wchar_t* wszString)
{
D3DXMATRIX pTransform;
D3DXMatrixIdentity(&pTransform);
GlyphInstance pInstance = {pTransform,D3DXVECTOR4(1.0f,1.0f,1.0f,1.0f),{10,10,256,256}};
D3D11_MAPPED_SUBRESOURCE pMap;
if(FAILED(pDeviceContext->Map(pInstanceBuffer,0,D3D11_MAP_WRITE_DISCARD,0,&pMap)))
return;
*(GlyphInstance*)pMap.pData = pInstance;
pDeviceContext->Unmap(pInstanceBuffer,0);
pDeviceContext->IASetInputLayout(pLayout);
pDeviceContext->VSSetShader(pVertexShader,NULL,0);
pDeviceContext->PSSetShader(pPixelShader,NULL,0);
pDeviceContext->PSSetSamplers(0,1,&pSamplerState);
unsigned int dwStride[] = {sizeof(FontVertex),sizeof(GlyphInstance)};
unsigned int dwOffset[] = {0,0};
ID3D11Buffer* pBuffers[] = {pVertexBuffer,pInstanceBuffer};
pDeviceContext->IASetVertexBuffers(0,2,pBuffers,dwStride,dwOffset);
pDeviceContext->IASetIndexBuffer(pIndexBuffer,DXGI_FORMAT_R32_UINT,0);
pDeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
D3D11_MAPPED_SUBRESOURCE pMappedResource;
if(FAILED(pDeviceContext->Map(pConstantBuffer,0,D3D11_MAP_WRITE_DISCARD,0,&pMappedResource)))
return;
D3DXVECTOR4* pData = reinterpret_cast<D3DXVECTOR4*>(pMappedResource.pData);
*pData = D3DXVECTOR4(256,256,1024,768);//hc'ed for now: texture is 256x256, viewport is 1024x768
pDeviceContext->Unmap(pConstantBuffer,0);
pDeviceContext->VSSetConstantBuffers(0,1,&pConstantBuffer);
pDeviceContext->PSSetShaderResources(0,1,&pTexture);
pDeviceContext->DrawIndexedInstanced(6,1,0,0,0);
}
};
Can anyone (MJP?) exlpain to me what I'm missing, as this draws nothing ...EDIT: just to make it clear, this is about my third attempt at creating a ortho projecting VS, best I got was building a ortho transform matrix and mul'ing by that, but that cause quite a few other problems. The code about attempts to rending out the entire font texture to screen as one giant quad at (10,10), just a a test. It might also help to note that this code doesn't crash, nor does it stall the pipeline, its just not rendering anything, at least in the viewport...