#include "wiFont.h" #include "wiRenderer.h" #include "wiResourceManager.h" #include "wiHelper.h" #include "wiLoader.h" #include "TextureMapping.h" BufferResource wiFont::vertexBuffer,wiFont::indexBuffer; VertexLayout wiFont::vertexLayout; VertexShader wiFont::vertexShader; PixelShader wiFont::pixelShader; BlendState wiFont::blendState; BufferResource wiFont::constantBuffer; RasterizerState wiFont::rasterizerState; DepthStencilState wiFont::depthStencilState; vector wiFont::vertexList; vector wiFont::fontStyles; wiFont::wiFont(const string& text, wiFontProps props, int style) : props(props), style(style) { this->text = wstring(text.begin(), text.end()); } wiFont::wiFont(const wstring& text, wiFontProps props, int style) : text(text), props(props), style(style) { } wiFont::~wiFont() { } void wiFont::Initialize() { indexBuffer=NULL; vertexBuffer=NULL; vertexLayout=NULL; vertexShader=NULL; pixelShader=NULL; blendState=NULL; constantBuffer=NULL; rasterizerState=NULL; depthStencilState=NULL; } void wiFont::SetUpStates() { RasterizerDesc rs; rs.FillMode=FILL_SOLID; rs.CullMode=CULL_BACK; rs.FrontCounterClockwise=TRUE; rs.DepthBias=0; rs.DepthBiasClamp=0; rs.SlopeScaledDepthBias=0; rs.DepthClipEnable=FALSE; rs.ScissorEnable=FALSE; rs.MultisampleEnable=FALSE; rs.AntialiasedLineEnable=FALSE; wiRenderer::graphicsDevice->CreateRasterizerState(&rs,&rasterizerState); DepthStencilDesc dsd; dsd.DepthEnable = false; dsd.DepthWriteMask = DEPTH_WRITE_MASK_ZERO; dsd.DepthFunc = COMPARISON_LESS; dsd.StencilEnable = false; dsd.StencilReadMask = 0xFF; dsd.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing. dsd.FrontFace.StencilFailOp = STENCIL_OP_KEEP; dsd.FrontFace.StencilDepthFailOp = STENCIL_OP_INCR; dsd.FrontFace.StencilPassOp = STENCIL_OP_KEEP; dsd.FrontFace.StencilFunc = COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing. dsd.BackFace.StencilFailOp = STENCIL_OP_KEEP; dsd.BackFace.StencilDepthFailOp = STENCIL_OP_DECR; dsd.BackFace.StencilPassOp = STENCIL_OP_KEEP; dsd.BackFace.StencilFunc = COMPARISON_ALWAYS; // Create the depth stencil state. wiRenderer::graphicsDevice->CreateDepthStencilState(&dsd, &depthStencilState); BlendDesc bd; ZeroMemory(&bd, sizeof(bd)); bd.RenderTarget[0].BlendEnable = TRUE; bd.RenderTarget[0].SrcBlend = BLEND_SRC_ALPHA; bd.RenderTarget[0].DestBlend = BLEND_INV_SRC_ALPHA; bd.RenderTarget[0].BlendOp = BLEND_OP_ADD; bd.RenderTarget[0].SrcBlendAlpha = BLEND_ONE; bd.RenderTarget[0].DestBlendAlpha = BLEND_INV_SRC_ALPHA; bd.RenderTarget[0].BlendOpAlpha = BLEND_OP_ADD; bd.RenderTarget[0].RenderTargetWriteMask = 0x0f; wiRenderer::graphicsDevice->CreateBlendState(&bd,&blendState); } void wiFont::SetUpCB() { BufferDesc bd; ZeroMemory( &bd, sizeof(bd) ); bd.Usage = USAGE_DYNAMIC; bd.ByteWidth = sizeof(ConstantBuffer); bd.BindFlags = BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = CPU_ACCESS_WRITE; wiRenderer::graphicsDevice->CreateBuffer( &bd, NULL, &constantBuffer ); BindPersistentState(GRAPHICSTHREAD_IMMEDIATE); } void wiFont::LoadShaders() { VertexLayoutDesc layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 }, }; UINT numElements = ARRAYSIZE(layout); VertexShaderInfo* vsinfo = static_cast(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "fontVS.cso", wiResourceManager::VERTEXSHADER, layout, numElements)); if (vsinfo != nullptr){ vertexShader = vsinfo->vertexShader; vertexLayout = vsinfo->vertexLayout; } pixelShader = static_cast(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "fontPS.cso", wiResourceManager::PIXELSHADER)); } void wiFont::SetUpStaticComponents() { SetUpStates(); SetUpCB(); LoadShaders(); LoadVertexBuffer(); LoadIndices(); } void wiFont::CleanUpStatic() { for(unsigned int i=0;iRelease(); vertexBuffer=NULL; if(indexBuffer) indexBuffer->Release(); indexBuffer=NULL; if(vertexShader) vertexShader->Release(); vertexShader=NULL; if(pixelShader) pixelShader->Release(); pixelShader=NULL; if(vertexLayout) vertexLayout->Release(); vertexLayout=NULL; if(constantBuffer) constantBuffer->Release(); constantBuffer=NULL; if(rasterizerState) rasterizerState->Release(); rasterizerState=NULL; if(blendState) blendState->Release(); blendState=NULL; if(depthStencilState) depthStencilState->Release(); depthStencilState=NULL; } void wiFont::BindPersistentState(GRAPHICSTHREAD threadID) { wiRenderer::graphicsDevice->LOCK(); wiRenderer::graphicsDevice->BindConstantBufferVS(constantBuffer, CB_GETBINDSLOT(ConstantBuffer), threadID); wiRenderer::graphicsDevice->UNLOCK(); } void wiFont::ModifyGeo(const wstring& text, wiFontProps props, int style, GRAPHICSTHREAD threadID) { int line = 0, pos = 0; vertexList.resize(text.length()*4); for(unsigned int i=0;iUpdateBuffer(vertexBuffer,vertexList.data(),threadID,sizeof(Vertex) * text.length() * 4); } void wiFont::LoadVertexBuffer() { BufferDesc bd; ZeroMemory( &bd, sizeof(bd) ); bd.Usage = USAGE_DYNAMIC; bd.ByteWidth = sizeof( Vertex ) * MAX_TEXT * 4; bd.BindFlags = BIND_VERTEX_BUFFER; bd.CPUAccessFlags = CPU_ACCESS_WRITE; wiRenderer::graphicsDevice->CreateBuffer( &bd, NULL, &vertexBuffer ); } void wiFont::LoadIndices() { std::vectorindices; indices.resize(MAX_TEXT*6); for(unsigned long i=0;iCreateBuffer( &bd, &InitData, &indexBuffer ); } void wiFont::Draw(GRAPHICSTHREAD threadID){ wiFontProps newProps = props; if(props.h_align==WIFALIGN_CENTER || props.h_align==WIFALIGN_MID) newProps.posX-= textWidth()*0.5f; else if(props.h_align==WIFALIGN_RIGHT) newProps.posX -= textWidth(); if (props.v_align == WIFALIGN_CENTER || props.h_align == WIFALIGN_MID) newProps.posY += textHeight()*0.5f; else if(props.v_align==WIFALIGN_BOTTOM) newProps.posY += textHeight(); ModifyGeo(text, newProps, style, threadID); if(text.length()>0){ wiRenderer::graphicsDevice->BindPrimitiveTopology(PRIMITIVETOPOLOGY::TRIANGLELIST,threadID); wiRenderer::graphicsDevice->BindVertexLayout(vertexLayout,threadID); wiRenderer::graphicsDevice->BindVS(vertexShader,threadID); wiRenderer::graphicsDevice->BindPS(pixelShader,threadID); static thread_local ConstantBuffer* cb = new ConstantBuffer; (*cb).mProjection = XMMatrixTranspose( XMMatrixOrthographicLH((float)wiRenderer::GetScreenWidth(),(float)wiRenderer::GetScreenHeight(),0,100) ); (*cb).mTrans = XMMatrixTranspose(XMMatrixTranslation(newProps.posX, newProps.posY, 0)); (*cb).mDimensions = XMFLOAT4((float)wiRenderer::GetScreenWidth(), (float)wiRenderer::GetScreenHeight(), 0, 0); wiRenderer::graphicsDevice->UpdateBuffer(constantBuffer,cb,threadID); wiRenderer::graphicsDevice->BindRasterizerState(rasterizerState,threadID); wiRenderer::graphicsDevice->BindDepthStencilState(depthStencilState,1,threadID); wiRenderer::graphicsDevice->BindBlendState(blendState,threadID); wiRenderer::graphicsDevice->BindVertexBuffer(vertexBuffer,0,sizeof(Vertex),threadID); wiRenderer::graphicsDevice->BindIndexBuffer(indexBuffer,threadID); wiRenderer::graphicsDevice->BindTexturePS(fontStyles[style].texture,TEXSLOT_ONDEMAND0,threadID); wiRenderer::graphicsDevice->DrawIndexed(text.length()*6,threadID); } } int wiFont::textWidth() { int i=0; int max=0,lineW=0; int len=text.length(); while(itext = wstring(text.begin(), text.end()); } void wiFont::SetText(const wstring& text) { this->text = text; } wstring wiFont::GetText() { return text; } string wiFont::GetTextA() { return string(text.begin(),text.end()); } wiFont::wiFontStyle::wiFontStyle(const string& newName){ wiRenderer::graphicsDevice->LOCK(); name=newName; for(short i=0;i<127;i++) lookup[i].code=lookup[i].offX=lookup[i].offY=0; std::stringstream ss(""),ss1(""); ss<<"fonts/"<add(ss1.str()); file>>texWidth>>texHeight>>recSize>>charSize; int i=0; while(!file.eof()){ i++; int code=0; file>>code; lookup[code].code=code; file>>lookup[code].offX>>lookup[code].offY>>lookup[code].width; } file.close(); } else { wiHelper::messageBox(name,"Could not load Font Data!"); } wiRenderer::graphicsDevice->UNLOCK(); } void wiFont::wiFontStyle::CleanUp(){ SAFE_DELETE(texture); } void wiFont::addFontStyle( const string& toAdd ){ for (auto& x : fontStyles) { if (!x.name.compare(toAdd)) return; } fontStyles.push_back(wiFontStyle(toAdd)); } int wiFont::getFontStyleByName( const string& get ){ for (unsigned int i = 0; i