diff --git a/enginecustom/applicationclass.cpp b/enginecustom/applicationclass.cpp index a4d57a4..8da9425 100644 --- a/enginecustom/applicationclass.cpp +++ b/enginecustom/applicationclass.cpp @@ -13,6 +13,11 @@ ApplicationClass::ApplicationClass() m_Sprite = 0; m_Timer = 0; m_Lights = 0; + m_FontShader = 0; + m_Font = 0; + m_TextString1 = 0; + m_TextString2 = 0; + m_TextString3 = 0; } @@ -28,6 +33,7 @@ ApplicationClass::~ApplicationClass() bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) { + char testString1[32], testString2[32], testString3[32]; char modelFilename[128]; char textureFilename1[128], textureFilename2[128]; char bitmapFilename[128]; @@ -61,6 +67,57 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) m_Camera->SetPosition(0.0f, 0.0f, -12.0f); m_Camera->SetRotation(0.0f, 0.0f, 0.0f); + // Create and initialize the font shader object. + m_FontShader = new FontShaderClass; + + result = m_FontShader->Initialize(m_Direct3D->GetDevice(), hwnd); + if (!result) + { + MessageBox(hwnd, L"Could not initialize the font shader object.", L"Error", MB_OK); + return false; + } + + // Create and initialize the font object. + m_Font = new FontClass; + + result = m_Font->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), 0); + if (!result) + { + return false; + } + + // Set the strings we want to display. + strcpy_s(testString1, "Yo"); + strcpy_s(testString2, "Les"); + strcpy_s(testString3, "Noobs !"); + + // Create and initialize the first text object. + m_TextString1 = new TextClass; + + result = m_TextString1->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), screenWidth, screenHeight, 32, m_Font, testString1, 25, screenHeight / 2 - m_Font->GetFontHeight(), 1.0f, 1.0f, 1.0f); + if (!result) + { + return false; + } + + // Create and initialize the second text object. + m_TextString2 = new TextClass; + + result = m_TextString2->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), screenWidth, screenHeight, 32, m_Font, testString2, 250, screenHeight / 2 - m_Font->GetFontHeight(), 0.0f, 1.0f, 1.0f); + if (!result) + { + return false; + } + + // Create and initialize the second text object. + m_TextString3 = new TextClass; + + result = m_TextString3->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), screenWidth, screenHeight, 32, m_Font, testString3, screenWidth / 2 - m_Font->GetSentencePixelLength(testString3), screenHeight / 2 - m_Font->GetFontHeight(), 1.0f, 1.0f, 0.0f); + if (!result) + { + return false; + } + // Create and initialize the texture shader object. m_TextureShader = new TextureShaderClass; @@ -167,6 +224,44 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) void ApplicationClass::Shutdown() { + // Release the text string objects. + if (m_TextString3) + { + m_TextString3->Shutdown(); + delete m_TextString3; + m_TextString3 = 0; + } + + if (m_TextString2) + { + m_TextString2->Shutdown(); + delete m_TextString2; + m_TextString2 = 0; + } + + if (m_TextString1) + { + m_TextString1->Shutdown(); + delete m_TextString1; + m_TextString1 = 0; + } + + // Release the font object. + if (m_Font) + { + m_Font->Shutdown(); + delete m_Font; + m_Font = 0; + } + + // Release the font shader object. + if (m_FontShader) + { + m_FontShader->Shutdown(); + delete m_FontShader; + m_FontShader = 0; + } + // Release the timer object. if (m_Timer) { @@ -319,8 +414,39 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z) m_Direct3D->GetProjectionMatrix(projectionMatrix); m_Direct3D->GetOrthoMatrix(orthoMatrix); - // Turn off the Z buffer to begin all 2D rendering. + // Disable the Z buffer and enable alpha blending for 2D rendering. m_Direct3D->TurnZBufferOff(); + m_Direct3D->EnableAlphaBlending(); + + // Render the first text string using the font shader. + m_TextString1->Render(m_Direct3D->GetDeviceContext()); + + result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_TextString1->GetIndexCount(), worldMatrix, viewMatrix, orthoMatrix, + m_Font->GetTexture(), m_TextString1->GetPixelColor()); + if (!result) + { + return false; + } + + // Render the second text string using the font shader. + m_TextString2->Render(m_Direct3D->GetDeviceContext()); + + result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_TextString2->GetIndexCount(), worldMatrix, viewMatrix, orthoMatrix, + m_Font->GetTexture(), m_TextString2->GetPixelColor()); + if (!result) + { + return false; + } + + // Render the second text string using the font shader. + m_TextString3->Render(m_Direct3D->GetDeviceContext()); + + result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_TextString3->GetIndexCount(), worldMatrix, viewMatrix, orthoMatrix, + m_Font->GetTexture(), m_TextString3->GetPixelColor()); + if (!result) + { + return false; + } // Put the sprite vertex and index buffers on the graphics pipeline to prepare them for drawing. result = m_Sprite->Render(m_Direct3D->GetDeviceContext()); @@ -398,8 +524,9 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z) result = m_MultiTextureShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(0), m_Model->GetTexture(1)); - // Turn the Z buffer back on now that all 2D rendering has completed. + // Enable the Z buffer and disable alpha blending now that 2D rendering is complete. m_Direct3D->TurnZBufferOn(); + m_Direct3D->DisableAlphaBlending(); // Present the rendered scene to the screen. m_Direct3D->EndScene(); diff --git a/enginecustom/applicationclass.h b/enginecustom/applicationclass.h index 13719f0..fe7a529 100644 --- a/enginecustom/applicationclass.h +++ b/enginecustom/applicationclass.h @@ -15,6 +15,9 @@ #include "textureshaderclass.h" #include "spriteclass.h" #include "timerclass.h" +#include "fontshaderclass.h" +#include "fontclass.h" +#include "textclass.h" ///////////// // GLOBALS // @@ -54,6 +57,9 @@ private: TimerClass* m_Timer; LightClass* m_Lights; int m_numLights; + FontShaderClass* m_FontShader; + FontClass* m_Font; + TextClass *m_TextString1, *m_TextString2, *m_TextString3; }; #endif diff --git a/enginecustom/d3dclass.cpp b/enginecustom/d3dclass.cpp index e91e8c7..53022f5 100644 --- a/enginecustom/d3dclass.cpp +++ b/enginecustom/d3dclass.cpp @@ -15,6 +15,8 @@ D3DClass::D3DClass() m_depthStencilView = 0; m_rasterState = 0; m_depthDisabledStencilState = 0; + m_alphaEnableBlendingState = 0; + m_alphaDisableBlendingState = 0; } @@ -48,6 +50,7 @@ bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hw D3D11_RASTERIZER_DESC rasterDesc; float fieldOfView, screenAspect; D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc; + D3D11_BLEND_DESC blendStateDescription; // Store the vsync setting. m_vsync_enabled = vsync; @@ -373,6 +376,35 @@ bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hw return false; } + // Clear the blend state description. + ZeroMemory(&blendStateDescription, sizeof(D3D11_BLEND_DESC)); + + // Create an alpha enabled blend state description. + blendStateDescription.RenderTarget[0].BlendEnable = TRUE; + blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; + blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 0x0f; + + // Create the blend state using the description. + result = m_device->CreateBlendState(&blendStateDescription, &m_alphaEnableBlendingState); + if (FAILED(result)) + { + return false; + } + + // Modify the description to create an alpha disabled blend state description. + blendStateDescription.RenderTarget[0].BlendEnable = FALSE; + + // Create the blend state using the description. + result = m_device->CreateBlendState(&blendStateDescription, &m_alphaDisableBlendingState); + if (FAILED(result)) + { + return false; + } return true; } @@ -386,6 +418,18 @@ void D3DClass::Shutdown() m_swapChain->SetFullscreenState(false, NULL); } + if (m_alphaEnableBlendingState) + { + m_alphaEnableBlendingState->Release(); + m_alphaEnableBlendingState = 0; + } + + if (m_alphaDisableBlendingState) + { + m_alphaDisableBlendingState->Release(); + m_alphaDisableBlendingState = 0; + } + if (m_depthDisabledStencilState) { m_depthDisabledStencilState->Release(); @@ -552,4 +596,38 @@ void D3DClass::TurnZBufferOff() { m_deviceContext->OMSetDepthStencilState(m_depthDisabledStencilState, 1); return; -} \ No newline at end of file +} + +void D3DClass::EnableAlphaBlending() +{ + float blendFactor[4]; + + + // Setup the blend factor. + blendFactor[0] = 0.0f; + blendFactor[1] = 0.0f; + blendFactor[2] = 0.0f; + blendFactor[3] = 0.0f; + + // Turn on the alpha blending. + m_deviceContext->OMSetBlendState(m_alphaEnableBlendingState, blendFactor, 0xffffffff); + + return; +} + +void D3DClass::DisableAlphaBlending() +{ + float blendFactor[4]; + + + // Setup the blend factor. + blendFactor[0] = 0.0f; + blendFactor[1] = 0.0f; + blendFactor[2] = 0.0f; + blendFactor[3] = 0.0f; + + // Turn off the alpha blending. + m_deviceContext->OMSetBlendState(m_alphaDisableBlendingState, blendFactor, 0xffffffff); + + return; +} diff --git a/enginecustom/d3dclass.h b/enginecustom/d3dclass.h index bb3c0ce..c6b64fd 100644 --- a/enginecustom/d3dclass.h +++ b/enginecustom/d3dclass.h @@ -16,8 +16,11 @@ ////////////// // INCLUDES // ////////////// -#include -#include +#include "d3d11.h" +#include "directxmath.h" +#include "fontshaderclass.h" +#include "fontclass.h" +#include "textclass.h" using namespace DirectX; @@ -52,6 +55,9 @@ public: void TurnZBufferOn(); void TurnZBufferOff(); + void EnableAlphaBlending(); + void DisableAlphaBlending(); + private: bool m_vsync_enabled; int m_videoCardMemory; @@ -69,6 +75,8 @@ private: XMMATRIX m_orthoMatrix; D3D11_VIEWPORT m_viewport; ID3D11DepthStencilState* m_depthDisabledStencilState; + ID3D11BlendState* m_alphaEnableBlendingState; + ID3D11BlendState* m_alphaDisableBlendingState; }; #endif \ No newline at end of file diff --git a/enginecustom/enginecustom.vcxproj b/enginecustom/enginecustom.vcxproj index f7ce25d..0628418 100644 --- a/enginecustom/enginecustom.vcxproj +++ b/enginecustom/enginecustom.vcxproj @@ -25,6 +25,8 @@ + + @@ -33,6 +35,7 @@ + @@ -43,6 +46,8 @@ + + @@ -50,11 +55,14 @@ + + + @@ -82,6 +90,7 @@ + @@ -89,6 +98,7 @@ + diff --git a/enginecustom/font.ps b/enginecustom/font.ps new file mode 100644 index 0000000..7de7ce3 --- /dev/null +++ b/enginecustom/font.ps @@ -0,0 +1,47 @@ +///////////// +// GLOBALS // +///////////// +Texture2D shaderTexture : register(t0); +SamplerState SampleType : register(s0); + +cbuffer PixelBuffer +{ + float4 pixelColor; +}; + + +////////////// +// TYPEDEFS // +////////////// +struct PixelInputType +{ + float4 position : SV_POSITION; + float2 tex : TEXCOORD0; +}; + +//////////////////////////////////////////////////////////////////////////////// +// Pixel Shader +//////////////////////////////////////////////////////////////////////////////// +float4 FontPixelShader(PixelInputType input) : SV_TARGET +{ + float4 color; + + + // Sample the texture pixel at this location. + color = shaderTexture.Sample(SampleType, input.tex); + + // If the color is black on the texture then treat this pixel as transparent. + if(color.r == 0.0f) + { + color.a = 0.0f; + } + + // If the color is other than black on the texture then this is a pixel in the font so draw it using the font pixel color. + else + { + color.a = 1.0f; + color = color * pixelColor; + } + + return color; +} diff --git a/enginecustom/font.vs b/enginecustom/font.vs new file mode 100644 index 0000000..0b71af3 --- /dev/null +++ b/enginecustom/font.vs @@ -0,0 +1,48 @@ +///////////// +// GLOBALS // +///////////// +cbuffer MatrixBuffer +{ + matrix worldMatrix; + matrix viewMatrix; + matrix projectionMatrix; +}; + + +////////////// +// TYPEDEFS // +////////////// +struct VertexInputType +{ + float4 position : POSITION; + float2 tex : TEXCOORD0; +}; + +struct PixelInputType +{ + float4 position : SV_POSITION; + float2 tex : TEXCOORD0; +}; + + +//////////////////////////////////////////////////////////////////////////////// +// Vertex Shader +//////////////////////////////////////////////////////////////////////////////// +PixelInputType FontVertexShader(VertexInputType input) +{ + PixelInputType output; + + + // Change the position vector to be 4 units for proper matrix calculations. + input.position.w = 1.0f; + + // Calculate the position of the vertex against the world, view, and projection matrices. + output.position = mul(input.position, worldMatrix); + output.position = mul(output.position, viewMatrix); + output.position = mul(output.position, projectionMatrix); + + // Store the texture coordinates for the pixel shader. + output.tex = input.tex; + + return output; +} diff --git a/enginecustom/font01.tga b/enginecustom/font01.tga new file mode 100644 index 0000000..042989d Binary files /dev/null and b/enginecustom/font01.tga differ diff --git a/enginecustom/font01.txt b/enginecustom/font01.txt new file mode 100644 index 0000000..b96a96f --- /dev/null +++ b/enginecustom/font01.txt @@ -0,0 +1,95 @@ +32 0.0 0.0 0 +33 ! 0.0 0.00390625 4 +34 " 0.0048828125 0.0107421875 6 +35 # 0.01171875 0.025390625 14 +36 $ 0.0263671875 0.0390625 13 +37 % 0.0400390625 0.0546875 15 +38 & 0.0556640625 0.0693359375 14 +39 ' 0.0703125 0.0732421875 3 +40 ( 0.07421875 0.0791015625 5 +41 ) 0.080078125 0.0849609375 5 +42 * 0.0859375 0.091796875 6 +43 + 0.0927734375 0.103515625 11 +44 , 0.1044921875 0.107421875 3 +45 - 0.1083984375 0.1142578125 6 +46 . 0.115234375 0.1181640625 3 +47 / 0.119140625 0.126953125 8 +48 0 0.1279296875 0.1416015625 14 +49 1 0.142578125 0.146484375 4 +50 2 0.1474609375 0.1591796875 12 +51 3 0.16015625 0.1708984375 11 +52 4 0.171875 0.1845703125 13 +53 5 0.185546875 0.1962890625 11 +54 6 0.197265625 0.2099609375 13 +55 7 0.2109375 0.22265625 12 +56 8 0.2236328125 0.236328125 13 +57 9 0.2373046875 0.2490234375 12 +58 : 0.25 0.2529296875 3 +59 ; 0.25390625 0.2568359375 3 +60 < 0.2578125 0.267578125 10 +61 = 0.2685546875 0.279296875 11 +62 > 0.2802734375 0.2900390625 10 +63 ? 0.291015625 0.302734375 12 +64 @ 0.3037109375 0.3173828125 14 +65 A 0.318359375 0.33203125 14 +66 B 0.3330078125 0.3447265625 12 +67 C 0.345703125 0.3564453125 11 +68 D 0.357421875 0.3701171875 13 +69 E 0.37109375 0.3818359375 11 +70 F 0.3828125 0.3935546875 11 +71 G 0.39453125 0.40625 12 +72 H 0.4072265625 0.41796875 11 +73 I 0.4189453125 0.421875 3 +74 J 0.4228515625 0.4326171875 10 +75 K 0.43359375 0.4443359375 11 +76 L 0.4453125 0.4541015625 9 +77 M 0.455078125 0.4697265625 15 +78 N 0.470703125 0.482421875 12 +79 O 0.4833984375 0.49609375 13 +80 P 0.4970703125 0.5078125 12 +81 Q 0.509765625 0.5224609375 13 +82 R 0.5234375 0.53515625 12 +83 S 0.5361328125 0.548828125 13 +84 T 0.5498046875 0.5615234375 12 +85 U 0.5625 0.57421875 12 +86 V 0.5751953125 0.5888671875 14 +87 W 0.58984375 0.609375 20 +88 X 0.6103515625 0.6220703125 12 +89 Y 0.623046875 0.6357421875 13 +90 Z 0.63671875 0.6474609375 11 +91 [ 0.6484375 0.654296875 6 +92 \ 0.6552734375 0.6630859375 8 +93 ] 0.6640625 0.6689453125 5 +94 ^ 0.669921875 0.6806640625 11 +95 _ 0.681640625 0.6904296875 9 +96 ` 0.69140625 0.6962890625 5 +97 a 0.697265625 0.70703125 10 +98 b 0.7080078125 0.7177734375 10 +99 c 0.71875 0.7275390625 9 +100 d 0.728515625 0.73828125 10 +101 e 0.7392578125 0.748046875 9 +102 f 0.7490234375 0.755859375 7 +103 g 0.7568359375 0.7666015625 10 +104 h 0.767578125 0.7763671875 9 +105 i 0.77734375 0.7802734375 3 +106 j 0.78125 0.7861328125 5 +107 k 0.787109375 0.796875 10 +108 l 0.7978515625 0.80078125 3 +109 m 0.8017578125 0.8154296875 14 +110 n 0.81640625 0.826171875 10 +111 o 0.8271484375 0.8369140625 10 +112 p 0.837890625 0.84765625 10 +113 q 0.8486328125 0.8583984375 10 +114 r 0.859375 0.8671875 8 +115 s 0.8681640625 0.8779296875 10 +116 t 0.87890625 0.8857421875 7 +117 u 0.88671875 0.8955078125 9 +118 v 0.896484375 0.908203125 12 +119 w 0.9091796875 0.9248046875 16 +120 x 0.92578125 0.935546875 10 +121 y 0.9365234375 0.9453125 9 +122 z 0.9462890625 0.9560546875 10 +123 { 0.95703125 0.9638671875 7 +124 | 0.96484375 0.966796875 2 +125 } 0.9677734375 0.974609375 7 +126 ~ 0.9755859375 0.986328125 11 diff --git a/enginecustom/fontclass.cpp b/enginecustom/fontclass.cpp new file mode 100644 index 0000000..68b4f4b --- /dev/null +++ b/enginecustom/fontclass.cpp @@ -0,0 +1,252 @@ +#include "fontclass.h" + +FontClass::FontClass() +{ + m_Font = 0; + m_Texture = 0; +} + + +FontClass::FontClass(const FontClass& other) +{ +} + + +FontClass::~FontClass() +{ +} + +bool FontClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceContext, int fontChoice) +{ + char fontFilename[128]; + char fontTextureFilename[128]; + bool result; + + // Choose one of the available fonts, and default to the first font otherwise. + switch (fontChoice) + { + case 0: + { + strcpy_s(fontFilename, "font01.txt"); + strcpy_s(fontTextureFilename, "font01.tga"); + m_fontHeight = 32.0f; + m_spaceSize = 3; + break; + } + default: + { + strcpy_s(fontFilename, "font01.txt"); + strcpy_s(fontTextureFilename, "font01.tga"); + m_fontHeight = 32.0f; + m_spaceSize = 3; + break; + } + } + + // Load in the text file containing the font data. + result = LoadFontData(fontFilename); + if (!result) + { + return false; + } + + // Load the texture that has the font characters on it. + result = LoadTexture(device, deviceContext, fontTextureFilename); + if (!result) + { + return false; + } + + return true; +} + +void FontClass::Shutdown() +{ + // Release the font texture. + ReleaseTexture(); + + // Release the font data. + ReleaseFontData(); + + return; +} + +bool FontClass::LoadFontData(char* filename) +{ + std::ifstream fin; + int i; + char temp; + + // Create the font spacing buffer. + m_Font = new FontType[95]; + + // Read in the font size and spacing between chars. + fin.open(filename); + if (fin.fail()) + { + return false; + } + + // Read in the 95 used ascii characters for text. + for (i = 0; i < 95; i++) + { + fin.get(temp); + while (temp != ' ') + { + fin.get(temp); + } + fin.get(temp); + while (temp != ' ') + { + fin.get(temp); + } + + fin >> m_Font[i].left; + fin >> m_Font[i].right; + fin >> m_Font[i].size; + } + + // Close the file. + fin.close(); + + return true; +} + +void FontClass::ReleaseFontData() +{ + // Release the font data array. + if (m_Font) + { + delete[] m_Font; + m_Font = 0; + } + + return; +} + +bool FontClass::LoadTexture(ID3D11Device* device, ID3D11DeviceContext* deviceContext, char* filename) +{ + bool result; + + + // Create and initialize the font texture object. + m_Texture = new TextureClass; + + result = m_Texture->Initialize(device, deviceContext, filename); + if (!result) + { + return false; + } + + return true; +} + +void FontClass::ReleaseTexture() +{ + // Release the texture object. + if (m_Texture) + { + m_Texture->Shutdown(); + delete m_Texture; + m_Texture = 0; + } + + return; +} + +ID3D11ShaderResourceView* FontClass::GetTexture() +{ + return m_Texture->GetTexture(); +} + +void FontClass::BuildVertexArray(void* vertices, char* sentence, float drawX, float drawY) +{ + VertexType* vertexPtr; + int numLetters, index, i, letter; + + + // Coerce the input vertices into a VertexType structure. + vertexPtr = (VertexType*)vertices; + + // Get the number of letters in the sentence. + numLetters = (int)strlen(sentence); + + // Initialize the index to the vertex array. + index = 0; + + // Draw each letter onto a quad. + for (i = 0; i < numLetters; i++) + { + letter = ((int)sentence[i]) - 32; + + // If the letter is a space then just move over three pixels. + if (letter == 0) + { + drawX = drawX + m_spaceSize; + } + else + { + // First triangle in quad. + vertexPtr[index].position = XMFLOAT3(drawX, drawY, 0.0f); // Top left. + vertexPtr[index].texture = XMFLOAT2(m_Font[letter].left, 0.0f); + index++; + + vertexPtr[index].position = XMFLOAT3((drawX + m_Font[letter].size), (drawY - m_fontHeight), 0.0f); // Bottom right. + vertexPtr[index].texture = XMFLOAT2(m_Font[letter].right, 1.0f); + index++; + + vertexPtr[index].position = XMFLOAT3(drawX, (drawY - m_fontHeight), 0.0f); // Bottom left. + vertexPtr[index].texture = XMFLOAT2(m_Font[letter].left, 1.0f); + index++; + + // Second triangle in quad. + vertexPtr[index].position = XMFLOAT3(drawX, drawY, 0.0f); // Top left. + vertexPtr[index].texture = XMFLOAT2(m_Font[letter].left, 0.0f); + index++; + + vertexPtr[index].position = XMFLOAT3(drawX + m_Font[letter].size, drawY, 0.0f); // Top right. + vertexPtr[index].texture = XMFLOAT2(m_Font[letter].right, 0.0f); + index++; + + vertexPtr[index].position = XMFLOAT3((drawX + m_Font[letter].size), (drawY - m_fontHeight), 0.0f); // Bottom right. + vertexPtr[index].texture = XMFLOAT2(m_Font[letter].right, 1.0f); + index++; + + // Update the x location for drawing by the size of the letter and one pixel. + drawX = drawX + m_Font[letter].size + 1.0f; + } + } + + return; +} + +int FontClass::GetSentencePixelLength(char* sentence) +{ + int pixelLength, numLetters, i, letter; + + + pixelLength = 0; + numLetters = (int)strlen(sentence); + + for (i = 0; i < numLetters; i++) + { + letter = ((int)sentence[i]) - 32; + + // If the letter is a space then count it as three pixels. + if (letter == 0) + { + pixelLength += m_spaceSize; + } + else + { + pixelLength += (m_Font[letter].size + 1); + } + } + + return pixelLength; +} + +int FontClass::GetFontHeight() +{ + return (int)m_fontHeight; +} diff --git a/enginecustom/fontclass.h b/enginecustom/fontclass.h new file mode 100644 index 0000000..cd5a11e --- /dev/null +++ b/enginecustom/fontclass.h @@ -0,0 +1,64 @@ +#ifndef _FONTCLASS_H_ +#define _FONTCLASS_H_ + + +////////////// +// INCLUDES // +////////////// +#include +#include +using namespace DirectX; + + +/////////////////////// +// MY CLASS INCLUDES // +/////////////////////// +#include "textureclass.h" + + +//////////////////////////////////////////////////////////////////////////////// +// Class name: FontClass +//////////////////////////////////////////////////////////////////////////////// +class FontClass +{ +private: + struct FontType + { + float left, right; + int size; + }; + + struct VertexType + { + XMFLOAT3 position; + XMFLOAT2 texture; + }; + +public: + FontClass(); + FontClass(const FontClass&); + ~FontClass(); + + bool Initialize(ID3D11Device*, ID3D11DeviceContext*, int); + void Shutdown(); + + ID3D11ShaderResourceView* GetTexture(); + + void BuildVertexArray(void*, char*, float, float); + int GetSentencePixelLength(char*); + int GetFontHeight(); + +private: + bool LoadFontData(char*); + void ReleaseFontData(); + bool LoadTexture(ID3D11Device*, ID3D11DeviceContext*, char*); + void ReleaseTexture(); + +private: + FontType* m_Font; + TextureClass* m_Texture; + float m_fontHeight; + int m_spaceSize; +}; + +#endif \ No newline at end of file diff --git a/enginecustom/fontshaderclass.cpp b/enginecustom/fontshaderclass.cpp new file mode 100644 index 0000000..21978f1 --- /dev/null +++ b/enginecustom/fontshaderclass.cpp @@ -0,0 +1,408 @@ +#include "fontshaderclass.h" + + +FontShaderClass::FontShaderClass() +{ + m_vertexShader = 0; + m_pixelShader = 0; + m_layout = 0; + m_matrixBuffer = 0; + m_sampleState = 0; + m_pixelBuffer = 0; +} + + +FontShaderClass::FontShaderClass(const FontShaderClass& other) +{ +} + + +FontShaderClass::~FontShaderClass() +{ +} + + +bool FontShaderClass::Initialize(ID3D11Device* device, HWND hwnd) +{ + bool result; + wchar_t vsFilename[128]; + wchar_t psFilename[128]; + int error; + + // Set the filename of the vertex shader. + error = wcscpy_s(vsFilename, 128, L"font.vs"); + if (error != 0) + { + return false; + } + + // Set the filename of the pixel shader. + error = wcscpy_s(psFilename, 128, L"font.ps"); + if (error != 0) + { + return false; + } + + // Initialize the vertex and pixel shaders. + result = InitializeShader(device, hwnd, vsFilename, psFilename); + if (!result) + { + return false; + } + + return true; +} + +void FontShaderClass::Shutdown() +{ + // Shutdown the vertex and pixel shaders as well as the related objects. + ShutdownShader(); + + return; +} + +bool FontShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, + XMMATRIX projectionMatrix, ID3D11ShaderResourceView* texture, XMFLOAT4 pixelColor) +{ + bool result; + + + // Set the shader parameters that it will use for rendering. + result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, pixelColor); + if (!result) + { + return false; + } + + // Now render the prepared buffers with the shader. + RenderShader(deviceContext, indexCount); + + return true; +} + +bool FontShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR* vsFilename, WCHAR* psFilename) +{ + HRESULT result; + ID3D10Blob* errorMessage; + ID3D10Blob* vertexShaderBuffer; + ID3D10Blob* pixelShaderBuffer; + D3D11_INPUT_ELEMENT_DESC polygonLayout[2]; + unsigned int numElements; + D3D11_BUFFER_DESC matrixBufferDesc; + D3D11_SAMPLER_DESC samplerDesc; + D3D11_BUFFER_DESC pixelBufferDesc; + + + // Initialize the pointers this function will use to null. + errorMessage = 0; + vertexShaderBuffer = 0; + pixelShaderBuffer = 0; + + // Compile the vertex shader code. + result = D3DCompileFromFile(vsFilename, NULL, NULL, "FontVertexShader", "vs_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, + &vertexShaderBuffer, &errorMessage); + if (FAILED(result)) + { + // If the shader failed to compile it should have writen something to the error message. + if (errorMessage) + { + OutputShaderErrorMessage(errorMessage, hwnd, vsFilename); + } + // If there was nothing in the error message then it simply could not find the shader file itself. + else + { + MessageBox(hwnd, vsFilename, L"Missing Shader File", MB_OK); + } + + return false; + } + + // Compile the pixel shader code. + result = D3DCompileFromFile(psFilename, NULL, NULL, "FontPixelShader", "ps_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, + &pixelShaderBuffer, &errorMessage); + if (FAILED(result)) + { + // If the shader failed to compile it should have writen something to the error message. + if (errorMessage) + { + OutputShaderErrorMessage(errorMessage, hwnd, psFilename); + } + // If there was nothing in the error message then it simply could not find the file itself. + else + { + MessageBox(hwnd, psFilename, L"Missing Shader File", MB_OK); + } + + return false; + } + + // Create the vertex shader from the buffer. + result = device->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &m_vertexShader); + if (FAILED(result)) + { + return false; + } + + // Create the pixel shader from the buffer. + result = device->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &m_pixelShader); + if (FAILED(result)) + { + return false; + } + + // Create the vertex input layout description. + polygonLayout[0].SemanticName = "POSITION"; + polygonLayout[0].SemanticIndex = 0; + polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT; + polygonLayout[0].InputSlot = 0; + polygonLayout[0].AlignedByteOffset = 0; + polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + polygonLayout[0].InstanceDataStepRate = 0; + + polygonLayout[1].SemanticName = "TEXCOORD"; + polygonLayout[1].SemanticIndex = 0; + polygonLayout[1].Format = DXGI_FORMAT_R32G32_FLOAT; + polygonLayout[1].InputSlot = 0; + polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; + polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + polygonLayout[1].InstanceDataStepRate = 0; + + // Get a count of the elements in the layout. + numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]); + + // Create the vertex input layout. + result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(), + vertexShaderBuffer->GetBufferSize(), &m_layout); + if (FAILED(result)) + { + return false; + } + + // Release the vertex shader buffer and pixel shader buffer since they are no longer needed. + vertexShaderBuffer->Release(); + vertexShaderBuffer = 0; + + pixelShaderBuffer->Release(); + pixelShaderBuffer = 0; + + // Setup the description of the dynamic matrix constant buffer that is in the vertex shader. + matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + matrixBufferDesc.ByteWidth = sizeof(MatrixBufferType); + matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + matrixBufferDesc.MiscFlags = 0; + matrixBufferDesc.StructureByteStride = 0; + + // Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class. + result = device->CreateBuffer(&matrixBufferDesc, NULL, &m_matrixBuffer); + if (FAILED(result)) + { + return false; + } + + // Create a texture sampler state description. + samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.MipLODBias = 0.0f; + samplerDesc.MaxAnisotropy = 1; + samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + samplerDesc.BorderColor[0] = 0; + samplerDesc.BorderColor[1] = 0; + samplerDesc.BorderColor[2] = 0; + samplerDesc.BorderColor[3] = 0; + samplerDesc.MinLOD = 0; + samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; + + // Create the texture sampler state. + result = device->CreateSamplerState(&samplerDesc, &m_sampleState); + if (FAILED(result)) + { + return false; + } + + // Setup the description of the dynamic pixel constant buffer that is in the pixel shader. + pixelBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + pixelBufferDesc.ByteWidth = sizeof(PixelBufferType); + pixelBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + pixelBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + pixelBufferDesc.MiscFlags = 0; + pixelBufferDesc.StructureByteStride = 0; + + // Create the pixel constant buffer pointer so we can access the pixel shader constant buffer from within this class. + result = device->CreateBuffer(&pixelBufferDesc, NULL, &m_pixelBuffer); + if (FAILED(result)) + { + return false; + } + + return true; +} + +void FontShaderClass::ShutdownShader() +{ + // Release the pixel constant buffer. + if (m_pixelBuffer) + { + m_pixelBuffer->Release(); + m_pixelBuffer = 0; + } + + // Release the sampler state. + if (m_sampleState) + { + m_sampleState->Release(); + m_sampleState = 0; + } + + // Release the matrix constant buffer. + if (m_matrixBuffer) + { + m_matrixBuffer->Release(); + m_matrixBuffer = 0; + } + + // Release the layout. + if (m_layout) + { + m_layout->Release(); + m_layout = 0; + } + + // Release the pixel shader. + if (m_pixelShader) + { + m_pixelShader->Release(); + m_pixelShader = 0; + } + + // Release the vertex shader. + if (m_vertexShader) + { + m_vertexShader->Release(); + m_vertexShader = 0; + } + + return; +} + +void FontShaderClass::OutputShaderErrorMessage(ID3D10Blob* errorMessage, HWND hwnd, WCHAR* shaderFilename) +{ + char* compileErrors; + unsigned long long bufferSize, i; + ofstream fout; + + + // Get a pointer to the error message text buffer. + compileErrors = (char*)(errorMessage->GetBufferPointer()); + + // Get the length of the message. + bufferSize = errorMessage->GetBufferSize(); + + // Open a file to write the error message to. + fout.open("shader-error.txt"); + + // Write out the error message. + for (i = 0; i < bufferSize; i++) + { + fout << compileErrors[i]; + } + + // Close the file. + fout.close(); + + // Release the error message. + errorMessage->Release(); + errorMessage = 0; + + // Pop a message up on the screen to notify the user to check the text file for compile errors. + MessageBox(hwnd, L"Error compiling shader. Check shader-error.txt for message.", shaderFilename, MB_OK); + + return; +} + +bool FontShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, + XMMATRIX projectionMatrix, ID3D11ShaderResourceView* texture, XMFLOAT4 pixelColor) +{ + HRESULT result; + D3D11_MAPPED_SUBRESOURCE mappedResource; + MatrixBufferType* dataPtr; + unsigned int bufferNumber; + PixelBufferType* dataPtr2; + + + // Transpose the matrices to prepare them for the shader. + worldMatrix = XMMatrixTranspose(worldMatrix); + viewMatrix = XMMatrixTranspose(viewMatrix); + projectionMatrix = XMMatrixTranspose(projectionMatrix); + + // Lock the constant buffer so it can be written to. + result = deviceContext->Map(m_matrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return false; + } + + // Get a pointer to the data in the constant buffer. + dataPtr = (MatrixBufferType*)mappedResource.pData; + + // Copy the matrices into the constant buffer. + dataPtr->world = worldMatrix; + dataPtr->view = viewMatrix; + dataPtr->projection = projectionMatrix; + + // Unlock the constant buffer. + deviceContext->Unmap(m_matrixBuffer, 0); + + // Set the position of the constant buffer in the vertex shader. + bufferNumber = 0; + + // Finally set the constant buffer in the vertex shader with the updated values. + deviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_matrixBuffer); + + // Set shader texture resource in the pixel shader. + deviceContext->PSSetShaderResources(0, 1, &texture); + + // Lock the pixel constant buffer so it can be written to. + result = deviceContext->Map(m_pixelBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return false; + } + + // Get a pointer to the data in the pixel constant buffer. + dataPtr2 = (PixelBufferType*)mappedResource.pData; + + // Copy the pixel color into the pixel constant buffer. + dataPtr2->pixelColor = pixelColor; + + // Unlock the pixel constant buffer. + deviceContext->Unmap(m_pixelBuffer, 0); + + // Set the position of the pixel constant buffer in the pixel shader. + bufferNumber = 0; + + // Now set the pixel constant buffer in the pixel shader with the updated value. + deviceContext->PSSetConstantBuffers(bufferNumber, 1, &m_pixelBuffer); + + return true; +} + +void FontShaderClass::RenderShader(ID3D11DeviceContext* deviceContext, int indexCount) +{ + // Set the vertex input layout. + deviceContext->IASetInputLayout(m_layout); + + // Set the vertex and pixel shaders that will be used to render this triangle. + deviceContext->VSSetShader(m_vertexShader, NULL, 0); + deviceContext->PSSetShader(m_pixelShader, NULL, 0); + + // Set the sampler state in the pixel shader. + deviceContext->PSSetSamplers(0, 1, &m_sampleState); + + // Render the triangle. + deviceContext->DrawIndexed(indexCount, 0, 0); + + return; +} \ No newline at end of file diff --git a/enginecustom/fontshaderclass.h b/enginecustom/fontshaderclass.h new file mode 100644 index 0000000..8a0221d --- /dev/null +++ b/enginecustom/fontshaderclass.h @@ -0,0 +1,60 @@ +#ifndef _FONTSHADERCLASS_H_ +#define _FONTSHADERCLASS_H_ + + +////////////// +// INCLUDES // +////////////// +#include +#include +#include +#include +using namespace DirectX; +using namespace std; + + +//////////////////////////////////////////////////////////////////////////////// +// Class name: FontShaderClass +//////////////////////////////////////////////////////////////////////////////// +class FontShaderClass +{ +private: + struct MatrixBufferType + { + XMMATRIX world; + XMMATRIX view; + XMMATRIX projection; + }; + + struct PixelBufferType + { + XMFLOAT4 pixelColor; + }; + +public: + FontShaderClass(); + FontShaderClass(const FontShaderClass&); + ~FontShaderClass(); + + bool Initialize(ID3D11Device*, HWND); + void Shutdown(); + bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4); + +private: + bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*); + void ShutdownShader(); + void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*); + + bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4); + void RenderShader(ID3D11DeviceContext*, int); + +private: + ID3D11VertexShader* m_vertexShader; + ID3D11PixelShader* m_pixelShader; + ID3D11InputLayout* m_layout; + ID3D11Buffer* m_matrixBuffer; + ID3D11SamplerState* m_sampleState; + ID3D11Buffer* m_pixelBuffer; +}; + +#endif \ No newline at end of file diff --git a/enginecustom/textclass.cpp b/enginecustom/textclass.cpp new file mode 100644 index 0000000..33df17a --- /dev/null +++ b/enginecustom/textclass.cpp @@ -0,0 +1,250 @@ +#include "textclass.h" + + +TextClass::TextClass() +{ + m_vertexBuffer = 0; + m_indexBuffer = 0; +} + + +TextClass::TextClass(const TextClass& other) +{ +} + + +TextClass::~TextClass() +{ +} + +bool TextClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceContext, int screenWidth, int screenHeight, int maxLength, FontClass* Font, char* text, + int positionX, int positionY, float red, float green, float blue) +{ + bool result; + + + // Store the screen width and height. + m_screenWidth = screenWidth; + m_screenHeight = screenHeight; + + // Store the maximum length of the sentence. + m_maxLength = maxLength; + + // Initalize the sentence. + result = InitializeBuffers(device, deviceContext, Font, text, positionX, positionY, red, green, blue); + if (!result) + { + return false; + } + + return true; +} + +void TextClass::Shutdown() +{ + // Release the vertex and index buffers. + ShutdownBuffers(); + + return; +} + +void TextClass::Render(ID3D11DeviceContext* deviceContext) +{ + // Put the vertex and index buffers on the graphics pipeline to prepare them for drawing. + RenderBuffers(deviceContext); + + return; +} + +int TextClass::GetIndexCount() +{ + return m_indexCount; +} + +bool TextClass::InitializeBuffers(ID3D11Device* device, ID3D11DeviceContext* deviceContext, FontClass* Font, char* text, int positionX, int positionY, float red, float green, float blue) +{ + VertexType* vertices; + unsigned long* indices; + D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc; + D3D11_SUBRESOURCE_DATA vertexData, indexData; + HRESULT result; + int i; + + // Set the vertex and index count. + m_vertexCount = 6 * m_maxLength; + m_indexCount = m_vertexCount; + + // Create the vertex array. + vertices = new VertexType[m_vertexCount]; + + // Create the index array. + indices = new unsigned long[m_indexCount]; + + // Initialize vertex array to zeros at first. + memset(vertices, 0, (sizeof(VertexType) * m_vertexCount)); + + // Initialize the index array. + for (i = 0; i < m_indexCount; i++) + { + indices[i] = i; + } + + // Set up the description of the dynamic vertex buffer. + vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + vertexBufferDesc.ByteWidth = sizeof(VertexType) * m_vertexCount; + vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + vertexBufferDesc.MiscFlags = 0; + vertexBufferDesc.StructureByteStride = 0; + + // Give the subresource structure a pointer to the vertex data. + vertexData.pSysMem = vertices; + vertexData.SysMemPitch = 0; + vertexData.SysMemSlicePitch = 0; + + // Create the vertex buffer. + result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &m_vertexBuffer); + if (FAILED(result)) + { + return false; + } + + // Set up the description of the static index buffer. + indexBufferDesc.Usage = D3D11_USAGE_DEFAULT; + indexBufferDesc.ByteWidth = sizeof(unsigned long) * m_indexCount; + indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + indexBufferDesc.CPUAccessFlags = 0; + indexBufferDesc.MiscFlags = 0; + indexBufferDesc.StructureByteStride = 0; + + // Give the subresource structure a pointer to the index data. + indexData.pSysMem = indices; + indexData.SysMemPitch = 0; + indexData.SysMemSlicePitch = 0; + + // Create the index buffer. + result = device->CreateBuffer(&indexBufferDesc, &indexData, &m_indexBuffer); + if (FAILED(result)) + { + return false; + } + + // Release the vertex array as it is no longer needed. + delete[] vertices; + vertices = 0; + + // Release the index array as it is no longer needed. + delete[] indices; + indices = 0; + + // Now add the text data to the sentence buffers. + result = UpdateText(deviceContext, Font, text, positionX, positionY, red, green, blue); + if (!result) + { + return false; + } + + return true; +} + +void TextClass::ShutdownBuffers() +{ + // Release the index buffer. + if (m_indexBuffer) + { + m_indexBuffer->Release(); + m_indexBuffer = 0; + } + + // Release the vertex buffer. + if (m_vertexBuffer) + { + m_vertexBuffer->Release(); + m_vertexBuffer = 0; + } + + return; +} + +bool TextClass::UpdateText(ID3D11DeviceContext* deviceContext, FontClass* Font, char* text, int positionX, int positionY, float red, float green, float blue) +{ + int numLetters; + VertexType* vertices; + float drawX, drawY; + HRESULT result; + D3D11_MAPPED_SUBRESOURCE mappedResource; + VertexType* verticesPtr; + + // Store the color of the sentence. + m_pixelColor = XMFLOAT4(red, green, blue, 1.0f); + + // Get the number of letters in the sentence. + numLetters = (int)strlen(text); + + // Check for possible buffer overflow. + if (numLetters > m_maxLength) + { + return false; + } + + // Create the vertex array. + vertices = new VertexType[m_vertexCount]; + + // Initialize vertex array to zeros at first. + memset(vertices, 0, (sizeof(VertexType) * m_vertexCount)); + + // Calculate the X and Y pixel position on the screen to start drawing to. + drawX = (float)(((m_screenWidth / 2) * -1) + positionX); + drawY = (float)((m_screenHeight / 2) - positionY); + + // Use the font class to build the vertex array from the sentence text and sentence draw location. + Font->BuildVertexArray((void*)vertices, text, drawX, drawY); + + // Lock the vertex buffer so it can be written to. + result = deviceContext->Map(m_vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return false; + } + + // Get a pointer to the data in the vertex buffer. + verticesPtr = (VertexType*)mappedResource.pData; + + // Copy the data into the vertex buffer. + memcpy(verticesPtr, (void*)vertices, (sizeof(VertexType) * m_vertexCount)); + + // Unlock the vertex buffer. + deviceContext->Unmap(m_vertexBuffer, 0); + + // Release the vertex array as it is no longer needed. + delete[] vertices; + vertices = 0; + + return true; +} + +void TextClass::RenderBuffers(ID3D11DeviceContext* deviceContext) +{ + unsigned int stride, offset; + + + // Set vertex buffer stride and offset. + stride = sizeof(VertexType); + offset = 0; + + // Set the vertex buffer to active in the input assembler so it can be rendered. + deviceContext->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset); + + // Set the index buffer to active in the input assembler so it can be rendered. + deviceContext->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0); + + // Set the type of primitive that should be rendered from this vertex buffer, in this case triangles. + deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + return; +} + +XMFLOAT4 TextClass::GetPixelColor() +{ + return m_pixelColor; +} diff --git a/enginecustom/textclass.h b/enginecustom/textclass.h new file mode 100644 index 0000000..643631a --- /dev/null +++ b/enginecustom/textclass.h @@ -0,0 +1,48 @@ +#ifndef _TEXTCLASS_H_ +#define _TEXTCLASS_H_ + + +/////////////////////// +// MY CLASS INCLUDES // +/////////////////////// +#include "fontclass.h" + + +//////////////////////////////////////////////////////////////////////////////// +// Class name: TextClass +//////////////////////////////////////////////////////////////////////////////// +class TextClass +{ +private: + struct VertexType + { + XMFLOAT3 position; + XMFLOAT2 texture; + }; + +public: + TextClass(); + TextClass(const TextClass&); + ~TextClass(); + + bool Initialize(ID3D11Device*, ID3D11DeviceContext*, int, int, int, FontClass*, char*, int, int, float, float, float); + void Shutdown(); + void Render(ID3D11DeviceContext*); + + int GetIndexCount(); + + bool UpdateText(ID3D11DeviceContext*, FontClass*, char*, int, int, float, float, float); + XMFLOAT4 GetPixelColor(); + +private: + bool InitializeBuffers(ID3D11Device*, ID3D11DeviceContext*, FontClass*, char*, int, int, float, float, float); + void ShutdownBuffers(); + void RenderBuffers(ID3D11DeviceContext*); + +private: + ID3D11Buffer* m_vertexBuffer, * m_indexBuffer; + int m_screenWidth, m_screenHeight, m_maxLength, m_vertexCount, m_indexCount; + XMFLOAT4 m_pixelColor; +}; + +#endif \ No newline at end of file