diff --git a/font.fx b/font.fx index 5847b40..c618200 100644 --- a/font.fx +++ b/font.fx @@ -1,25 +1,48 @@ +float2 vInvScreenSize; +float2 vPosition; +float2 vGlyphScale; +float2 vCharCoord; +float2 vTexScale; + +Texture2D txDiffuse; +SamplerState samPoint { + Filter = MIN_MAG_MIP_POINT; + AddressU = Wrap; + AddressV = Wrap; +}; + struct VS_INPUT { - float4 Pos : POSITION; + float2 Pos : POSITION; }; struct PS_INPUT { float4 Pos : SV_POSITION; + float2 Tex : TEXCOORD0; }; PS_INPUT VS(VS_INPUT input) { PS_INPUT output = (PS_INPUT)0; - output.Pos = input.Pos; + float2 Pos = input.Pos * vGlyphScale + vPosition; + Pos = Pos * vInvScreenSize + float2(-1, 1); + output.Pos = float4(Pos.xy, 0, 1); + float2 Tex = float2(input.Pos.x, -input.Pos.y); + + output.Tex = (Tex + vCharCoord) * vTexScale; return output; } float4 PS(PS_INPUT input) : SV_Target { - return float4(1, 1, 1, 1); + float4 texColor = txDiffuse.Sample(samPoint, input.Tex); + + float c = texColor.x == 0 ? 0.0 : 1.0; + + return float4(c, c, c, 1); } technique10 Font diff --git a/include/render_state.hpp b/include/render_state.hpp index bd9eabe..a1ed81e 100644 --- a/include/render_state.hpp +++ b/include/render_state.hpp @@ -4,6 +4,8 @@ HRESULT LoadTexture(const wchar_t * resourceName, const int width, const int height, + const int pitch, + const DXGI_FORMAT format, ID3D10ShaderResourceView ** pTextureShaderResourceView); #endif _RENDER_STATE_HPP_ diff --git a/main.rc b/main.rc index 54e2822..dcf670c 100644 --- a/main.rc +++ b/main.rc @@ -1,3 +1,4 @@ RES_MAIN_FXO RCDATA "main.fxo" RES_FONT_FXO RCDATA "font.fxo" -RES_ROBOT_PLAYER RCDATA "robot_player.data" \ No newline at end of file +RES_ROBOT_PLAYER RCDATA "robot_player.data" +RES_FONT_TERMINUS_6X12 RCDATA "font/terminus_128x64_6x12.data" \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 5671de7..90be717 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -52,7 +52,13 @@ ID3D10EffectTechnique * g_pTechniqueFont = NULL; ID3D10InputLayout * g_pVertexLayoutFont = NULL; const DWORD g_dwVertexBufferCountFont = 1; ID3D10Buffer * g_pVertexBuffersFont[g_dwVertexBufferCountFont]; - +ID3D10ShaderResourceView * g_pTextureShaderResourceViewFont = NULL; +ID3D10EffectVectorVariable * g_pInvScreenSizeVariableFont = NULL; +ID3D10EffectVectorVariable * g_pPositionVariableFont = NULL; +ID3D10EffectVectorVariable * g_pGlyphScaleVariableFont = NULL; +ID3D10EffectVectorVariable * g_pCharCoordVariableFont = NULL; +ID3D10EffectVectorVariable * g_pTexScaleVariableFont = NULL; +ID3D10EffectShaderResourceVariable * g_pDiffuseVariableFont = NULL; HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow); LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); @@ -66,6 +72,22 @@ struct WindowSize { UINT Height; }; +struct FontSize { + struct { + UINT Width; + UINT Height; + } Glyph; + struct { + UINT Width; + UINT Height; + } Texture; +}; + +const FontSize g_FontSize = { + { 6, 12 }, + { 128, 64 }, +}; + WindowSize g_ViewportSize; int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) @@ -323,7 +345,23 @@ HRESULT LoadMesh() // textures ////////////////////////////////////////////////////////////////////// - hr = LoadTexture(L"RES_ROBOT_PLAYER", 64, 64, &g_pTextureShaderResourceView); + hr = LoadTexture(L"RES_ROBOT_PLAYER", + 64, // width + 64, // height + 64 * 4, // pitch + DXGI_FORMAT_R8G8B8A8_UNORM, + &g_pTextureShaderResourceView); + if (FAILED(hr)) { + print("LoadTexture\n"); + return hr; + } + + hr = LoadTexture(L"RES_FONT_TERMINUS_6X12", + g_FontSize.Texture.Width, // width + g_FontSize.Texture.Height, // height + g_FontSize.Texture.Width * 1, // pitch + DXGI_FORMAT_R8_UNORM, + &g_pTextureShaderResourceViewFont); if (FAILED(hr)) { print("LoadTexture\n"); return hr; @@ -337,9 +375,10 @@ struct FontVertex { }; const FontVertex FontVertices[] = { - D3DXVECTOR2( 0.0f, 0.5f), - D3DXVECTOR2( 0.5f, -0.5f), - D3DXVECTOR2(-0.5f, -0.5f), + D3DXVECTOR2( 0.0f, 0.0f), // -- top right + D3DXVECTOR2( 1.0f, 0.0f), // -- top left + D3DXVECTOR2( 0.0f, -1.0f), // -- bottom right + D3DXVECTOR2( 1.0f, -1.0f), // -- bottom left }; HRESULT InitFontBuffers() @@ -371,6 +410,12 @@ HRESULT InitFontBuffers() } g_pTechniqueFont = g_pEffectFont->GetTechniqueByName("Font"); + g_pInvScreenSizeVariableFont = g_pEffectFont->GetVariableByName("vInvScreenSize")->AsVector(); + g_pPositionVariableFont = g_pEffectFont->GetVariableByName("vPosition")->AsVector(); + g_pGlyphScaleVariableFont = g_pEffectFont->GetVariableByName("vGlyphScale")->AsVector(); + g_pCharCoordVariableFont = g_pEffectFont->GetVariableByName("vCharCoord")->AsVector(); + g_pTexScaleVariableFont = g_pEffectFont->GetVariableByName("vTexScale")->AsVector(); + g_pDiffuseVariableFont = g_pEffectFont->GetVariableByName("txDiffuse")->AsShaderResource(); ////////////////////////////////////////////////////////////////////// // layout @@ -854,20 +899,38 @@ void RenderModel(float t) void RenderFont() { + D3DXVECTOR2 invScreenSize = D3DXVECTOR2(2.0f / (float)g_ViewportSize.Width, + 2.0f / (float)g_ViewportSize.Height); + + D3DXVECTOR2 position = D3DXVECTOR2(6, 0); + D3DXVECTOR2 glyphScale = D3DXVECTOR2((float)g_FontSize.Glyph.Width, + (float)g_FontSize.Glyph.Height); + + D3DXVECTOR2 charCoord = D3DXVECTOR2(16, 0); + D3DXVECTOR2 texScale = D3DXVECTOR2(glyphScale.x / (float)g_FontSize.Texture.Width, + glyphScale.y / (float)g_FontSize.Texture.Height); + + g_pInvScreenSizeVariableFont->SetFloatVector((float *)&invScreenSize); + g_pPositionVariableFont->SetFloatVector((float *)&position); + g_pGlyphScaleVariableFont->SetFloatVector((float *)&glyphScale); + g_pCharCoordVariableFont->SetFloatVector((float *)&charCoord); + g_pTexScaleVariableFont->SetFloatVector((float *)&texScale); + g_pDiffuseVariableFont->SetResource(g_pTextureShaderResourceViewFont); + UINT stride[] = { (sizeof (FontVertex)), }; UINT offset[] = { 0 }; g_pd3dDevice->IASetInputLayout(g_pVertexLayoutFont); g_pd3dDevice->IASetVertexBuffers(0, g_dwVertexBufferCountFont, g_pVertexBuffersFont, stride, offset); - g_pd3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + g_pd3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); D3D10_TECHNIQUE_DESC techDesc; g_pTechniqueFont->GetDesc(&techDesc); for (UINT p = 0; p < techDesc.Passes; p++) { g_pTechniqueFont->GetPassByIndex(p)->Apply(0); - g_pd3dDevice->Draw(3, 0); + g_pd3dDevice->Draw(4, 0); } } diff --git a/src/render_state.cpp b/src/render_state.cpp index c270987..c8ed5a3 100644 --- a/src/render_state.cpp +++ b/src/render_state.cpp @@ -11,6 +11,8 @@ HRESULT LoadTexture(const wchar_t * resourceName, const int width, const int height, + const int pitch, + const DXGI_FORMAT format, ID3D10ShaderResourceView ** pTextureShaderResourceView) { HRESULT hr; @@ -22,18 +24,19 @@ HRESULT LoadTexture(const wchar_t * resourceName, return -1; } DWORD dwResourceSize = SizeofResource(NULL, hRobotPlayerRes); - assert(width * height * 4 == dwResourceSize); + assert(pitch >= width); + assert(pitch * height == dwResourceSize); HGLOBAL hRobotPlayerData = LoadResource(NULL, hRobotPlayerRes); D3D10_SUBRESOURCE_DATA subresourceData; subresourceData.pSysMem = LockResource(hRobotPlayerData); - subresourceData.SysMemPitch = width * 4; + subresourceData.SysMemPitch = pitch; D3D10_TEXTURE2D_DESC textureDesc; textureDesc.Width = width; textureDesc.Height = height; textureDesc.MipLevels = 1; textureDesc.ArraySize = 1; - textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + textureDesc.Format = format; textureDesc.SampleDesc.Count = 1; textureDesc.SampleDesc.Quality = 0; textureDesc.Usage = D3D10_USAGE_DEFAULT;