Jump to content

  • Log In with Google      Sign In   
  • Create Account


#Actualmolehill mountaineer

Posted 18 November 2012 - 05:14 PM

Hi folks,

I'm trying to display the amount of seconds a program has been running using a simple font engine which samples 2 textures (one for numbers, one for letters). Displaying letters works fine but the numbers come out wrong. By changing the background colors of the textures I've come to the conclusion that I'm not switching shader resources correctly. Can somebody tell me what I'm doing wrong here? Relevant code will most likely be in the DrawString() method.

EDIT: I figure I'm not supposed to switch shader resources before callin Draw(). Comments & suggestion are welcome

FontEngine.cpp

[source lang="cpp"]#include "FontEngine.h"#include "Graphics.h"#include "D3DX11.h"#include "xnamath.h"struct vertexPos{XMFLOAT3 position;XMFLOAT2 texCoord;};FontEngine::FontEngine(Graphics* p_parent): m_bInitialized(false), m_pGraphics(p_parent), m_pInputLayout(NULL), m_pVertexShader(NULL), m_pPixelShader(NULL), m_pLetterMap(NULL), m_pNumberMap(NULL), m_pSampler(NULL), m_pDynamicVertexBuffer(NULL){}FontEngine::~FontEngine(){cleanup();}//remove member objectsvoid FontEngine::cleanup(){m_pGraphics->log(_T("[CLEANING] subsystem FontEngine"));if(m_pInputLayout) m_pInputLayout->Release();if(m_pVertexShader) m_pVertexShader->Release();if(m_pPixelShader) m_pPixelShader->Release();if(m_pLetterMap) m_pLetterMap->Release();if(m_pNumberMap) m_pNumberMap->Release();if(m_pSampler) m_pSampler->Release();if(m_pDynamicVertexBuffer) m_pDynamicVertexBuffer->Release();}bool FontEngine::initialize(){ID3DBlob* vertexShaderBuffer = NULL;bool compileResult = m_pGraphics->CompileD3DShader(_T("Effects/FontTextureMap.fx"), "VS_Main", "vs_4_0", &amp;amp;vertexShaderBuffer);if(!compileResult) //texture shader compilation failed{ MessageBox(NULL, _T("Failed to compile font engine vertex shader"), _T("Fatal Error"), MB_OK); return false;}HRESULT d3dResult;d3dResult = m_pGraphics->getDevice()->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &amp;amp;m_pVertexShader);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create font vertex shader"), _T("Fatal Error"), MB_OK); return false;}D3D11_INPUT_ELEMENT_DESC solidColorLayout[] ={ { "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}};unsigned int totalLayoutElements = ARRAYSIZE( solidColorLayout );d3dResult = m_pGraphics->getDevice()->CreateInputLayout(solidColorLayout, totalLayoutElements, vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), &amp;amp;m_pInputLayout);vertexShaderBuffer->Release();if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create input layout in fontengine"), _T("Fatal Error"), MB_OK); return false;}//compile and create pixel shaderID3DBlob* pixelShaderBuffer;compileResult = m_pGraphics->CompileD3DShader(_T("Effects/FontTextureMap.fx"), "PS_Main", "ps_4_0", &amp;amp;pixelShaderBuffer);if(!compileResult) //compilation of pixel shader failed{ MessageBox(NULL, _T("Failed to compile pixel shader in fontengine"), _T("Fatal Error"), MB_OK); return false;}d3dResult = m_pGraphics->getDevice()->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), 0, &amp;amp;m_pPixelShader);pixelShaderBuffer->Release();//warn user if pixel shader could not be createdif(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create pixel shader in fontengine"), _T("Fatal Error"), MB_OK); return false;}//create shader resource view for lettersd3dResult = D3DX11CreateShaderResourceViewFromFile(m_pGraphics->getDevice(), _T("Graphics/Fonts/testFont2.dds"), 0, 0, &amp;amp;m_pLetterMap, 0);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create shader resource view for letters in fontengine"), _T("Fatal Error"), MB_OK); return false;}//create shader resource view for numbersd3dResult = D3DX11CreateShaderResourceViewFromFile(m_pGraphics->getDevice(), _T("Graphics/Fonts/numbersArial.dds"), 0, 0, &amp;amp;m_pNumberMap, 0);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create shader resource view for numbers in fontengine"), _T("Fatal Error"), MB_OK); return false;}//create sampler stateD3D11_SAMPLER_DESC colorMapDesc;ZeroMemory(&amp;amp;colorMapDesc, sizeof(colorMapDesc)); colorMapDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; colorMapDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; colorMapDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; colorMapDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; colorMapDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; colorMapDesc.MaxLOD = D3D11_FLOAT32_MAX;d3dResult = m_pGraphics->getDevice()->CreateSamplerState(&amp;amp;colorMapDesc, &amp;amp;m_pSampler);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create sampler state in fontengine"), _T("Fatal Error"), MB_OK); return false;}D3D11_BUFFER_DESC vertexDesc;ZeroMemory(&amp;amp;vertexDesc, sizeof(vertexDesc));vertexDesc.Usage = D3D11_USAGE_DYNAMIC;vertexDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;const int sizeOfSprite = sizeof(vertexPos) * 6; //six points to a quadconst int maxLetters = 45; //45 quads to a stringvertexDesc.ByteWidth =sizeOfSprite * maxLetters;//create dynamic bufferd3dResult = m_pGraphics->getDevice()->CreateBuffer(&amp;amp;vertexDesc, NULL, &amp;amp;m_pDynamicVertexBuffer);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create dynamic buffer in fontengine"), _T("Fatal Error"), MB_OK); return false;}//all checks passed - return truem_bInitialized = true;return true;}void FontEngine::drawString(tstring p_message, float p_xPosition, float p_yPosition){//TODO datamembers?//size (in bytes) of a single spriteconst int sizeOfSprite = sizeof(vertexPos) * 6;const int maxLetters = 45;int length = p_message.length();//clamp strings that are too longif(length > maxLetters) length = maxLetters;//per quad two triangles, per triangle three vertices (3*2=6)const int verticesPerLetter = 6;D3D11_MAPPED_SUBRESOURCE mapResource;HRESULT d3dResult = m_pGraphics->getContext()->Map(m_pDynamicVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &amp;amp;mapResource);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to map dynamic buffer in fontengine"), _T("Fatal Error"), MB_OK); return;}vertexPos* spritePtr = (vertexPos*) mapResource.pData;//convert to array of charactersconst wchar_t* cString = p_message.c_str();const int indexA = static_cast<char>('A');const int indexZ = static_cast<char>('Z');const int index0 = static_cast<char>('0');const int index9 = static_cast<char>('9');for(int i = 0; i < length; ++i){ //TODO hardcoded! float charWidth = 32.0f / 800.0f; // Char's height on screen. float charHeight = 32.0f / 640.0f; // Char's texel width. float texelWidth = 32.0f / 864.0f; int texLookup = 0; //the "index" of the character in the texture int letter = static_cast<char>( cString[i] ); //the "index" of the character in the ASCII table //select letter texture by default because we use space as default when the character isn't found on the fontmap m_pGraphics->getContext()->PSSetShaderResources( 0, 1, &amp;amp;m_pLetterMap); if( letter < indexA || letter > indexZ ) //not an uppercase letter? { if(letter < index0 || letter > index9) //not a number? texLookup = ( indexZ - indexA ) + 1; // Grab one index past Z, which is a blank space in the texture. else //it's a number { // Char's texel width. texelWidth = 32.0f / 333.0f; texLookup = (letter - index0); m_pGraphics->getContext()->PSSetShaderResources(1,1, &amp;amp;m_pNumberMap); } } else //uppercase letter { //select letter texture by default because we use space as kind of an error character m_pGraphics->getContext()->PSSetShaderResources( 0, 1, &amp;amp;m_pLetterMap); // A = 0, B = 1, Z = 25, etc. texLookup = ( letter - indexA ); } float thisStartX = p_xPosition + ( charWidth * static_cast<float>( i ) ); float thisEndX = thisStartX + charWidth; float thisEndY = p_yPosition + charHeight; spritePtr[0].position = XMFLOAT3( thisEndX, thisEndY, 0.01f ); spritePtr[1].position = XMFLOAT3( thisEndX, p_yPosition, 0.01f ); spritePtr[2].position = XMFLOAT3( thisStartX, p_yPosition, 0.01f ); spritePtr[3].position = XMFLOAT3( thisStartX, p_yPosition, 0.01f ); spritePtr[4].position = XMFLOAT3( thisStartX, thisEndY, 0.01f ); spritePtr[5].position = XMFLOAT3( thisEndX, thisEndY, 0.01f ); float tuStart = 0.0f + ( texelWidth * static_cast<float>( texLookup ) ); float tuEnd = tuStart + texelWidth; spritePtr[0].texCoord = XMFLOAT2( tuEnd, 0.0f ); spritePtr[1].texCoord = XMFLOAT2( tuEnd, 1.0f ); spritePtr[2].texCoord = XMFLOAT2( tuStart, 1.0f ); spritePtr[3].texCoord = XMFLOAT2( tuStart, 1.0f ); spritePtr[4].texCoord = XMFLOAT2( tuStart, 0.0f ); spritePtr[5].texCoord = XMFLOAT2( tuEnd, 0.0f ); //move forward the size of a single quad (6 vertices per quad) spritePtr += 6; }m_pGraphics->getContext()->Unmap(m_pDynamicVertexBuffer, 0 ); m_pGraphics->getContext()->Draw( 6 * length, 0 );}void FontEngine::setupRender(){ID3D11DeviceContext* context = m_pGraphics->getContext();if(context == 0 ) return; unsigned int stride = sizeof( vertexPos ); unsigned int offset = 0; context->IASetInputLayout( m_pInputLayout ); context->IASetVertexBuffers( 0, 1, &amp;amp;m_pDynamicVertexBuffer, &amp;amp;stride, &amp;amp;offset ); context->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); context->VSSetShader( m_pVertexShader, 0, 0 ); context->PSSetShader( m_pPixelShader, 0, 0 ); context->PSSetSamplers( 0, 1, &amp;amp;m_pSampler );}bool FontEngine::isInitialized(){return m_bInitialized;}[/source]

