diff --git a/enginecustom/applicationclass.cpp b/enginecustom/applicationclass.cpp index a28c4a7..41f09b8 100644 --- a/enginecustom/applicationclass.cpp +++ b/enginecustom/applicationclass.cpp @@ -1,15 +1,11 @@ -//////////////////////////////////////////////////////////////////////////////// -// Filename: applicationclass.cpp -//////////////////////////////////////////////////////////////////////////////// #include "applicationclass.h" - ApplicationClass::ApplicationClass() { m_Direct3D = 0; m_Camera = 0; m_Model = 0; - m_ColorShader = 0; + m_TextureShader = 0; } @@ -25,42 +21,53 @@ ApplicationClass::~ApplicationClass() bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) { + char textureFilename[128]; bool result; - // Create and initialize the Direct3D object. + // Create the Direct3D object. m_Direct3D = new D3DClass; + if (!m_Direct3D) + { + return false; + } + // Initialize the Direct3D object. result = m_Direct3D->Initialize(screenWidth, screenHeight, VSYNC_ENABLED, hwnd, FULL_SCREEN, SCREEN_DEPTH, SCREEN_NEAR); if (!result) { - MessageBox(hwnd, L"Could not initialize Direct3D", L"Error", MB_OK); + MessageBox(hwnd, L"Could not initialize Direct3D.", L"Error", MB_OK); return false; } // Create the camera object. m_Camera = new CameraClass; + if (!m_Camera) + { + return false; + } // Set the initial position of the camera. m_Camera->SetPosition(0.0f, 0.0f, -5.0f); // Create and initialize the model object. m_Model = new ModelClass; + // Set the name of the texture file that we will be loading. + strcpy_s(textureFilename, "stone01.tga"); - result = m_Model->Initialize(m_Direct3D->GetDevice()); + result = m_Model->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), textureFilename); if (!result) { MessageBox(hwnd, L"Could not initialize the model object.", L"Error", MB_OK); return false; } + // Create and initialize the texture shader object. + m_TextureShader = new TextureShaderClass; - // Create and initialize the color shader object. - m_ColorShader = new ColorShaderClass; - - result = m_ColorShader->Initialize(m_Direct3D->GetDevice(), hwnd); + result = m_TextureShader->Initialize(m_Direct3D->GetDevice(), hwnd); if (!result) { - MessageBox(hwnd, L"Could not initialize the color shader object.", L"Error", MB_OK); + MessageBox(hwnd, L"Could not initialize the texture shader object.", L"Error", MB_OK); return false; } @@ -70,12 +77,12 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) void ApplicationClass::Shutdown() { - // Release the color shader object. - if (m_ColorShader) + // Release the texture shader object. + if (m_TextureShader) { - m_ColorShader->Shutdown(); - delete m_ColorShader; - m_ColorShader = 0; + m_TextureShader->Shutdown(); + delete m_TextureShader; + m_TextureShader = 0; } // Release the model object. @@ -93,7 +100,7 @@ void ApplicationClass::Shutdown() m_Camera = 0; } - // Release the Direct3D object. + // Release the D3D object. if (m_Direct3D) { m_Direct3D->Shutdown(); @@ -140,9 +147,8 @@ bool ApplicationClass::Render() // Put the model vertex and index buffers on the graphics pipeline to prepare them for drawing. m_Model->Render(m_Direct3D->GetDeviceContext()); - - // Render the model using the color shader. - result = m_ColorShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix); + // Render the model using the texture shader. + result = m_TextureShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture()); if (!result) { return false; diff --git a/enginecustom/applicationclass.h b/enginecustom/applicationclass.h index 8a74383..b0bf8f3 100644 --- a/enginecustom/applicationclass.h +++ b/enginecustom/applicationclass.h @@ -2,13 +2,14 @@ #define _APPLICATIONCLASS_H_ -////////////// -// INCLUDES // -////////////// +/////////////////////// +// MY CLASS INCLUDES // +/////////////////////// +#include "d3dclass.h" #include "cameraclass.h" #include "modelclass.h" -#include "colorshaderclass.h" -#include "d3dclass.h" + +#include "textureshaderclass.h" ///////////// @@ -19,6 +20,10 @@ const bool VSYNC_ENABLED = true; const float SCREEN_DEPTH = 1000.0f; const float SCREEN_NEAR = 0.3f; + +//////////////////////////////////////////////////////////////////////////////// +// Class name: ApplicationClass +//////////////////////////////////////////////////////////////////////////////// class ApplicationClass { public: @@ -37,7 +42,7 @@ private: D3DClass* m_Direct3D; CameraClass* m_Camera; ModelClass* m_Model; - ColorShaderClass* m_ColorShader; + TextureShaderClass* m_TextureShader; }; -#endif \ No newline at end of file +#endif diff --git a/enginecustom/enginecustom.vcxproj b/enginecustom/enginecustom.vcxproj index 3c74b8c..ba1ba40 100644 --- a/enginecustom/enginecustom.vcxproj +++ b/enginecustom/enginecustom.vcxproj @@ -28,6 +28,8 @@ + + @@ -37,9 +39,13 @@ + + + + @@ -59,6 +65,9 @@ Document + + + 17.0 Win32Proj diff --git a/enginecustom/enginecustom.vcxproj.filters b/enginecustom/enginecustom.vcxproj.filters index c3fe977..cc96857 100644 --- a/enginecustom/enginecustom.vcxproj.filters +++ b/enginecustom/enginecustom.vcxproj.filters @@ -16,6 +16,12 @@ {b016e481-576e-4d99-bdde-34cc10c55b1d} + + {f76f9761-bbbe-42a8-935d-01f1b9172c38} + + + {741e1efe-db9b-48a7-9ecb-4c34a696f40e} + @@ -42,6 +48,12 @@ Fichiers sources + + Fichiers sources + + + Fichiers sources + @@ -65,6 +77,12 @@ Fichiers d%27en-tête + + Fichiers d%27en-tête + + + Fichiers d%27en-tête + @@ -74,5 +92,16 @@ shader + + texture + + + texture + + + + + assets + \ No newline at end of file diff --git a/enginecustom/modelclass.cpp b/enginecustom/modelclass.cpp index 0eedb98..4187f71 100644 --- a/enginecustom/modelclass.cpp +++ b/enginecustom/modelclass.cpp @@ -1,6 +1,3 @@ -//////////////////////////////////////////////////////////////////////////////// -// Filename: modelclass.cpp -//////////////////////////////////////////////////////////////////////////////// #include "modelclass.h" @@ -8,6 +5,7 @@ ModelClass::ModelClass() { m_vertexBuffer = 0; m_indexBuffer = 0; + m_Texture = 0; } @@ -20,8 +18,7 @@ ModelClass::~ModelClass() { } - -bool ModelClass::Initialize(ID3D11Device* device) +bool ModelClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceContext, char* textureFilename) { bool result; @@ -32,6 +29,12 @@ bool ModelClass::Initialize(ID3D11Device* device) { return false; } + // Load the texture for this model. + result = LoadTexture(device, deviceContext, textureFilename); + if (!result) + { + return false; + } return true; } @@ -39,6 +42,9 @@ bool ModelClass::Initialize(ID3D11Device* device) void ModelClass::Shutdown() { + // Release the model texture. + ReleaseTexture(); + // Shutdown the vertex and index buffers. ShutdownBuffers(); @@ -60,6 +66,11 @@ int ModelClass::GetIndexCount() return m_indexCount; } +ID3D11ShaderResourceView* ModelClass::GetTexture() +{ + return m_Texture->GetTexture(); +} + bool ModelClass::InitializeBuffers(ID3D11Device* device) { @@ -71,39 +82,42 @@ bool ModelClass::InitializeBuffers(ID3D11Device* device) // Set the number of vertices in the vertex array. - m_vertexCount = 3; + m_vertexCount = 6; // Set the number of indices in the index array. - m_indexCount = 3; + m_indexCount = 6; // Create the vertex array. vertices = new VertexType[m_vertexCount]; - if (!vertices) - { - return false; - } // Create the index array. indices = new unsigned long[m_indexCount]; - if (!indices) - { - return false; - } - // Load the vertex array with data. vertices[0].position = XMFLOAT3(-1.0f, -1.0f, 0.0f); // Bottom left. - vertices[0].color = XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f); + vertices[0].texture = XMFLOAT2(0.0f, 1.0f); - vertices[1].position = XMFLOAT3(0.0f, 1.0f, 0.0f); // Top middle. - vertices[1].color = XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f); + vertices[1].position = XMFLOAT3(1.0f, 1.0f, 0.0f); // Top Right. + vertices[1].texture = XMFLOAT2(0.5f, 0.0f); vertices[2].position = XMFLOAT3(1.0f, -1.0f, 0.0f); // Bottom right. - vertices[2].color = XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f); + vertices[2].texture = XMFLOAT2(1.0f, 1.0f); + + vertices[3].position = XMFLOAT3(-1.0f, 1.0f, 0.0f); // Top left. + vertices[3].texture = XMFLOAT2(0.0f, 1.0f); + + vertices[4].position = XMFLOAT3(1.0f, 1.0f, 0.0f); // Top right. + vertices[4].texture = XMFLOAT2(0.5f, 0.0f); + + vertices[5].position = XMFLOAT3(-1.0f, -1.0f, 0.0f); // Bottom left. + vertices[5].texture = XMFLOAT2(1.0f, 1.0f); // Load the index array with data. indices[0] = 0; // Bottom left. indices[1] = 1; // Top middle. indices[2] = 2; // Bottom right. + indices[3] = 3; // Top left. + indices[4] = 4; // Top right. + indices[5] = 5; // Bottom left. // Set up the description of the static vertex buffer. vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT; @@ -195,5 +209,35 @@ void ModelClass::RenderBuffers(ID3D11DeviceContext* deviceContext) // Set the type of primitive that should be rendered from this vertex buffer, in this case triangles. deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + return; +} + +bool ModelClass::LoadTexture(ID3D11Device* device, ID3D11DeviceContext* deviceContext, char* filename) +{ + bool result; + + + // Create and initialize the texture object. + m_Texture = new TextureClass; + + result = m_Texture->Initialize(device, deviceContext, filename); + if (!result) + { + return false; + } + + return true; +} + +void ModelClass::ReleaseTexture() +{ + // Release the texture object. + if (m_Texture) + { + m_Texture->Shutdown(); + delete m_Texture; + m_Texture = 0; + } + return; } \ No newline at end of file diff --git a/enginecustom/modelclass.h b/enginecustom/modelclass.h index f84628b..aee6989 100644 --- a/enginecustom/modelclass.h +++ b/enginecustom/modelclass.h @@ -1,6 +1,3 @@ -//////////////////////////////////////////////////////////////////////////////// -// Filename: modelclass.h -//////////////////////////////////////////////////////////////////////////////// #ifndef _MODELCLASS_H_ #define _MODELCLASS_H_ @@ -12,6 +9,11 @@ #include using namespace DirectX; +/////////////////////// +// MY CLASS INCLUDES // +/////////////////////// +#include "textureclass.h" + //////////////////////////////////////////////////////////////////////////////// // Class name: ModelClass @@ -19,10 +21,11 @@ using namespace DirectX; class ModelClass { private: + struct VertexType { XMFLOAT3 position; - XMFLOAT4 color; + XMFLOAT2 texture; }; public: @@ -30,20 +33,25 @@ public: ModelClass(const ModelClass&); ~ModelClass(); - bool Initialize(ID3D11Device*); + bool Initialize(ID3D11Device*, ID3D11DeviceContext*, char*); void Shutdown(); void Render(ID3D11DeviceContext*); int GetIndexCount(); + ID3D11ShaderResourceView* GetTexture(); + private: bool InitializeBuffers(ID3D11Device*); void ShutdownBuffers(); void RenderBuffers(ID3D11DeviceContext*); + bool LoadTexture(ID3D11Device*, ID3D11DeviceContext*, char*); + void ReleaseTexture(); private: ID3D11Buffer* m_vertexBuffer, * m_indexBuffer; int m_vertexCount, m_indexCount; + TextureClass* m_Texture; }; #endif \ No newline at end of file diff --git a/enginecustom/stone01.tga b/enginecustom/stone01.tga new file mode 100644 index 0000000..e1c9cab Binary files /dev/null and b/enginecustom/stone01.tga differ diff --git a/enginecustom/texture.ps b/enginecustom/texture.ps new file mode 100644 index 0000000..192f1fc --- /dev/null +++ b/enginecustom/texture.ps @@ -0,0 +1,28 @@ +///////////// +// GLOBALS // +///////////// +Texture2D shaderTexture : register(t0); +SamplerState SampleType : register(s0); + +////////////// +// TYPEDEFS // +////////////// +struct PixelInputType +{ + float4 position : SV_POSITION; + float2 tex : TEXCOORD0; +}; + +//////////////////////////////////////////////////////////////////////////////// +// Pixel Shader +//////////////////////////////////////////////////////////////////////////////// +float4 TexturePixelShader(PixelInputType input) : SV_TARGET +{ + float4 textureColor; + + + // Sample the pixel color from the texture using the sampler at this texture coordinate location. + textureColor = shaderTexture.Sample(SampleType, input.tex); + + return textureColor; +} \ No newline at end of file diff --git a/enginecustom/texture.vs b/enginecustom/texture.vs new file mode 100644 index 0000000..41f1ab9 --- /dev/null +++ b/enginecustom/texture.vs @@ -0,0 +1,47 @@ +///////////// +// 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 TextureVertexShader(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/textureclass.cpp b/enginecustom/textureclass.cpp new file mode 100644 index 0000000..542e6dc --- /dev/null +++ b/enginecustom/textureclass.cpp @@ -0,0 +1,211 @@ +#include "textureclass.h" + +TextureClass::TextureClass() +{ + m_targaData = 0; + m_texture = 0; + m_textureView = 0; +} + + +TextureClass::TextureClass(const TextureClass& other) +{ +} + + +TextureClass::~TextureClass() +{ +} + +bool TextureClass::Initialize(ID3D11Device * device, ID3D11DeviceContext * deviceContext, char* filename) +{ + bool result; + int height, width; + D3D11_TEXTURE2D_DESC textureDesc; + HRESULT hResult; + unsigned int rowPitch; + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + // Load the targa image data into memory. + result = LoadTarga32Bit(filename); + if (!result) + { + return false; + } + // Setup the description of the texture. + textureDesc.Height = m_height; + textureDesc.Width = m_width; + textureDesc.MipLevels = 0; + textureDesc.ArraySize = 1; + textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Usage = D3D11_USAGE_DEFAULT; + textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + textureDesc.CPUAccessFlags = 0; + textureDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; + + // Create the empty texture. + hResult = device->CreateTexture2D(&textureDesc, NULL, &m_texture); + if (FAILED(hResult)) + { + return false; + } + + // Set the row pitch of the targa image data. + rowPitch = (m_width * 4) * sizeof(unsigned char); + // Copy the targa image data into the texture. + deviceContext->UpdateSubresource(m_texture, 0, NULL, m_targaData, rowPitch, 0); + // Setup the shader resource view description. + srvDesc.Format = textureDesc.Format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MostDetailedMip = 0; + srvDesc.Texture2D.MipLevels = -1; + + // Create the shader resource view for the texture. + hResult = device->CreateShaderResourceView(m_texture, &srvDesc, &m_textureView); + if (FAILED(hResult)) + { + return false; + } + + // Generate mipmaps for this texture. + deviceContext->GenerateMips(m_textureView); + + // Release the targa image data now that the image data has been loaded into the texture. + delete[] m_targaData; + m_targaData = 0; + + return true; +} + +void TextureClass::Shutdown() +{ + // Release the texture view resource. + if (m_textureView) + { + m_textureView->Release(); + m_textureView = 0; + } + + // Release the texture. + if (m_texture) + { + m_texture->Release(); + m_texture = 0; + } + + // Release the targa data. + if (m_targaData) + { + delete[] m_targaData; + m_targaData = 0; + } + + return; +} + +ID3D11ShaderResourceView* TextureClass::GetTexture() +{ + return m_textureView; +} + +bool TextureClass::LoadTarga32Bit(char* filename) +{ + int error, bpp, imageSize, index, i, j, k; + FILE* filePtr; + unsigned int count; + TargaHeader targaFileHeader; + unsigned char* targaImage; + + + // Open the targa file for reading in binary. + error = fopen_s(&filePtr, filename, "rb"); + if (error != 0) + { + return false; + } + + // Read in the file header. + count = (unsigned int)fread(&targaFileHeader, sizeof(TargaHeader), 1, filePtr); + if (count != 1) + { + return false; + } + + // Get the important information from the header. + m_height = (int)targaFileHeader.height; + m_width = (int)targaFileHeader.width; + bpp = (int)targaFileHeader.bpp; + + // Check that it is 32 bit and not 24 bit. + if (bpp != 32) + { + return false; + } + + // Calculate the size of the 32 bit image data. + imageSize = m_width * m_height * 4; + + // Allocate memory for the targa image data. + targaImage = new unsigned char[imageSize]; + + // Read in the targa image data. + count = (unsigned int)fread(targaImage, 1, imageSize, filePtr); + if (count != imageSize) + { + return false; + } + + // Close the file. + error = fclose(filePtr); + if (error != 0) + { + return false; + } + + // Allocate memory for the targa destination data. + m_targaData = new unsigned char[imageSize]; + + // Initialize the index into the targa destination data array. + index = 0; + + // Initialize the index into the targa image data. + k = (m_width * m_height * 4) - (m_width * 4); + + // Now copy the targa image data into the targa destination array in the correct order since the targa format is stored upside down and also is not in RGBA order. + for (j = 0; j < m_height; j++) + { + for (i = 0; i < m_width; i++) + { + m_targaData[index + 0] = targaImage[k + 2]; // Red. + m_targaData[index + 1] = targaImage[k + 1]; // Green. + m_targaData[index + 2] = targaImage[k + 0]; // Blue + m_targaData[index + 3] = targaImage[k + 3]; // Alpha + + // Increment the indexes into the targa data. + k += 4; + index += 4; + } + + // Set the targa image data index back to the preceding row at the beginning of the column since its reading it in upside down. + k -= (m_width * 8); + } + + // Release the targa image data now that it was copied into the destination array. + delete[] targaImage; + targaImage = 0; + + return true; +} + + +int TextureClass::GetWidth() +{ + return m_width; +} + + +int TextureClass::GetHeight() +{ + return m_height; +} diff --git a/enginecustom/textureclass.h b/enginecustom/textureclass.h new file mode 100644 index 0000000..d9c66e9 --- /dev/null +++ b/enginecustom/textureclass.h @@ -0,0 +1,50 @@ +#ifndef _TEXTURECLASS_H_ +#define _TEXTURECLASS_H_ + + +////////////// +// INCLUDES // +////////////// +#include +#include + + +//////////////////////////////////////////////////////////////////////////////// +// Class name: TextureClass +//////////////////////////////////////////////////////////////////////////////// +class TextureClass +{ +private: + struct TargaHeader + { + unsigned char data1[12]; + unsigned short width; + unsigned short height; + unsigned char bpp; + unsigned char data2; + }; + +public: + TextureClass(); + TextureClass(const TextureClass&); + ~TextureClass(); + + bool Initialize(ID3D11Device*, ID3D11DeviceContext*, char*); + void Shutdown(); + + ID3D11ShaderResourceView* GetTexture(); + + int GetWidth(); + int GetHeight(); + +private: + bool LoadTarga32Bit(char*); + +private: + unsigned char* m_targaData; + ID3D11Texture2D* m_texture; + ID3D11ShaderResourceView* m_textureView; + int m_width, m_height; +}; + +#endif diff --git a/enginecustom/textureshaderclass.cpp b/enginecustom/textureshaderclass.cpp new file mode 100644 index 0000000..b28fed9 --- /dev/null +++ b/enginecustom/textureshaderclass.cpp @@ -0,0 +1,357 @@ +#include "textureshaderclass.h" + + +TextureShaderClass::TextureShaderClass() +{ + m_vertexShader = 0; + m_pixelShader = 0; + m_layout = 0; + m_matrixBuffer = 0; + m_sampleState = 0; +} + + +TextureShaderClass::TextureShaderClass(const TextureShaderClass& other) +{ +} + + +TextureShaderClass::~TextureShaderClass() +{ +} + + +bool TextureShaderClass::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"texture.vs"); + if (error != 0) + { + return false; + } + + // Set the filename of the pixel shader. + error = wcscpy_s(psFilename, 128, L"texture.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 TextureShaderClass::Shutdown() +{ + // Shutdown the vertex and pixel shaders as well as the related objects. + ShutdownShader(); + + return; +} + +bool TextureShaderClass::Render(ID3D11DeviceContext * deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, + XMMATRIX projectionMatrix, ID3D11ShaderResourceView * texture) +{ + bool result; + + + // Set the shader parameters that it will use for rendering. + result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture); + if (!result) + { + return false; + } + + // Now render the prepared buffers with the shader. + RenderShader(deviceContext, indexCount); + + return true; +} + +bool TextureShaderClass::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; + + + // 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, "TextureVertexShader", "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, "TexturePixelShader", "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. + // This setup needs to match the VertexType stucture in the ModelClass and in the shader. + 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; + } + + return true; +} + +void TextureShaderClass::ShutdownShader() +{ + + // 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 TextureShaderClass::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 TextureShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, + XMMATRIX projectionMatrix, ID3D11ShaderResourceView* texture) +{ + HRESULT result; + D3D11_MAPPED_SUBRESOURCE mappedResource; + MatrixBufferType* dataPtr; + unsigned int bufferNumber; + + + // 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; + + // Finanly 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); + + return true; +} + +void TextureShaderClass::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/textureshaderclass.h b/enginecustom/textureshaderclass.h new file mode 100644 index 0000000..6c88f59 --- /dev/null +++ b/enginecustom/textureshaderclass.h @@ -0,0 +1,54 @@ +#ifndef _TEXTURESHADERCLASS_H_ +#define _TEXTURESHADERCLASS_H_ + + +////////////// +// INCLUDES // +////////////// +#include +#include +#include +#include +using namespace DirectX; +using namespace std; + + +//////////////////////////////////////////////////////////////////////////////// +// Class name: TextureShaderClass +//////////////////////////////////////////////////////////////////////////////// +class TextureShaderClass +{ +private: + struct MatrixBufferType + { + XMMATRIX world; + XMMATRIX view; + XMMATRIX projection; + }; + +public: + TextureShaderClass(); + TextureShaderClass(const TextureShaderClass&); + ~TextureShaderClass(); + + bool Initialize(ID3D11Device*, HWND); + void Shutdown(); + bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*); + +private: + bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*); + void ShutdownShader(); + void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*); + + bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*); + void RenderShader(ID3D11DeviceContext*, int); + +private: + ID3D11VertexShader* m_vertexShader; + ID3D11PixelShader* m_pixelShader; + ID3D11InputLayout* m_layout; + ID3D11Buffer* m_matrixBuffer; + ID3D11SamplerState* m_sampleState; +}; + +#endif \ No newline at end of file