#2molehill mountaineer

Posted 18 November 2012 - 04:25 PM

Hi folks,

I'm trying to display the amount of seconds a program has been running using a simple font engine which samples 2 textures (one for numbers, one for letters). Displaying letters works fine but the numbers come out wrong. By changing the background colors of the textures I've come to the conclusion that I'm not switching shader resources correctly. Can somebody tell me what I'm doing wrong here? Relevant code will most likely be in the DrawString() method. Explanations and further reading are welcome since I'm obviously a beginner.


FontEngine.cpp

[source lang="cpp"]#include "FontEngine.h"#include "Graphics.h"#include "D3DX11.h"#include "xnamath.h"struct vertexPos{XMFLOAT3 position;XMFLOAT2 texCoord;};FontEngine::FontEngine(Graphics* p_parent): m_bInitialized(false), m_pGraphics(p_parent), m_pInputLayout(NULL), m_pVertexShader(NULL), m_pPixelShader(NULL), m_pLetterMap(NULL), m_pNumberMap(NULL), m_pSampler(NULL), m_pDynamicVertexBuffer(NULL){}FontEngine::~FontEngine(){cleanup();}//remove member objectsvoid FontEngine::cleanup(){m_pGraphics->log(_T("[CLEANING] subsystem FontEngine"));if(m_pInputLayout) m_pInputLayout->Release();if(m_pVertexShader) m_pVertexShader->Release();if(m_pPixelShader) m_pPixelShader->Release();if(m_pLetterMap) m_pLetterMap->Release();if(m_pNumberMap) m_pNumberMap->Release();if(m_pSampler) m_pSampler->Release();if(m_pDynamicVertexBuffer) m_pDynamicVertexBuffer->Release();}bool FontEngine::initialize(){ID3DBlob* vertexShaderBuffer = NULL;bool compileResult = m_pGraphics->CompileD3DShader(_T("Effects/FontTextureMap.fx"), "VS_Main", "vs_4_0", &amp;vertexShaderBuffer);if(!compileResult) //texture shader compilation failed{ MessageBox(NULL, _T("Failed to compile font engine vertex shader"), _T("Fatal Error"), MB_OK); return false;}HRESULT d3dResult;d3dResult = m_pGraphics->getDevice()->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &amp;m_pVertexShader);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create font vertex shader"), _T("Fatal Error"), MB_OK); return false;}D3D11_INPUT_ELEMENT_DESC solidColorLayout[] ={ { "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}};unsigned int totalLayoutElements = ARRAYSIZE( solidColorLayout );d3dResult = m_pGraphics->getDevice()->CreateInputLayout(solidColorLayout, totalLayoutElements, vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), &amp;m_pInputLayout);vertexShaderBuffer->Release();if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create input layout in fontengine"), _T("Fatal Error"), MB_OK); return false;}//compile and create pixel shaderID3DBlob* pixelShaderBuffer;compileResult = m_pGraphics->CompileD3DShader(_T("Effects/FontTextureMap.fx"), "PS_Main", "ps_4_0", &amp;pixelShaderBuffer);if(!compileResult) //compilation of pixel shader failed{ MessageBox(NULL, _T("Failed to compile pixel shader in fontengine"), _T("Fatal Error"), MB_OK); return false;}d3dResult = m_pGraphics->getDevice()->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), 0, &amp;m_pPixelShader);pixelShaderBuffer->Release();//warn user if pixel shader could not be createdif(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create pixel shader in fontengine"), _T("Fatal Error"), MB_OK); return false;}//create shader resource view for lettersd3dResult = D3DX11CreateShaderResourceViewFromFile(m_pGraphics->getDevice(), _T("Graphics/Fonts/testFont2.dds"), 0, 0, &amp;m_pLetterMap, 0);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create shader resource view for letters in fontengine"), _T("Fatal Error"), MB_OK); return false;}//create shader resource view for numbersd3dResult = D3DX11CreateShaderResourceViewFromFile(m_pGraphics->getDevice(), _T("Graphics/Fonts/numbersArial.dds"), 0, 0, &amp;m_pNumberMap, 0);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create shader resource view for numbers in fontengine"), _T("Fatal Error"), MB_OK); return false;}//create sampler stateD3D11_SAMPLER_DESC colorMapDesc;ZeroMemory(&amp;colorMapDesc, sizeof(colorMapDesc)); colorMapDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; colorMapDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; colorMapDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; colorMapDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; colorMapDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; colorMapDesc.MaxLOD = D3D11_FLOAT32_MAX;d3dResult = m_pGraphics->getDevice()->CreateSamplerState(&amp;colorMapDesc, &amp;m_pSampler);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create sampler state in fontengine"), _T("Fatal Error"), MB_OK); return false;}D3D11_BUFFER_DESC vertexDesc;ZeroMemory(&amp;vertexDesc, sizeof(vertexDesc));vertexDesc.Usage = D3D11_USAGE_DYNAMIC;vertexDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;const int sizeOfSprite = sizeof(vertexPos) * 6; //six points to a quadconst int maxLetters = 45; //45 quads to a stringvertexDesc.ByteWidth =sizeOfSprite * maxLetters;//create dynamic bufferd3dResult = m_pGraphics->getDevice()->CreateBuffer(&amp;vertexDesc, NULL, &amp;m_pDynamicVertexBuffer);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create dynamic buffer in fontengine"), _T("Fatal Error"), MB_OK); return false;}//all checks passed - return truem_bInitialized = true;return true;}void FontEngine::drawString(tstring p_message, float p_xPosition, float p_yPosition){//TODO datamembers?//size (in bytes) of a single spriteconst int sizeOfSprite = sizeof(vertexPos) * 6;const int maxLetters = 45;int length = p_message.length();//clamp strings that are too longif(length > maxLetters) length = maxLetters;//per quad two triangles, per triangle three vertices (3*2=6)const int verticesPerLetter = 6;D3D11_MAPPED_SUBRESOURCE mapResource;HRESULT d3dResult = m_pGraphics->getContext()->Map(m_pDynamicVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &amp;mapResource);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to map dynamic buffer in fontengine"), _T("Fatal Error"), MB_OK); return;}vertexPos* spritePtr = (vertexPos*) mapResource.pData;//convert to array of charactersconst wchar_t* cString = p_message.c_str();const int indexA = static_cast<char>('A');const int indexZ = static_cast<char>('Z');const int index0 = static_cast<char>('0');const int index9 = static_cast<char>('9');for(int i = 0; i < length; ++i){ //TODO hardcoded! float charWidth = 32.0f / 800.0f; // Char's height on screen. float charHeight = 32.0f / 640.0f; // Char's texel width. float texelWidth = 32.0f / 864.0f; int texLookup = 0; //the "index" of the character in the texture int letter = static_cast<char>( cString[i] ); //the "index" of the character in the ASCII table //select letter texture by default because we use space as default when the character isn't found on the fontmap m_pGraphics->getContext()->PSSetShaderResources( 0, 1, &amp;m_pLetterMap); if( letter < indexA || letter > indexZ ) //not an uppercase letter? { if(letter < index0 || letter > index9) //not a number? texLookup = ( indexZ - indexA ) + 1; // Grab one index past Z, which is a blank space in the texture. else //it's a number { // Char's texel width. texelWidth = 32.0f / 333.0f; texLookup = (letter - index0); m_pGraphics->getContext()->PSSetShaderResources(1,1, &amp;m_pNumberMap); } } else //uppercase letter { //select letter texture by default because we use space as kind of an error character m_pGraphics->getContext()->PSSetShaderResources( 0, 1, &amp;m_pLetterMap); // A = 0, B = 1, Z = 25, etc. texLookup = ( letter - indexA ); } float thisStartX = p_xPosition + ( charWidth * static_cast<float>( i ) ); float thisEndX = thisStartX + charWidth; float thisEndY = p_yPosition + charHeight; spritePtr[0].position = XMFLOAT3( thisEndX, thisEndY, 0.01f ); spritePtr[1].position = XMFLOAT3( thisEndX, p_yPosition, 0.01f ); spritePtr[2].position = XMFLOAT3( thisStartX, p_yPosition, 0.01f ); spritePtr[3].position = XMFLOAT3( thisStartX, p_yPosition, 0.01f ); spritePtr[4].position = XMFLOAT3( thisStartX, thisEndY, 0.01f ); spritePtr[5].position = XMFLOAT3( thisEndX, thisEndY, 0.01f ); float tuStart = 0.0f + ( texelWidth * static_cast<float>( texLookup ) ); float tuEnd = tuStart + texelWidth; spritePtr[0].texCoord = XMFLOAT2( tuEnd, 0.0f ); spritePtr[1].texCoord = XMFLOAT2( tuEnd, 1.0f ); spritePtr[2].texCoord = XMFLOAT2( tuStart, 1.0f ); spritePtr[3].texCoord = XMFLOAT2( tuStart, 1.0f ); spritePtr[4].texCoord = XMFLOAT2( tuStart, 0.0f ); spritePtr[5].texCoord = XMFLOAT2( tuEnd, 0.0f ); //move forward the size of a single quad (6 vertices per quad) spritePtr += 6; }m_pGraphics->getContext()->Unmap(m_pDynamicVertexBuffer, 0 ); m_pGraphics->getContext()->Draw( 6 * length, 0 );}void FontEngine::setupRender(){ID3D11DeviceContext* context = m_pGraphics->getContext();if(context == 0 ) return; unsigned int stride = sizeof( vertexPos ); unsigned int offset = 0; context->IASetInputLayout( m_pInputLayout ); context->IASetVertexBuffers( 0, 1, &amp;m_pDynamicVertexBuffer, &amp;stride, &amp;offset ); context->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); context->VSSetShader( m_pVertexShader, 0, 0 ); context->PSSetShader( m_pPixelShader, 0, 0 ); context->PSSetSamplers( 0, 1, &amp;m_pSampler );}bool FontEngine::isInitialized(){return m_bInitialized;}[/source]

#1molehill mountaineer

Posted 18 November 2012 - 04:22 PM

Hi folks,

I'm trying to display the amount of seconds a program has been running using a simple font engine which samples 2 textures (one for numbers, one for letters). Displaying letters works fine but the numbers come out wrong. By changing the background colors of the textures I've come to the conclusion that I'm not switching shader resources correctly. Can somebody tell me what I'm doing wrong here? Relevant code will most likely be in the DrawString() method. Explanations and further reading are welcome since I'm obviously a beginner.


FontEngine.cpp

[source lang="cpp"]#include "FontEngine.h"#include "Graphics.h"#include "D3DX11.h"#include "xnamath.h"struct vertexPos{XMFLOAT3 position;XMFLOAT2 texCoord;};FontEngine::FontEngine(Graphics* p_parent): m_bInitialized(false), m_pGraphics(p_parent), m_pInputLayout(NULL), m_pVertexShader(NULL), m_pPixelShader(NULL), m_pLetterMap(NULL), m_pNumberMap(NULL), m_pSampler(NULL), m_pDynamicVertexBuffer(NULL){}FontEngine::~FontEngine(){cleanup();}//remove member objectsvoid FontEngine::cleanup(){m_pGraphics->log(_T("[CLEANING] subsystem FontEngine"));if(m_pInputLayout) m_pInputLayout->Release();if(m_pVertexShader) m_pVertexShader->Release();if(m_pPixelShader) m_pPixelShader->Release();if(m_pLetterMap) m_pLetterMap->Release();if(m_pNumberMap) m_pNumberMap->Release();if(m_pSampler) m_pSampler->Release();if(m_pDynamicVertexBuffer) m_pDynamicVertexBuffer->Release();}bool FontEngine::initialize(){ID3DBlob* vertexShaderBuffer = NULL;bool compileResult = m_pGraphics->CompileD3DShader(_T("Effects/FontTextureMap.fx"), "VS_Main", "vs_4_0", &vertexShaderBuffer);if(!compileResult) //texture shader compilation failed{ MessageBox(NULL, _T("Failed to compile font engine vertex shader"), _T("Fatal Error"), MB_OK); return false;}HRESULT d3dResult;d3dResult = m_pGraphics->getDevice()->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &m_pVertexShader);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create font vertex shader"), _T("Fatal Error"), MB_OK); return false;}D3D11_INPUT_ELEMENT_DESC solidColorLayout[] ={ { "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}};unsigned int totalLayoutElements = ARRAYSIZE( solidColorLayout );d3dResult = m_pGraphics->getDevice()->CreateInputLayout(solidColorLayout, totalLayoutElements, vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), &m_pInputLayout);vertexShaderBuffer->Release();if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create input layout in fontengine"), _T("Fatal Error"), MB_OK); return false;}//compile and create pixel shaderID3DBlob* pixelShaderBuffer;compileResult = m_pGraphics->CompileD3DShader(_T("Effects/FontTextureMap.fx"), "PS_Main", "ps_4_0", &pixelShaderBuffer);if(!compileResult) //compilation of pixel shader failed{ MessageBox(NULL, _T("Failed to compile pixel shader in fontengine"), _T("Fatal Error"), MB_OK); return false;}d3dResult = m_pGraphics->getDevice()->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), 0, &m_pPixelShader);pixelShaderBuffer->Release();//warn user if pixel shader could not be createdif(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create pixel shader in fontengine"), _T("Fatal Error"), MB_OK); return false;}//create shader resource view for lettersd3dResult = D3DX11CreateShaderResourceViewFromFile(m_pGraphics->getDevice(), _T("Graphics/Fonts/testFont2.dds"), 0, 0, &m_pLetterMap, 0);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create shader resource view for letters in fontengine"), _T("Fatal Error"), MB_OK); return false;}//create shader resource view for numbersd3dResult = D3DX11CreateShaderResourceViewFromFile(m_pGraphics->getDevice(), _T("Graphics/Fonts/numbersArial.dds"), 0, 0, &m_pNumberMap, 0);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create shader resource view for numbers in fontengine"), _T("Fatal Error"), MB_OK); return false;}//create sampler stateD3D11_SAMPLER_DESC colorMapDesc;ZeroMemory(&colorMapDesc, sizeof(colorMapDesc)); colorMapDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; colorMapDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; colorMapDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; colorMapDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; colorMapDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; colorMapDesc.MaxLOD = D3D11_FLOAT32_MAX;d3dResult = m_pGraphics->getDevice()->CreateSamplerState(&colorMapDesc, &m_pSampler);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create sampler state in fontengine"), _T("Fatal Error"), MB_OK); return false;}D3D11_BUFFER_DESC vertexDesc;ZeroMemory(&vertexDesc, sizeof(vertexDesc));vertexDesc.Usage = D3D11_USAGE_DYNAMIC;vertexDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;const int sizeOfSprite = sizeof(vertexPos) * 6; //six points to a quadconst int maxLetters = 45; //45 quads to a stringvertexDesc.ByteWidth =sizeOfSprite * maxLetters;//create dynamic bufferd3dResult = m_pGraphics->getDevice()->CreateBuffer(&vertexDesc, NULL, &m_pDynamicVertexBuffer);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to create dynamic buffer in fontengine"), _T("Fatal Error"), MB_OK); return false;}//all checks passed - return truem_bInitialized = true;return true;}void FontEngine::drawString(tstring p_message, float p_xPosition, float p_yPosition){//TODO datamembers?//size (in bytes) of a single spriteconst int sizeOfSprite = sizeof(vertexPos) * 6;const int maxLetters = 45;int length = p_message.length();//clamp strings that are too longif(length > maxLetters) length = maxLetters;//per quad two triangles, per triangle three vertices (3*2=6)const int verticesPerLetter = 6;D3D11_MAPPED_SUBRESOURCE mapResource;HRESULT d3dResult = m_pGraphics->getContext()->Map(m_pDynamicVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapResource);if(FAILED(d3dResult)){ MessageBox(NULL, _T("Failed to map dynamic buffer in fontengine"), _T("Fatal Error"), MB_OK); return;}vertexPos* spritePtr = (vertexPos*) mapResource.pData;//convert to array of charactersconst wchar_t* cString = p_message.c_str();const int indexA = static_cast<char>('A');const int indexZ = static_cast<char>('Z');const int index0 = static_cast<char>('0');const int index9 = static_cast<char>('9');for(int i = 0; i < length; ++i){ //TODO hardcoded! float charWidth = 32.0f / 800.0f; // Char's height on screen. float charHeight = 32.0f / 640.0f; // Char's texel width. float texelWidth = 32.0f / 864.0f; int texLookup = 0; //the "index" of the character in the texture int letter = static_cast<char>( cString[i] ); //the "index" of the character in the ASCII table //select letter texture by default because we use space as default when the character isn't found on the fontmap m_pGraphics->getContext()->PSSetShaderResources( 0, 1, &m_pLetterMap); if( letter < indexA || letter > indexZ ) //not an uppercase letter? { if(letter < index0 || letter > index9) //not a number? texLookup = ( indexZ - indexA ) + 1; // Grab one index past Z, which is a blank space in the texture. else //it's a number { // Char's texel width. texelWidth = 32.0f / 333.0f; texLookup = (letter - index0); m_pGraphics->getContext()->PSSetShaderResources(1,1, &m_pNumberMap); } } else //uppercase letter { //select letter texture by default because we use space as kind of an error character m_pGraphics->getContext()->PSSetShaderResources( 0, 1, &m_pLetterMap); // A = 0, B = 1, Z = 25, etc. texLookup = ( letter - indexA ); } float thisStartX = p_xPosition + ( charWidth * static_cast<float>( i ) ); float thisEndX = thisStartX + charWidth; float thisEndY = p_yPosition + charHeight; spritePtr[0].position = XMFLOAT3( thisEndX, thisEndY, 0.01f ); spritePtr[1].position = XMFLOAT3( thisEndX, p_yPosition, 0.01f ); spritePtr[2].position = XMFLOAT3( thisStartX, p_yPosition, 0.01f ); spritePtr[3].position = XMFLOAT3( thisStartX, p_yPosition, 0.01f ); spritePtr[4].position = XMFLOAT3( thisStartX, thisEndY, 0.01f ); spritePtr[5].position = XMFLOAT3( thisEndX, thisEndY, 0.01f ); float tuStart = 0.0f + ( texelWidth * static_cast<float>( texLookup ) ); float tuEnd = tuStart + texelWidth; spritePtr[0].texCoord = XMFLOAT2( tuEnd, 0.0f ); spritePtr[1].texCoord = XMFLOAT2( tuEnd, 1.0f ); spritePtr[2].texCoord = XMFLOAT2( tuStart, 1.0f ); spritePtr[3].texCoord = XMFLOAT2( tuStart, 1.0f ); spritePtr[4].texCoord = XMFLOAT2( tuStart, 0.0f ); spritePtr[5].texCoord = XMFLOAT2( tuEnd, 0.0f ); //move forward the size of a single quad (6 vertices per quad) spritePtr += 6; }m_pGraphics->getContext()->Unmap(m_pDynamicVertexBuffer, 0 ); m_pGraphics->getContext()->Draw( 6 * length, 0 );}void FontEngine::setupRender(){ID3D11DeviceContext* context = m_pGraphics->getContext();if(context == 0 ) return; unsigned int stride = sizeof( vertexPos ); unsigned int offset = 0; context->IASetInputLayout( m_pInputLayout ); context->IASetVertexBuffers( 0, 1, &m_pDynamicVertexBuffer, &stride, &offset ); context->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); context->VSSetShader( m_pVertexShader, 0, 0 ); context->PSSetShader( m_pPixelShader, 0, 0 ); context->PSSetSamplers( 0, 1, &m_pSampler );}bool FontEngine::isInitialized(){return m_bInitialized;}[/source]

PARTNERS