diff --git a/enginecustom/Light.ps b/enginecustom/Light.ps new file mode 100644 index 0000000..66babd6 --- /dev/null +++ b/enginecustom/Light.ps @@ -0,0 +1,57 @@ +//////////////////////////////////////////////////////////////////////////////// +// Filename: light.ps +//////////////////////////////////////////////////////////////////////////////// + + +///////////// +// GLOBALS // +///////////// +Texture2D shaderTexture : register(t0); +SamplerState SampleType : register(s0); +cbuffer LightBuffer +{ + float4 diffuseColor; + float3 lightDirection; + float padding; +}; + + +////////////// +// TYPEDEFS // +////////////// +struct PixelInputType +{ + float4 position : SV_POSITION; + float2 tex : TEXCOORD0; + float3 normal : NORMAL; +}; + + +//////////////////////////////////////////////////////////////////////////////// +// Pixel Shader +//////////////////////////////////////////////////////////////////////////////// +float4 LightPixelShader(PixelInputType input) : SV_TARGET +{ + float4 textureColor; + float3 lightDir; + float lightIntensity; + float4 color; + + + // Sample the pixel color from the texture using the sampler at this texture coordinate location. + textureColor = shaderTexture.Sample(SampleType, input.tex); + + // Invert the light direction for calculations. + lightDir = -lightDirection; + + // Calculate the amount of light on this pixel. + lightIntensity = saturate(dot(input.normal, lightDir)); + + // Determine the final amount of diffuse color based on the diffuse color combined with the light intensity. + color = saturate(diffuseColor * lightIntensity); + + // Multiply the texture pixel and the final diffuse color to get the final pixel color result. + color = color * textureColor; + + return color; +} \ No newline at end of file diff --git a/enginecustom/Light.vs b/enginecustom/Light.vs new file mode 100644 index 0000000..87f1edd --- /dev/null +++ b/enginecustom/Light.vs @@ -0,0 +1,60 @@ +//////////////////////////////////////////////////////////////////////////////// +// Filename: light.vs +//////////////////////////////////////////////////////////////////////////////// + + +///////////// +// GLOBALS // +///////////// +cbuffer MatrixBuffer +{ + matrix worldMatrix; + matrix viewMatrix; + matrix projectionMatrix; +}; + +////////////// +// TYPEDEFS // +////////////// +struct VertexInputType +{ + float4 position : POSITION; + float2 tex : TEXCOORD0; + float3 normal : NORMAL; +}; + +struct PixelInputType +{ + float4 position : SV_POSITION; + float2 tex : TEXCOORD0; + float3 normal : NORMAL; +}; + + +//////////////////////////////////////////////////////////////////////////////// +// Vertex Shader +//////////////////////////////////////////////////////////////////////////////// +PixelInputType LightVertexShader(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; + + // Calculate the normal vector against the world matrix only. + output.normal = mul(input.normal, (float3x3)worldMatrix); + + // Normalize the normal vector. + output.normal = normalize(output.normal); + + return output; +} \ No newline at end of file diff --git a/enginecustom/Lightclass.cpp b/enginecustom/Lightclass.cpp new file mode 100644 index 0000000..e6f0f9b --- /dev/null +++ b/enginecustom/Lightclass.cpp @@ -0,0 +1,45 @@ +//////////////////////////////////////////////////////////////////////////////// +// Filename: lightclass.cpp +//////////////////////////////////////////////////////////////////////////////// +#include "lightclass.h" + + +LightClass::LightClass() +{ +} + + +LightClass::LightClass(const LightClass& other) +{ +} + + +LightClass::~LightClass() +{ +} + + +void LightClass::SetDiffuseColor(float red, float green, float blue, float alpha) +{ + m_diffuseColor = XMFLOAT4(red, green, blue, alpha); + return; +} + + +void LightClass::SetDirection(float x, float y, float z) +{ + m_direction = XMFLOAT3(x, y, z); + return; +} + + +XMFLOAT4 LightClass::GetDiffuseColor() +{ + return m_diffuseColor; +} + + +XMFLOAT3 LightClass::GetDirection() +{ + return m_direction; +} \ No newline at end of file diff --git a/enginecustom/Lightclass.h b/enginecustom/Lightclass.h new file mode 100644 index 0000000..0159c95 --- /dev/null +++ b/enginecustom/Lightclass.h @@ -0,0 +1,37 @@ +#pragma once +//////////////////////////////////////////////////////////////////////////////// +// Filename: lightclass.h +//////////////////////////////////////////////////////////////////////////////// +#ifndef _LIGHTCLASS_H_ +#define _LIGHTCLASS_H_ + + +////////////// +// INCLUDES // +////////////// +#include +using namespace DirectX; + + +//////////////////////////////////////////////////////////////////////////////// +// Class name: LightClass +//////////////////////////////////////////////////////////////////////////////// +class LightClass +{ +public: + LightClass(); + LightClass(const LightClass&); + ~LightClass(); + + void SetDirection(float, float, float); + void SetDiffuseColor(float, float, float, float); + + XMFLOAT3 GetDirection(); + XMFLOAT4 GetDiffuseColor(); + +private: + XMFLOAT4 m_diffuseColor; + XMFLOAT3 m_direction; +}; + +#endif \ No newline at end of file diff --git a/enginecustom/Lightshaderclass.cpp b/enginecustom/Lightshaderclass.cpp new file mode 100644 index 0000000..c759fd3 --- /dev/null +++ b/enginecustom/Lightshaderclass.cpp @@ -0,0 +1,428 @@ +//////////////////////////////////////////////////////////////////////////////// +// Filename: lightshaderclass.cpp +//////////////////////////////////////////////////////////////////////////////// +#include "lightshaderclass.h" + + +LightShaderClass::LightShaderClass() +{ + m_vertexShader = 0; + m_pixelShader = 0; + m_layout = 0; + m_sampleState = 0; + m_matrixBuffer = 0; + m_lightBuffer = 0; +} + + +LightShaderClass::LightShaderClass(const LightShaderClass& other) +{ +} + + +LightShaderClass::~LightShaderClass() +{ +} + + +bool LightShaderClass::Initialize(ID3D11Device* device, HWND hwnd) +{ + wchar_t vsFilename[128]; + wchar_t psFilename[128]; + int error; + bool result; + + // Set the filename of the vertex shader. + error = wcscpy_s(vsFilename, 128, L"./Light.vs"); + if (error != 0) + { + return false; + } + + // Set the filename of the pixel shader. + error = wcscpy_s(psFilename, 128, L"./Light.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 LightShaderClass::Shutdown() +{ + // Shutdown the vertex and pixel shaders as well as the related objects. + ShutdownShader(); + + return; +} + +bool LightShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix, + ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 diffuseColor) +{ + bool result; + + + // Set the shader parameters that it will use for rendering. + result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, lightDirection, diffuseColor); + if (!result) + { + return false; + } + + // Now render the prepared buffers with the shader. + RenderShader(deviceContext, indexCount); + + return true; +} + + +bool LightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR* vsFilename, WCHAR* psFilename) +{ + HRESULT result; + ID3D10Blob* errorMessage; + ID3D10Blob* vertexShaderBuffer; + ID3D10Blob* pixelShaderBuffer; + + D3D11_INPUT_ELEMENT_DESC polygonLayout[3]; + unsigned int numElements; + D3D11_SAMPLER_DESC samplerDesc; + D3D11_BUFFER_DESC matrixBufferDesc; + + D3D11_BUFFER_DESC lightBufferDesc; + + + // 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, "LightVertexShader", "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, "LightPixelShader", "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; + + polygonLayout[2].SemanticName = "NORMAL"; + polygonLayout[2].SemanticIndex = 0; + polygonLayout[2].Format = DXGI_FORMAT_R32G32B32_FLOAT; + polygonLayout[2].InputSlot = 0; + polygonLayout[2].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; + polygonLayout[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + polygonLayout[2].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; + + // 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 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; + } + + // Setup the description of the light dynamic constant buffer that is in the pixel shader. + // Note that ByteWidth always needs to be a multiple of 16 if using D3D11_BIND_CONSTANT_BUFFER or CreateBuffer will fail. + lightBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + lightBufferDesc.ByteWidth = sizeof(LightBufferType); + lightBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + lightBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + lightBufferDesc.MiscFlags = 0; + lightBufferDesc.StructureByteStride = 0; + + // Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class. + result = device->CreateBuffer(&lightBufferDesc, NULL, &m_lightBuffer); + if (FAILED(result)) + { + return false; + } + + return true; +} + + +void LightShaderClass::ShutdownShader() +{ + // Release the light constant buffer. + if (m_lightBuffer) + { + m_lightBuffer->Release(); + m_lightBuffer = 0; + } + + // Release the matrix constant buffer. + if (m_matrixBuffer) + { + m_matrixBuffer->Release(); + m_matrixBuffer = 0; + } + + // Release the sampler state. + if (m_sampleState) + { + m_sampleState->Release(); + m_sampleState = 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 LightShaderClass::OutputShaderErrorMessage(ID3D10Blob* errorMessage, HWND hwnd, WCHAR* shaderFilename) +{ + char* compileErrors; + unsigned __int64 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 LightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix, + ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 diffuseColor) +{ + HRESULT result; + D3D11_MAPPED_SUBRESOURCE mappedResource; + unsigned int bufferNumber; + MatrixBufferType* dataPtr; + LightBufferType* 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; + + // Now 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 light constant buffer so it can be written to. + result = deviceContext->Map(m_lightBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return false; + } + + // Get a pointer to the data in the constant buffer. + dataPtr2 = (LightBufferType*)mappedResource.pData; + + // Copy the lighting variables into the constant buffer. + dataPtr2->diffuseColor = diffuseColor; + dataPtr2->lightDirection = lightDirection; + dataPtr2->padding = 0.0f; + + // Unlock the constant buffer. + deviceContext->Unmap(m_lightBuffer, 0); + + // Set the position of the light constant buffer in the pixel shader. + bufferNumber = 0; + + // Finally set the light constant buffer in the pixel shader with the updated values. + deviceContext->PSSetConstantBuffers(bufferNumber, 1, &m_lightBuffer); + + return true; +} + + +void LightShaderClass::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; +} diff --git a/enginecustom/Lightshaderclass.h b/enginecustom/Lightshaderclass.h new file mode 100644 index 0000000..247d3b8 --- /dev/null +++ b/enginecustom/Lightshaderclass.h @@ -0,0 +1,65 @@ +//////////////////////////////////////////////////////////////////////////////// +// Filename: lightshaderclass.h +//////////////////////////////////////////////////////////////////////////////// +#ifndef _LIGHTSHADERCLASS_H_ +#define _LIGHTSHADERCLASS_H_ + + +////////////// +// INCLUDES // +////////////// +#include +#include +#include +#include +using namespace DirectX; +using namespace std; + + +//////////////////////////////////////////////////////////////////////////////// +// Class name: LightShaderClass +//////////////////////////////////////////////////////////////////////////////// +class LightShaderClass +{ +private: + struct MatrixBufferType + { + XMMATRIX world; + XMMATRIX view; + XMMATRIX projection; + }; + + struct LightBufferType + { + XMFLOAT4 diffuseColor; + XMFLOAT3 lightDirection; + float padding; // Added extra padding so structure is a multiple of 16 for CreateBuffer function requirements. + }; + +public: + LightShaderClass(); + LightShaderClass(const LightShaderClass&); + ~LightShaderClass(); + + bool Initialize(ID3D11Device*, HWND); + void Shutdown(); + bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4); + +private: + bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*); + void ShutdownShader(); + void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*); + + bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4); + void RenderShader(ID3D11DeviceContext*, int); + +private: + ID3D11VertexShader* m_vertexShader; + ID3D11PixelShader* m_pixelShader; + ID3D11InputLayout* m_layout; + ID3D11SamplerState* m_sampleState; + ID3D11Buffer* m_matrixBuffer; + ID3D11Buffer* m_lightBuffer; +}; + +#endif \ No newline at end of file diff --git a/enginecustom/Spriteclass.cpp b/enginecustom/Spriteclass.cpp new file mode 100644 index 0000000..14e17bf --- /dev/null +++ b/enginecustom/Spriteclass.cpp @@ -0,0 +1,421 @@ +#include "spriteclass.h" + + +SpriteClass::SpriteClass() +{ + m_vertexBuffer = 0; + m_indexBuffer = 0; + m_Textures = 0; +} + + +SpriteClass::SpriteClass(const SpriteClass& other) +{ +} + + +SpriteClass::~SpriteClass() +{ +} + +bool SpriteClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceContext, int screenWidth, int screenHeight, char* spriteFilename, int renderX, int renderY) +{ + bool result; + + + // Store the screen size. + m_screenWidth = screenWidth; + m_screenHeight = screenHeight; + + // Store where the sprite should be rendered to. + m_renderX = renderX; + m_renderY = renderY; + + // Initialize the frame time for this sprite object. + m_frameTime = 0; + + // Initialize the vertex and index buffer that hold the geometry for the sprite bitmap. + result = InitializeBuffers(device); + if (!result) + { + return false; + } + + // Load the textures for this sprite. + result = LoadTextures(device, deviceContext, spriteFilename); + if (!result) + { + return false; + } + + return true; +} + + +void SpriteClass::Shutdown() +{ + // Release the textures used for this sprite. + ReleaseTextures(); + + // Release the vertex and index buffers. + ShutdownBuffers(); + + return; +} + + +bool SpriteClass::Render(ID3D11DeviceContext* deviceContext) +{ + bool result; + + + // Update the buffers if the position of the sprite has changed from its original position. + result = UpdateBuffers(deviceContext); + if (!result) + { + return false; + } + + // Put the vertex and index buffers on the graphics pipeline to prepare them for drawing. + RenderBuffers(deviceContext); + + return true; +} + +void SpriteClass::Update(float frameTime) +{ + // Increment the frame time each frame. + m_frameTime += frameTime; + + // Check if the frame time has reached the cycle time. + if (m_frameTime >= m_cycleTime) + { + // If it has then reset the frame time and cycle to the next sprite in the texture array. + m_frameTime -= m_cycleTime; + + m_currentTexture++; + + // If we are at the last sprite texture then go back to the beginning of the texture array to the first texture again. + if (m_currentTexture == m_textureCount) + { + m_currentTexture = 0; + } + } + + return; +} + + +int SpriteClass::GetIndexCount() +{ + return m_indexCount; +} + +ID3D11ShaderResourceView* SpriteClass::GetTexture() +{ + return m_Textures[m_currentTexture].GetTexture(); +} + + +bool SpriteClass::InitializeBuffers(ID3D11Device* device) +{ + VertexType* vertices; + unsigned long* indices; + D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc; + D3D11_SUBRESOURCE_DATA vertexData, indexData; + HRESULT result; + int i; + + + // Initialize the previous rendering position to negative one. + m_prevPosX = -1; + m_prevPosY = -1; + + // Set the number of vertices in the vertex array. + m_vertexCount = 6; + + // Set the number of indices in the index array. + 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)); + + // Load the index array with data. + 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; + + // Now finally create the vertex buffer. + result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &m_vertexBuffer); + if (FAILED(result)) + { + return false; + } + + // Set up the description of the 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 arrays now that the vertex and index buffers have been created and loaded. + delete[] vertices; + vertices = 0; + + delete[] indices; + indices = 0; + + return true; +} + + +void SpriteClass::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 SpriteClass::UpdateBuffers(ID3D11DeviceContext* deviceContent) +{ + float left, right, top, bottom; + VertexType* vertices; + D3D11_MAPPED_SUBRESOURCE mappedResource; + VertexType* dataPtr; + HRESULT result; + + + // If the position we are rendering this bitmap to hasn't changed then don't update the vertex buffer. + if ((m_prevPosX == m_renderX) && (m_prevPosY == m_renderY)) + { + return true; + } + + // If the rendering location has changed then store the new position and update the vertex buffer. + m_prevPosX = m_renderX; + m_prevPosY = m_renderY; + + // Create the vertex array. + vertices = new VertexType[m_vertexCount]; + + // Calculate the screen coordinates of the left side of the bitmap. + left = (float)((m_screenWidth / 2) * -1) + (float)m_renderX; + + // Calculate the screen coordinates of the right side of the bitmap. + right = left + (float)m_bitmapWidth; + + // Calculate the screen coordinates of the top of the bitmap. + top = (float)(m_screenHeight / 2) - (float)m_renderY; + + // Calculate the screen coordinates of the bottom of the bitmap. + bottom = top - (float)m_bitmapHeight; + + // Load the vertex array with data. + // First triangle. + vertices[0].position = XMFLOAT3(left, top, 0.0f); // Top left. + vertices[0].texture = XMFLOAT2(0.0f, 0.0f); + + vertices[1].position = XMFLOAT3(right, bottom, 0.0f); // Bottom right. + vertices[1].texture = XMFLOAT2(1.0f, 1.0f); + + vertices[2].position = XMFLOAT3(left, bottom, 0.0f); // Bottom left. + vertices[2].texture = XMFLOAT2(0.0f, 1.0f); + + // Second triangle. + vertices[3].position = XMFLOAT3(left, top, 0.0f); // Top left. + vertices[3].texture = XMFLOAT2(0.0f, 0.0f); + + vertices[4].position = XMFLOAT3(right, top, 0.0f); // Top right. + vertices[4].texture = XMFLOAT2(1.0f, 0.0f); + + vertices[5].position = XMFLOAT3(right, bottom, 0.0f); // Bottom right. + vertices[5].texture = XMFLOAT2(1.0f, 1.0f); + + // Lock the vertex buffer. + result = deviceContent->Map(m_vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return false; + } + + // Get a pointer to the data in the constant buffer. + dataPtr = (VertexType*)mappedResource.pData; + + // Copy the data into the vertex buffer. + memcpy(dataPtr, (void*)vertices, (sizeof(VertexType) * m_vertexCount)); + + // Unlock the vertex buffer. + deviceContent->Unmap(m_vertexBuffer, 0); + + // Release the pointer reference. + dataPtr = 0; + + // Release the vertex array as it is no longer needed. + delete[] vertices; + vertices = 0; + + return true; +} + + +void SpriteClass::RenderBuffers(ID3D11DeviceContext* deviceContext) +{ + unsigned int stride; + unsigned int 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; +} + +bool SpriteClass::LoadTextures(ID3D11Device* device, ID3D11DeviceContext* deviceContext, char* filename) +{ + char textureFilename[128]; + std::ifstream fin; + int i, j; + char input; + bool result; + + + // Open the sprite info data file. + fin.open(filename); + if (fin.fail()) + { + return false; + } + + // Read in the number of textures. + fin >> m_textureCount; + + // Create and initialize the texture array with the texture count from the file. + m_Textures = new TextureClass[m_textureCount]; + + // Read to start of next line. + fin.get(input); + + // Read in each texture file name. + for (i = 0; i < m_textureCount; i++) + { + j = 0; + fin.get(input); + while (input != '\n') + { + textureFilename[j] = input; + j++; + fin.get(input); + } + textureFilename[j] = '\0'; + + // Once you have the filename then load the texture in the texture array. + result = m_Textures[i].Initialize(device, deviceContext, textureFilename); + if (!result) + { + return false; + } + } + + // Read in the cycle time. + fin >> m_cycleTime; + + // Convert the integer milliseconds to float representation. + m_cycleTime = m_cycleTime * 0.001f; + + // Close the file. + fin.close(); + + // Get the dimensions of the first texture and use that as the dimensions of the 2D sprite images. + m_bitmapWidth = m_Textures[0].GetWidth(); + m_bitmapHeight = m_Textures[0].GetHeight(); + + // Set the starting texture in the cycle to be the first one in the list. + m_currentTexture = 0; + + return true; +} + +void SpriteClass::ReleaseTextures() +{ + int i; + + + // Release the texture objects. + if (m_Textures) + { + for (i = 0; i < m_textureCount; i++) + { + m_Textures[i].Shutdown(); + } + + delete[] m_Textures; + m_Textures = 0; + } + + return; +} + + +void SpriteClass::SetRenderLocation(int x, int y) +{ + m_renderX = x; + m_renderY = y; + return; +} diff --git a/enginecustom/Spriteclass.h b/enginecustom/Spriteclass.h new file mode 100644 index 0000000..5cf28cf --- /dev/null +++ b/enginecustom/Spriteclass.h @@ -0,0 +1,63 @@ +#ifndef _SPRITECLASS_H_ +#define _SPRITECLASS_H_ + + +////////////// +// INCLUDES // +////////////// +#include +#include +using namespace DirectX; + + +/////////////////////// +// MY CLASS INCLUDES // +/////////////////////// +#include "textureclass.h" + + +//////////////////////////////////////////////////////////////////////////////// +// Class name: SpriteClass +//////////////////////////////////////////////////////////////////////////////// +class SpriteClass +{ +private: + struct VertexType + { + XMFLOAT3 position; + XMFLOAT2 texture; + }; + +public: + SpriteClass(); + SpriteClass(const SpriteClass&); + ~SpriteClass(); + + bool Initialize(ID3D11Device*, ID3D11DeviceContext*, int, int, char*, int, int); + void Shutdown(); + bool Render(ID3D11DeviceContext*); + void Update(float); + + int GetIndexCount(); + ID3D11ShaderResourceView* GetTexture(); + + void SetRenderLocation(int, int); + +private: + bool InitializeBuffers(ID3D11Device*); + void ShutdownBuffers(); + bool UpdateBuffers(ID3D11DeviceContext*); + void RenderBuffers(ID3D11DeviceContext*); + + bool LoadTextures(ID3D11Device*, ID3D11DeviceContext*, char*); + void ReleaseTextures(); + +private: + ID3D11Buffer* m_vertexBuffer, * m_indexBuffer; + int m_vertexCount, m_indexCount, m_screenWidth, m_screenHeight, m_bitmapWidth, m_bitmapHeight, m_renderX, m_renderY, m_prevPosX, m_prevPosY; + TextureClass* m_Textures; + float m_frameTime, m_cycleTime; + int m_currentTexture, m_textureCount; +}; + +#endif \ No newline at end of file diff --git a/enginecustom/Systemclass.cpp b/enginecustom/Systemclass.cpp index 2f0b18e..287ca70 100644 --- a/enginecustom/Systemclass.cpp +++ b/enginecustom/Systemclass.cpp @@ -213,9 +213,9 @@ void SystemClass::InitializeWindows(int& screenWidth, int& screenHeight) } else { - // If windowed then set it to 800x600 resolution. - screenWidth = 800; - screenHeight = 600; + // If windowed then set it to 1600x900 resolution. + screenWidth = 1600; + screenHeight = 900; // Place the window in the middle of the screen. posX = (GetSystemMetrics(SM_CXSCREEN) - screenWidth) / 2; diff --git a/enginecustom/Timerclass.cpp b/enginecustom/Timerclass.cpp new file mode 100644 index 0000000..1b21aa6 --- /dev/null +++ b/enginecustom/Timerclass.cpp @@ -0,0 +1,63 @@ +#include "timerclass.h" + + +TimerClass::TimerClass() +{ +} + + +TimerClass::TimerClass(const TimerClass& other) +{ +} + + +TimerClass::~TimerClass() +{ +} + +bool TimerClass::Initialize() +{ + INT64 frequency; + + + // Get the cycles per second speed for this system. + QueryPerformanceFrequency((LARGE_INTEGER*)&frequency); + if (frequency == 0) + { + return false; + } + + // Store it in floating point. + m_frequency = (float)frequency; + + // Get the initial start time. + QueryPerformanceCounter((LARGE_INTEGER*)&m_startTime); + + return true; +} + +void TimerClass::Frame() +{ + INT64 currentTime; + INT64 elapsedTicks; + + + // Query the current time. + QueryPerformanceCounter((LARGE_INTEGER*)¤tTime); + + // Calculate the difference in time since the last time we queried for the current time. + elapsedTicks = currentTime - m_startTime; + + // Calculate the frame time. + m_frameTime = (float)elapsedTicks / m_frequency; + + // Restart the timer. + m_startTime = currentTime; + + return; +} + +float TimerClass::GetTime() +{ + return m_frameTime; +} diff --git a/enginecustom/Timerclass.h b/enginecustom/Timerclass.h new file mode 100644 index 0000000..d0c5cb7 --- /dev/null +++ b/enginecustom/Timerclass.h @@ -0,0 +1,32 @@ +#ifndef _TIMERCLASS_H_ +#define _TIMERCLASS_H_ + + +////////////// +// INCLUDES // +////////////// +#include + + +//////////////////////////////////////////////////////////////////////////////// +// Class name: TimerClass +//////////////////////////////////////////////////////////////////////////////// +class TimerClass +{ +public: + TimerClass(); + TimerClass(const TimerClass&); + ~TimerClass(); + + bool Initialize(); + void Frame(); + + float GetTime(); + +private: + float m_frequency; + INT64 m_startTime; + float m_frameTime; +}; + +#endif \ No newline at end of file diff --git a/enginecustom/applicationclass.cpp b/enginecustom/applicationclass.cpp index 388e678..49698e7 100644 --- a/enginecustom/applicationclass.cpp +++ b/enginecustom/applicationclass.cpp @@ -8,6 +8,10 @@ ApplicationClass::ApplicationClass() m_Model = 0; m_LightShader = 0; m_Light = 0; + m_TextureShader = 0; + m_Bitmap = 0; + m_Sprite = 0; + m_Timer = 0; } @@ -23,7 +27,10 @@ ApplicationClass::~ApplicationClass() bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) { - char modelFilename[128], textureFilename1[128], textureFilename2[128]; + char modelFilename[128]; + char textureFilename1[128], textureFilename2[128]; + char bitmapFilename[128]; + char spriteFilename[128]; bool result; @@ -50,8 +57,51 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) } // Set the initial position of the camera. - m_Camera->SetPosition(0.0f, 0.0f, -5.0f); - m_Camera->SetRotation(0.0f, 0.0f, 10.0f); + m_Camera->SetPosition(0.0f, 0.0f, -10.0f); + m_Camera->SetRotation(0.0f, 0.0f, 0.0f); + + // Create and initialize the texture shader object. + m_TextureShader = new TextureShaderClass; + + result = m_TextureShader->Initialize(m_Direct3D->GetDevice(), hwnd); + if (!result) + { + MessageBox(hwnd, L"Could not initialize the texture shader object.", L"Error", MB_OK); + return false; + } + + // Set the sprite info file we will be using. + strcpy_s(spriteFilename, "sprite_data_01.txt"); + + // Create and initialize the sprite object. + m_Sprite = new SpriteClass; + + result = m_Sprite->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), screenWidth, screenHeight, spriteFilename, 50, 50); + if (!result) + { + return false; + } + + // Create and initialize the timer object. + m_Timer = new TimerClass; + + result = m_Timer->Initialize(); + if (!result) + { + return false; + } + + // Set the file name of the bitmap file. + strcpy_s(bitmapFilename, "stone01.tga"); + + // Create and initialize the bitmap object. + m_Bitmap = new BitmapClass; + + result = m_Bitmap->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), screenWidth, screenHeight, bitmapFilename, 50, 50); + if (!result) + { + return false; + } // Create and initialize the multitexture shader object. m_MultiTextureShader = new MultiTextureShaderClass; @@ -90,6 +140,7 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) MessageBox(hwnd, L"Could not initialize the light shader object.", L"Error", MB_OK); return false; } + // Create and initialize the light object. m_Light = new LightClass; @@ -103,6 +154,21 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) void ApplicationClass::Shutdown() { + // Release the timer object. + if (m_Timer) + { + delete m_Timer; + m_Timer = 0; + } + + // Release the sprite object. + if (m_Sprite) + { + m_Sprite->Shutdown(); + delete m_Sprite; + m_Sprite = 0; + } + // Release the light object. if (m_Light) { @@ -118,6 +184,14 @@ void ApplicationClass::Shutdown() m_LightShader = 0; } + // Release the light shader object. + if (m_LightShader) + { + m_LightShader->Shutdown(); + delete m_LightShader; + m_LightShader = 0; + } + // Release the model object. if (m_Model) { @@ -132,33 +206,51 @@ void ApplicationClass::Shutdown() m_MultiTextureShader->Shutdown(); delete m_MultiTextureShader; m_MultiTextureShader = 0; - } + // Release the bitmap object. + if (m_Bitmap) + { + m_Bitmap->Shutdown(); + delete m_Bitmap; + m_Bitmap = 0; + } - // Release the camera object. - if (m_Camera) - { - delete m_Camera; - m_Camera = 0; - } + // Release the texture shader object. + if (m_TextureShader) + { + m_TextureShader->Shutdown(); + delete m_TextureShader; + m_TextureShader = 0; + } - // Release the D3D object. - if (m_Direct3D) - { - m_Direct3D->Shutdown(); - delete m_Direct3D; - m_Direct3D = 0; - } + // Release the camera object. + if (m_Camera) + { + delete m_Camera; + m_Camera = 0; + } - return; + // Release the D3D object. + if (m_Direct3D) + { + m_Direct3D->Shutdown(); + delete m_Direct3D; + m_Direct3D = 0; + } + + return; + } } bool ApplicationClass::Frame() { + float frameTime; static float rotation = 0.0f; + static float x = 2.f; + static float y = 0.f; + static float z = 0.f; bool result; - // Update the rotation variable each frame. rotation -= 0.0174532925f * 0.1f; if (rotation < 0.0f) @@ -166,20 +258,38 @@ bool ApplicationClass::Frame() rotation += 360.0f; } + // Update the x position variable each frame. + x -= 0.0174532925f * 0.54672f; + + y -= 0.0174532925f * 0.8972f; + + // Update the z position variable each frame. + z -= 0.0174532925f * 0.8972f; + + // Render the graphics scene. - result = Render(rotation); + result = Render(rotation, x, y, z); if (!result) { return false; } + // Update the system stats. + m_Timer->Frame(); + + // Get the current frame time. + frameTime = m_Timer->GetTime(); + + // Update the sprite object using the frame time. + m_Sprite->Update(frameTime); + return true; } -bool ApplicationClass::Render(float rotation) +bool ApplicationClass::Render(float rotation, float x, float y, float z) { - XMMATRIX worldMatrix, viewMatrix, projectionMatrix; + XMMATRIX worldMatrix, viewMatrix, orthoMatrix, projectionMatrix, rotateMatrix, translateMatrix, scaleMatrix, srMatrix; bool result; // Clear the buffers to begin the scene. @@ -192,8 +302,54 @@ bool ApplicationClass::Render(float rotation) m_Direct3D->GetWorldMatrix(worldMatrix); m_Camera->GetViewMatrix(viewMatrix); m_Direct3D->GetProjectionMatrix(projectionMatrix); - // Rotate the world matrix by the rotation value so that the triangle will spin. - worldMatrix = XMMatrixRotationY(rotation); + m_Direct3D->GetOrthoMatrix(orthoMatrix); + + // Turn off the Z buffer to begin all 2D rendering. + m_Direct3D->TurnZBufferOff(); + + // Put the sprite vertex and index buffers on the graphics pipeline to prepare them for drawing. + result = m_Sprite->Render(m_Direct3D->GetDeviceContext()); + if (!result) + { + return false; + } + + // Render the sprite with the texture shader. + result = m_TextureShader->Render(m_Direct3D->GetDeviceContext(), m_Sprite->GetIndexCount(), worldMatrix, viewMatrix, orthoMatrix, m_Sprite->GetTexture()); + if (!result) + { + return false; + } + + // Put the bitmap vertex and index buffers on the graphics pipeline to prepare them for drawing. + result = m_Bitmap->Render(m_Direct3D->GetDeviceContext()); + if (!result) + { + return false; + } + + m_Bitmap->SetRenderLocation(1200, 50); + + // Render the bitmap with the texture shader. + result = m_TextureShader->Render(m_Direct3D->GetDeviceContext(), m_Bitmap->GetIndexCount(), worldMatrix, viewMatrix, orthoMatrix, m_Bitmap->GetTexture()); + if (!result) + { + return false; + } + + + + // Render the model using the multitexture shader. + result = m_MultiTextureShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, + m_Model->GetTexture(0), m_Model->GetTexture(1)); + + scaleMatrix = XMMatrixScaling(0.5f, 0.5f, 0.5f); // Build the scaling matrix. + rotateMatrix = XMMatrixRotationY(rotation); // Build the rotation matrix. + translateMatrix = XMMatrixTranslation(x, y, z); // Build the translation matrix. + + // Multiply the scale, rotation, and translation matrices together to create the final world transformation matrix. + srMatrix = XMMatrixMultiply(scaleMatrix, rotateMatrix); + worldMatrix = XMMatrixMultiply(srMatrix, translateMatrix); // Render the model using the multitexture shader. m_Model->Render(m_Direct3D->GetDeviceContext()); @@ -206,14 +362,28 @@ bool ApplicationClass::Render(float rotation) return false; } - // Render the model using the multitexture shader. - result = m_MultiTextureShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, - m_Model->GetTexture(0), m_Model->GetTexture(1)); + scaleMatrix = XMMatrixScaling(2.0f, 2.0f, 2.0f); // Build the scaling matrix. + rotateMatrix = XMMatrixRotationY(-rotation); // Build the rotation matrix. + translateMatrix = XMMatrixTranslation(-x, -y, -z); // Build the translation matrix. + + // Multiply the scale, rotation, and translation matrices together to create the final world transformation matrix. + srMatrix = XMMatrixMultiply(scaleMatrix, rotateMatrix); + worldMatrix = XMMatrixMultiply(srMatrix, translateMatrix); + + // 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 light shader. + result = m_LightShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(0), + m_Light->GetDirection(), m_Light->GetAmbientColor(), m_Light->GetDiffuseColor()); if (!result) { return false; } + // Turn the Z buffer back on now that all 2D rendering has completed. + m_Direct3D->TurnZBufferOn(); + // Present the rendered scene to the screen. m_Direct3D->EndScene(); diff --git a/enginecustom/applicationclass.h b/enginecustom/applicationclass.h index ac2f097..9ceb351 100644 --- a/enginecustom/applicationclass.h +++ b/enginecustom/applicationclass.h @@ -11,7 +11,10 @@ #include "lightshaderclass.h" #include "lightclass.h" #include "multitextureshaderclass.h" -#include "modelclass.h" +#include "bitmapclass.h" +#include "textureshaderclass.h" +#include "spriteclass.h" +#include "timerclass.h" ///////////// // GLOBALS // @@ -37,8 +40,7 @@ public: bool Frame(); private: - bool Render(float); - + bool Render(float, float, float, float); private: D3DClass* m_Direct3D; CameraClass* m_Camera; @@ -46,6 +48,10 @@ private: LightClass* m_Light; MultiTextureShaderClass* m_MultiTextureShader; ModelClass* m_Model; + TextureShaderClass* m_TextureShader; + BitmapClass* m_Bitmap; + SpriteClass* m_Sprite; + TimerClass* m_Timer; }; #endif diff --git a/enginecustom/bitmapclass.cpp b/enginecustom/bitmapclass.cpp new file mode 100644 index 0000000..ce25cb2 --- /dev/null +++ b/enginecustom/bitmapclass.cpp @@ -0,0 +1,333 @@ +#include "bitmapclass.h" + +BitmapClass::BitmapClass() +{ + m_vertexBuffer = 0; + m_indexBuffer = 0; + m_Texture = 0; +} + + +BitmapClass::BitmapClass(const BitmapClass& other) +{ +} + + +BitmapClass::~BitmapClass() +{ +} + + +bool BitmapClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceContext, int screenWidth, int screenHeight, char* textureFilename, int renderX, int renderY) +{ + bool result; + + // Store the screen size. + m_screenWidth = screenWidth; + m_screenHeight = screenHeight; + + // Store where the bitmap should be rendered to. + m_renderX = renderX; + m_renderY = renderY; + + // Initialize the vertex and index buffer that hold the geometry for the bitmap quad. + result = InitializeBuffers(device); + if (!result) + { + return false; + } + + // Load the texture for this bitmap. + result = LoadTexture(device, deviceContext, textureFilename); + if (!result) + { + return false; + } + + return true; +} + +void BitmapClass::Shutdown() +{ + // Release the bitmap texture. + ReleaseTexture(); + + // Release the vertex and index buffers. + ShutdownBuffers(); + + return; +} + +bool BitmapClass::Render(ID3D11DeviceContext* deviceContext) +{ + bool result; + + + // Update the buffers if the position of the bitmap has changed from its original position. + result = UpdateBuffers(deviceContext); + if (!result) + { + return false; + } + + // Put the vertex and index buffers on the graphics pipeline to prepare them for drawing. + RenderBuffers(deviceContext); + + return true; +} + +int BitmapClass::GetIndexCount() +{ + return m_indexCount; +} + +ID3D11ShaderResourceView* BitmapClass::GetTexture() +{ + return m_Texture->GetTexture(); +} + +bool BitmapClass::InitializeBuffers(ID3D11Device* device) +{ + VertexType* vertices; + unsigned long* indices; + D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc; + D3D11_SUBRESOURCE_DATA vertexData, indexData; + HRESULT result; + int i; + + // Initialize the previous rendering position to negative one. + m_prevPosX = -1; + m_prevPosY = -1; + + // Set the number of vertices in the vertex array. + m_vertexCount = 6; + + // Set the number of indices in the index array. + 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)); + + // Load the index array with data. + 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; + + // Now finally create the vertex buffer. + result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &m_vertexBuffer); + if (FAILED(result)) + { + return false; + } + + // Set up the description of the 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 arrays now that the vertex and index buffers have been created and loaded. + delete[] vertices; + vertices = 0; + + delete[] indices; + indices = 0; + + return true; +} + +void BitmapClass::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 BitmapClass::UpdateBuffers(ID3D11DeviceContext* deviceContent) +{ + float left, right, top, bottom; + VertexType* vertices; + D3D11_MAPPED_SUBRESOURCE mappedResource; + VertexType* dataPtr; + HRESULT result; + + // If the position we are rendering this bitmap to hasn't changed then don't update the vertex buffer. + if ((m_prevPosX == m_renderX) && (m_prevPosY == m_renderY)) + { + return true; + } + + // If the rendering location has changed then store the new position and update the vertex buffer. + m_prevPosX = m_renderX; + m_prevPosY = m_renderY; + + // Create the vertex array. + vertices = new VertexType[m_vertexCount]; + + // Calculate the screen coordinates of the left side of the bitmap. + left = (float)((m_screenWidth / 2) * -1) + (float)m_renderX; + + // Calculate the screen coordinates of the right side of the bitmap. + right = left + (float)m_bitmapWidth; + + // Calculate the screen coordinates of the top of the bitmap. + top = (float)(m_screenHeight / 2) - (float)m_renderY; + + // Calculate the screen coordinates of the bottom of the bitmap. + bottom = top - (float)m_bitmapHeight; + + // Load the vertex array with data. +// First triangle. + vertices[0].position = XMFLOAT3(left, top, 0.0f); // Top left. + vertices[0].texture = XMFLOAT2(0.0f, 0.0f); + + vertices[1].position = XMFLOAT3(right, bottom, 0.0f); // Bottom right. + vertices[1].texture = XMFLOAT2(1.0f, 1.0f); + + vertices[2].position = XMFLOAT3(left, bottom, 0.0f); // Bottom left. + vertices[2].texture = XMFLOAT2(0.0f, 1.0f); + + // Second triangle. + vertices[3].position = XMFLOAT3(left, top, 0.0f); // Top left. + vertices[3].texture = XMFLOAT2(0.0f, 0.0f); + + vertices[4].position = XMFLOAT3(right, top, 0.0f); // Top right. + vertices[4].texture = XMFLOAT2(1.0f, 0.0f); + + vertices[5].position = XMFLOAT3(right, bottom, 0.0f); // Bottom right. + vertices[5].texture = XMFLOAT2(1.0f, 1.0f); + + // Lock the vertex buffer. + result = deviceContent->Map(m_vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return false; + } + + // Get a pointer to the data in the constant buffer. + dataPtr = (VertexType*)mappedResource.pData; + + // Copy the data into the vertex buffer. + memcpy(dataPtr, (void*)vertices, (sizeof(VertexType) * m_vertexCount)); + + // Unlock the vertex buffer. + deviceContent->Unmap(m_vertexBuffer, 0); + + // Release the pointer reference. + dataPtr = 0; + + // Release the vertex array as it is no longer needed. + delete[] vertices; + vertices = 0; + + return true; +} + +void BitmapClass::RenderBuffers(ID3D11DeviceContext* deviceContext) +{ + unsigned int stride; + unsigned int 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; +} + +bool BitmapClass::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; + } + + // Store the size in pixels that this bitmap should be rendered at. + m_bitmapWidth = m_Texture->GetWidth(); + m_bitmapHeight = m_Texture->GetHeight(); + + return true; +} + +void BitmapClass::ReleaseTexture() +{ + // Release the texture object. + if (m_Texture) + { + m_Texture->Shutdown(); + delete m_Texture; + m_Texture = 0; + } + + return; +} + +void BitmapClass::SetRenderLocation(int x, int y) +{ + m_renderX = x; + m_renderY = y; + return; +} \ No newline at end of file diff --git a/enginecustom/bitmapclass.h b/enginecustom/bitmapclass.h new file mode 100644 index 0000000..9af076c --- /dev/null +++ b/enginecustom/bitmapclass.h @@ -0,0 +1,58 @@ +#ifndef _BITMAPCLASS_H_ +#define _BITMAPCLASS_H_ + + +////////////// +// INCLUDES // +////////////// +#include +using namespace DirectX; + + +/////////////////////// +// MY CLASS INCLUDES // +/////////////////////// +#include "textureclass.h" + + +//////////////////////////////////////////////////////////////////////////////// +// Class name: BitmapClass +//////////////////////////////////////////////////////////////////////////////// +class BitmapClass +{ +private: + struct VertexType + { + XMFLOAT3 position; + XMFLOAT2 texture; + }; + +public: + BitmapClass(); + BitmapClass(const BitmapClass&); + ~BitmapClass(); + + bool Initialize(ID3D11Device*, ID3D11DeviceContext*, int, int, char*, int, int); + void Shutdown(); + bool Render(ID3D11DeviceContext*); + + int GetIndexCount(); + ID3D11ShaderResourceView* GetTexture(); + + void SetRenderLocation(int, int); + +private: + bool InitializeBuffers(ID3D11Device*); + void ShutdownBuffers(); + bool UpdateBuffers(ID3D11DeviceContext*); + void RenderBuffers(ID3D11DeviceContext*); + + bool LoadTexture(ID3D11Device*, ID3D11DeviceContext*, char*); + void ReleaseTexture(); +private: + ID3D11Buffer* m_vertexBuffer, * m_indexBuffer; + int m_vertexCount, m_indexCount, m_screenWidth, m_screenHeight, m_bitmapWidth, m_bitmapHeight, m_renderX, m_renderY, m_prevPosX, m_prevPosY; + TextureClass* m_Texture; +}; + +#endif \ No newline at end of file diff --git a/enginecustom/cube.mtl b/enginecustom/cube.mtl new file mode 100644 index 0000000..d189f87 --- /dev/null +++ b/enginecustom/cube.mtl @@ -0,0 +1,22 @@ +# Blender MTL File: 'None' +# Material Count: 2 + +newmtl Material +Ns 323.999994 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.800000 0.800000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 + +newmtl Material.001 +Ns 225.000000 +Ka 1.000000 1.000000 1.000000 +Kd 0.000000 0.002280 0.800000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 diff --git a/enginecustom/cube.txt b/enginecustom/cube.txt index 00b34ba..f8040ca 100644 --- a/enginecustom/cube.txt +++ b/enginecustom/cube.txt @@ -37,4 +37,4 @@ Data: -1.0 -1.0 1.0 0.0 1.0 0.0 -1.0 0.0 -1.0 -1.0 1.0 0.0 1.0 0.0 -1.0 0.0 1.0 -1.0 -1.0 1.0 0.0 0.0 -1.0 0.0 - 1.0 -1.0 1.0 1.0 1.0 0.0 -1.0 0.0 \ No newline at end of file + 1.0 -1.0 1.0 1.0 1.0 0.0 -1.0 0.0 diff --git a/enginecustom/d3dclass.cpp b/enginecustom/d3dclass.cpp index e87bc65..e91e8c7 100644 --- a/enginecustom/d3dclass.cpp +++ b/enginecustom/d3dclass.cpp @@ -14,6 +14,7 @@ D3DClass::D3DClass() m_depthStencilState = 0; m_depthStencilView = 0; m_rasterState = 0; + m_depthDisabledStencilState = 0; } @@ -46,7 +47,7 @@ bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hw D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; float fieldOfView, screenAspect; - + D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc; // Store the vsync setting. m_vsync_enabled = vsync; @@ -345,6 +346,34 @@ bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hw // Create an orthographic projection matrix for 2D rendering. m_orthoMatrix = XMMatrixOrthographicLH((float)screenWidth, (float)screenHeight, screenNear, screenDepth); + // Clear the second depth stencil state before setting the parameters. + ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc)); + + // Now create a second depth stencil state which turns off the Z buffer for 2D rendering. The only difference is + // that DepthEnable is set to false, all other parameters are the same as the other depth stencil state. + depthDisabledStencilDesc.DepthEnable = false; + depthDisabledStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + depthDisabledStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; + depthDisabledStencilDesc.StencilEnable = true; + depthDisabledStencilDesc.StencilReadMask = 0xFF; + depthDisabledStencilDesc.StencilWriteMask = 0xFF; + depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; + depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthDisabledStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + depthDisabledStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthDisabledStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; + depthDisabledStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthDisabledStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + + // Create the state using the device. + result = m_device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_depthDisabledStencilState); + if (FAILED(result)) + { + return false; + } + + return true; } @@ -357,6 +386,12 @@ void D3DClass::Shutdown() m_swapChain->SetFullscreenState(false, NULL); } + if (m_depthDisabledStencilState) + { + m_depthDisabledStencilState->Release(); + m_depthDisabledStencilState = 0; + } + if (m_rasterState) { m_rasterState->Release(); @@ -503,5 +538,18 @@ void D3DClass::ResetViewport() // Set the viewport. m_deviceContext->RSSetViewports(1, &m_viewport); + return; +} + +void D3DClass::TurnZBufferOn() +{ + m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); + return; +} + + +void D3DClass::TurnZBufferOff() +{ + m_deviceContext->OMSetDepthStencilState(m_depthDisabledStencilState, 1); return; } \ No newline at end of file diff --git a/enginecustom/d3dclass.h b/enginecustom/d3dclass.h index df75750..bb3c0ce 100644 --- a/enginecustom/d3dclass.h +++ b/enginecustom/d3dclass.h @@ -49,6 +49,9 @@ public: void SetBackBufferRenderTarget(); void ResetViewport(); + void TurnZBufferOn(); + void TurnZBufferOff(); + private: bool m_vsync_enabled; int m_videoCardMemory; @@ -65,6 +68,7 @@ private: XMMATRIX m_worldMatrix; XMMATRIX m_orthoMatrix; D3D11_VIEWPORT m_viewport; + ID3D11DepthStencilState* m_depthDisabledStencilState; }; #endif \ No newline at end of file diff --git a/enginecustom/enginecustom.vcxproj b/enginecustom/enginecustom.vcxproj index f0bb46b..9a20df2 100644 --- a/enginecustom/enginecustom.vcxproj +++ b/enginecustom/enginecustom.vcxproj @@ -21,20 +21,25 @@ + - - + + + + + + @@ -43,8 +48,11 @@ + + + @@ -52,6 +60,8 @@ + + @@ -75,10 +85,16 @@ + + + + Document + + 17.0 Win32Proj diff --git a/enginecustom/enginecustom.vcxproj.filters b/enginecustom/enginecustom.vcxproj.filters index 87a4e5e..1fb3790 100644 --- a/enginecustom/enginecustom.vcxproj.filters +++ b/enginecustom/enginecustom.vcxproj.filters @@ -58,6 +58,16 @@ Fichiers sources + + Fichiers sources + + + Fichiers sources + + + Fichiers sources + + Fichiers sources @@ -95,6 +105,24 @@ Fichiers d%27en-tête + + Fichiers d%27en-tête + + + Fichiers d%27en-tête + + + Fichiers d%27en-tête + + + Fichiers d%27en-tête + + + Fichiers d%27en-tête + + + Fichiers d%27en-tête + @@ -112,8 +140,20 @@ + + texture + + + texture + + + assets + + + assets + assets diff --git a/enginecustom/light.ps b/enginecustom/light.ps index f0fe5fb..8af8dd4 100644 --- a/enginecustom/light.ps +++ b/enginecustom/light.ps @@ -8,13 +8,12 @@ ///////////// Texture2D shaderTexture : register(t0); SamplerState SampleType : register(s0); - cbuffer LightBuffer { float4 ambientColor; float4 diffuseColor; float3 lightDirection; - float padding; + float padding; }; @@ -25,7 +24,7 @@ struct PixelInputType { float4 position : SV_POSITION; float2 tex : TEXCOORD0; - float3 normal : NORMAL; + float3 normal : NORMAL; }; @@ -34,14 +33,14 @@ struct PixelInputType //////////////////////////////////////////////////////////////////////////////// float4 LightPixelShader(PixelInputType input) : SV_TARGET { - float4 textureColor; - float3 lightDir; - float lightIntensity; - float4 color; + float4 textureColor; + float3 lightDir; + float lightIntensity; + float4 color; - // Sample the pixel color from the texture using the sampler at this texture coordinate location. - textureColor = shaderTexture.Sample(SampleType, input.tex); + // Sample the pixel color from the texture using the sampler at this texture coordinate location. + textureColor = shaderTexture.Sample(SampleType, input.tex); // Set the default output color to the ambient light value for all pixels. color = ambientColor; @@ -62,7 +61,7 @@ float4 LightPixelShader(PixelInputType input) : SV_TARGET color = saturate(color); // Multiply the texture pixel and the final diffuse color to get the final pixel color result. - color = color * textureColor; + color = color * textureColor; - return color; -} + return color; +} \ No newline at end of file diff --git a/enginecustom/light.vs b/enginecustom/light.vs index 4a0b1f3..940b5ec 100644 --- a/enginecustom/light.vs +++ b/enginecustom/light.vs @@ -13,7 +13,6 @@ cbuffer MatrixBuffer matrix projectionMatrix; }; - ////////////// // TYPEDEFS // ////////////// diff --git a/enginecustom/lightclass.cpp b/enginecustom/lightclass.cpp index 1626027..85f6160 100644 --- a/enginecustom/lightclass.cpp +++ b/enginecustom/lightclass.cpp @@ -28,15 +28,15 @@ void LightClass::SetAmbientColor(float red, float green, float blue, float alpha void LightClass::SetDiffuseColor(float red, float green, float blue, float alpha) { - m_diffuseColor = XMFLOAT4(red, green, blue, alpha); - return; + m_diffuseColor = XMFLOAT4(red, green, blue, alpha); + return; } void LightClass::SetDirection(float x, float y, float z) { - m_direction = XMFLOAT3(x, y, z); - return; + m_direction = XMFLOAT3(x, y, z); + return; } XMFLOAT4 LightClass::GetAmbientColor() @@ -47,11 +47,11 @@ XMFLOAT4 LightClass::GetAmbientColor() XMFLOAT4 LightClass::GetDiffuseColor() { - return m_diffuseColor; + return m_diffuseColor; } XMFLOAT3 LightClass::GetDirection() { - return m_direction; + return m_direction; } \ No newline at end of file diff --git a/enginecustom/lightclass.h b/enginecustom/lightclass.h index e17e066..aafc8a2 100644 --- a/enginecustom/lightclass.h +++ b/enginecustom/lightclass.h @@ -1,3 +1,4 @@ +#pragma once //////////////////////////////////////////////////////////////////////////////// // Filename: lightclass.h //////////////////////////////////////////////////////////////////////////////// @@ -18,9 +19,9 @@ using namespace DirectX; class LightClass { public: - LightClass(); - LightClass(const LightClass&); - ~LightClass(); + LightClass(); + LightClass(const LightClass&); + ~LightClass(); void SetAmbientColor(float, float, float, float); void SetDiffuseColor(float, float, float, float); diff --git a/enginecustom/lightshaderclass.cpp b/enginecustom/lightshaderclass.cpp index 637f870..9a8cc93 100644 --- a/enginecustom/lightshaderclass.cpp +++ b/enginecustom/lightshaderclass.cpp @@ -6,12 +6,12 @@ LightShaderClass::LightShaderClass() { - m_vertexShader = 0; - m_pixelShader = 0; - m_layout = 0; - m_sampleState = 0; - m_matrixBuffer = 0; - m_lightBuffer = 0; + m_vertexShader = 0; + m_pixelShader = 0; + m_layout = 0; + m_sampleState = 0; + m_matrixBuffer = 0; + m_lightBuffer = 0; } @@ -27,11 +27,17 @@ LightShaderClass::~LightShaderClass() bool LightShaderClass::Initialize(ID3D11Device* device, HWND hwnd) { - wchar_t vsFilename[128]; - wchar_t psFilename[128]; - int error; - bool result; + wchar_t vsFilename[128]; + wchar_t psFilename[128]; + int error; + bool result; + // Set the filename of the vertex shader. + error = wcscpy_s(vsFilename, 128, L"./Light.vs"); + if (error != 0) + { + return false; + } // Set the filename of the vertex shader. error = wcscpy_s(vsFilename, 128, L"light.vs"); @@ -46,31 +52,29 @@ bool LightShaderClass::Initialize(ID3D11Device* device, HWND hwnd) { return false; } + // Initialize the vertex and pixel shaders. + result = InitializeShader(device, hwnd, vsFilename, psFilename); + if (!result) + { + return false; + } - // Initialize the vertex and pixel shaders. - result = InitializeShader(device, hwnd, vsFilename, psFilename); - if(!result) - { - return false; - } - - return true; + return true; } void LightShaderClass::Shutdown() { - // Shutdown the vertex and pixel shaders as well as the related objects. - ShutdownShader(); + // Shutdown the vertex and pixel shaders as well as the related objects. + ShutdownShader(); - return; + return; } - bool LightShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix, ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 ambientColor, XMFLOAT4 diffuseColor) { - bool result; + bool result; // Set the shader parameters that it will use for rendering. @@ -80,126 +84,128 @@ bool LightShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount return false; } - // Now render the prepared buffers with the shader. - RenderShader(deviceContext, indexCount); + // Now render the prepared buffers with the shader. + RenderShader(deviceContext, indexCount); - return true; + return true; } bool LightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR* vsFilename, WCHAR* psFilename) { - HRESULT result; - ID3D10Blob* errorMessage; - ID3D10Blob* vertexShaderBuffer; - ID3D10Blob* pixelShaderBuffer; - D3D11_INPUT_ELEMENT_DESC polygonLayout[3]; - unsigned int numElements; + HRESULT result; + ID3D10Blob* errorMessage; + ID3D10Blob* vertexShaderBuffer; + ID3D10Blob* pixelShaderBuffer; + + D3D11_INPUT_ELEMENT_DESC polygonLayout[3]; + unsigned int numElements; D3D11_SAMPLER_DESC samplerDesc; - D3D11_BUFFER_DESC matrixBufferDesc; - D3D11_BUFFER_DESC lightBufferDesc; + D3D11_BUFFER_DESC matrixBufferDesc; + + D3D11_BUFFER_DESC lightBufferDesc; - // Initialize the pointers this function will use to null. - errorMessage = 0; - vertexShaderBuffer = 0; - pixelShaderBuffer = 0; + // 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, "LightVertexShader", "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); - } + result = D3DCompileFromFile(vsFilename, NULL, NULL, "LightVertexShader", "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; - } + return false; + } // Compile the pixel shader code. - result = D3DCompileFromFile(psFilename, NULL, NULL, "LightPixelShader", "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); - } + result = D3DCompileFromFile(psFilename, NULL, NULL, "LightPixelShader", "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; - } + return false; + } // Create the vertex shader from the buffer. result = device->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &m_vertexShader); - if(FAILED(result)) - { - return false; - } + 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; - } + 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; + // 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; + 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; - polygonLayout[2].SemanticName = "NORMAL"; - polygonLayout[2].SemanticIndex = 0; - polygonLayout[2].Format = DXGI_FORMAT_R32G32B32_FLOAT; - polygonLayout[2].InputSlot = 0; - polygonLayout[2].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; - polygonLayout[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - polygonLayout[2].InstanceDataStepRate = 0; + polygonLayout[2].SemanticName = "NORMAL"; + polygonLayout[2].SemanticIndex = 0; + polygonLayout[2].Format = DXGI_FORMAT_R32G32B32_FLOAT; + polygonLayout[2].InputSlot = 0; + polygonLayout[2].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; + polygonLayout[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + polygonLayout[2].InstanceDataStepRate = 0; - // Get a count of the elements in the layout. + // 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; - } + // 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; + // Release the vertex shader buffer and pixel shader buffer since they are no longer needed. + vertexShaderBuffer->Release(); + vertexShaderBuffer = 0; - pixelShaderBuffer->Release(); - pixelShaderBuffer = 0; + pixelShaderBuffer->Release(); + pixelShaderBuffer = 0; - // Create a texture sampler state description. + // 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; @@ -208,189 +214,189 @@ bool LightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR* 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.BorderColor[1] = 0; + samplerDesc.BorderColor[2] = 0; + samplerDesc.BorderColor[3] = 0; samplerDesc.MinLOD = 0; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; - // Create the texture sampler state. + // Create the texture sampler state. result = device->CreateSamplerState(&samplerDesc, &m_sampleState); - if(FAILED(result)) - { - return false; - } + if (FAILED(result)) + { + return false; + } - // Setup the description of the dynamic matrix constant buffer that is in the vertex shader. + // 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.ByteWidth = sizeof(MatrixBufferType); matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; matrixBufferDesc.MiscFlags = 0; - matrixBufferDesc.StructureByteStride = 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 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; + } - // Setup the description of the light dynamic constant buffer that is in the pixel shader. - // Note that ByteWidth always needs to be a multiple of 16 if using D3D11_BIND_CONSTANT_BUFFER or CreateBuffer will fail. - lightBufferDesc.Usage = D3D11_USAGE_DYNAMIC; - lightBufferDesc.ByteWidth = sizeof(LightBufferType); - lightBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - lightBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - lightBufferDesc.MiscFlags = 0; - lightBufferDesc.StructureByteStride = 0; + // Setup the description of the light dynamic constant buffer that is in the pixel shader. + // Note that ByteWidth always needs to be a multiple of 16 if using D3D11_BIND_CONSTANT_BUFFER or CreateBuffer will fail. + lightBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + lightBufferDesc.ByteWidth = sizeof(LightBufferType); + lightBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + lightBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + lightBufferDesc.MiscFlags = 0; + lightBufferDesc.StructureByteStride = 0; - // Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class. - result = device->CreateBuffer(&lightBufferDesc, NULL, &m_lightBuffer); - if(FAILED(result)) - { - return false; - } + // Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class. + result = device->CreateBuffer(&lightBufferDesc, NULL, &m_lightBuffer); + if (FAILED(result)) + { + return false; + } - return true; + return true; } void LightShaderClass::ShutdownShader() { - // Release the light constant buffer. - if(m_lightBuffer) - { - m_lightBuffer->Release(); - m_lightBuffer = 0; - } + // Release the light constant buffer. + if (m_lightBuffer) + { + m_lightBuffer->Release(); + m_lightBuffer = 0; + } - // Release the matrix constant buffer. - if(m_matrixBuffer) - { - m_matrixBuffer->Release(); - m_matrixBuffer = 0; - } + // Release the matrix constant buffer. + if (m_matrixBuffer) + { + m_matrixBuffer->Release(); + m_matrixBuffer = 0; + } - // Release the sampler state. - if(m_sampleState) - { - m_sampleState->Release(); - m_sampleState = 0; - } + // Release the sampler state. + if (m_sampleState) + { + m_sampleState->Release(); + m_sampleState = 0; + } - // Release the layout. - if(m_layout) - { - m_layout->Release(); - m_layout = 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 pixel shader. + if (m_pixelShader) + { + m_pixelShader->Release(); + m_pixelShader = 0; + } - // Release the vertex shader. - if(m_vertexShader) - { - m_vertexShader->Release(); - m_vertexShader = 0; - } + // Release the vertex shader. + if (m_vertexShader) + { + m_vertexShader->Release(); + m_vertexShader = 0; + } - return; + return; } void LightShaderClass::OutputShaderErrorMessage(ID3D10Blob* errorMessage, HWND hwnd, WCHAR* shaderFilename) { - char* compileErrors; - unsigned __int64 bufferSize, i; - ofstream fout; + char* compileErrors; + unsigned __int64 bufferSize, i; + ofstream fout; - // Get a pointer to the error message text buffer. - compileErrors = (char*)(errorMessage->GetBufferPointer()); + // Get a pointer to the error message text buffer. + compileErrors = (char*)(errorMessage->GetBufferPointer()); - // Get the length of the message. - bufferSize = errorMessage->GetBufferSize(); + // Get the length of the message. + bufferSize = errorMessage->GetBufferSize(); - // Open a file to write the error message to. - fout.open("shader-error.txt"); + // Open a file to write the error message to. + fout.open("shader-error.txt"); - // Write out the error message. - for(i=0; iRelease(); - errorMessage = 0; + // 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); + // 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; + return; } bool LightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix, ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 ambientColor, XMFLOAT4 diffuseColor) { - HRESULT result; + HRESULT result; D3D11_MAPPED_SUBRESOURCE mappedResource; - unsigned int bufferNumber; - MatrixBufferType* dataPtr; - LightBufferType* dataPtr2; + unsigned int bufferNumber; + MatrixBufferType* dataPtr; + LightBufferType* dataPtr2; - // Transpose the matrices to prepare them for the shader. - worldMatrix = XMMatrixTranspose(worldMatrix); - viewMatrix = XMMatrixTranspose(viewMatrix); - projectionMatrix = XMMatrixTranspose(projectionMatrix); + // 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; - } + // 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; + // 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; + // Copy the matrices into the constant buffer. + dataPtr->world = worldMatrix; + dataPtr->view = viewMatrix; + dataPtr->projection = projectionMatrix; - // Unlock the constant buffer. + // Unlock the constant buffer. deviceContext->Unmap(m_matrixBuffer, 0); - // Set the position of the constant buffer in the vertex shader. - bufferNumber = 0; + // Set the position of the constant buffer in the vertex shader. + bufferNumber = 0; - // Now set the constant buffer in the vertex shader with the updated values. + // Now 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); + // Set shader texture resource in the pixel shader. + deviceContext->PSSetShaderResources(0, 1, &texture); - // Lock the light constant buffer so it can be written to. - result = deviceContext->Map(m_lightBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if(FAILED(result)) - { - return false; - } + // Lock the light constant buffer so it can be written to. + result = deviceContext->Map(m_lightBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return false; + } - // Get a pointer to the data in the constant buffer. - dataPtr2 = (LightBufferType*)mappedResource.pData; + // Get a pointer to the data in the constant buffer. + dataPtr2 = (LightBufferType*)mappedResource.pData; // Copy the lighting variables into the constant buffer. dataPtr2->ambientColor = ambientColor; @@ -398,33 +404,33 @@ bool LightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, X dataPtr2->lightDirection = lightDirection; dataPtr2->padding = 0.0f; - // Unlock the constant buffer. - deviceContext->Unmap(m_lightBuffer, 0); + // Unlock the constant buffer. + deviceContext->Unmap(m_lightBuffer, 0); - // Set the position of the light constant buffer in the pixel shader. - bufferNumber = 0; + // Set the position of the light constant buffer in the pixel shader. + bufferNumber = 0; - // Finally set the light constant buffer in the pixel shader with the updated values. - deviceContext->PSSetConstantBuffers(bufferNumber, 1, &m_lightBuffer); + // Finally set the light constant buffer in the pixel shader with the updated values. + deviceContext->PSSetConstantBuffers(bufferNumber, 1, &m_lightBuffer); - return true; + return true; } void LightShaderClass::RenderShader(ID3D11DeviceContext* deviceContext, int indexCount) { - // Set the vertex input layout. - deviceContext->IASetInputLayout(m_layout); + // 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); + // Set the sampler state in the pixel shader. + deviceContext->PSSetSamplers(0, 1, &m_sampleState); - // Render the triangle. - deviceContext->DrawIndexed(indexCount, 0, 0); + // Render the triangle. + deviceContext->DrawIndexed(indexCount, 0, 0); - return; -} \ No newline at end of file + return; +} diff --git a/enginecustom/lightshaderclass.h b/enginecustom/lightshaderclass.h index 950bd93..6384900 100644 --- a/enginecustom/lightshaderclass.h +++ b/enginecustom/lightshaderclass.h @@ -22,12 +22,12 @@ using namespace std; class LightShaderClass { private: - struct MatrixBufferType - { - XMMATRIX world; - XMMATRIX view; - XMMATRIX projection; - }; + struct MatrixBufferType + { + XMMATRIX world; + XMMATRIX view; + XMMATRIX projection; + }; struct LightBufferType { @@ -38,29 +38,29 @@ private: }; public: - LightShaderClass(); - LightShaderClass(const LightShaderClass&); - ~LightShaderClass(); + LightShaderClass(); + LightShaderClass(const LightShaderClass&); + ~LightShaderClass(); bool Initialize(ID3D11Device*, HWND); void Shutdown(); bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4, XMFLOAT4); private: - bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*); - void ShutdownShader(); - void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*); + bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*); + void ShutdownShader(); + void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*); bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4, XMFLOAT4); void RenderShader(ID3D11DeviceContext*, int); private: - ID3D11VertexShader* m_vertexShader; - ID3D11PixelShader* m_pixelShader; - ID3D11InputLayout* m_layout; - ID3D11SamplerState* m_sampleState; - ID3D11Buffer* m_matrixBuffer; - ID3D11Buffer* m_lightBuffer; + ID3D11VertexShader* m_vertexShader; + ID3D11PixelShader* m_pixelShader; + ID3D11InputLayout* m_layout; + ID3D11SamplerState* m_sampleState; + ID3D11Buffer* m_matrixBuffer; + ID3D11Buffer* m_lightBuffer; }; #endif \ No newline at end of file diff --git a/enginecustom/modelclass.cpp b/enginecustom/modelclass.cpp index 1487a20..8cc6963 100644 --- a/enginecustom/modelclass.cpp +++ b/enginecustom/modelclass.cpp @@ -89,7 +89,7 @@ bool ModelClass::InitializeBuffers(ID3D11Device* device) D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc; D3D11_SUBRESOURCE_DATA vertexData, indexData; HRESULT result; - + int i; // Create the vertex array. vertices = new VertexType[m_vertexCount]; @@ -98,7 +98,7 @@ bool ModelClass::InitializeBuffers(ID3D11Device* device) indices = new unsigned long[m_indexCount]; // Load the vertex array and index array with data. - for (int i = 0; i < m_vertexCount; i++) + for (i = 0; i < m_vertexCount; i++) { vertices[i].position = XMFLOAT3(m_model[i].x, m_model[i].y, m_model[i].z); vertices[i].texture = XMFLOAT2(m_model[i].tu, m_model[i].tv); @@ -107,31 +107,6 @@ bool ModelClass::InitializeBuffers(ID3D11Device* device) indices[i] = i; } - - //// Create the vertex array. - //vertices = new VertexType[m_vertexCount]; - - //// Create the index array. - //indices = new unsigned long[m_indexCount]; - - //// Load the vertex array with data. - //vertices[0].position = XMFLOAT3(-1.0f, -1.0f, 0.0f); // Bottom left. - //vertices[0].texture = XMFLOAT2(0.0f, 1.0f); - //vertices[0].normal = XMFLOAT3(0.0f, 0.0f, -1.0f); - - //vertices[1].position = XMFLOAT3(0.0f, 1.0f, 0.0f); // Top middle. - //vertices[1].texture = XMFLOAT2(0.5f, 0.0f); - //vertices[1].normal = XMFLOAT3(0.0f, 0.0f, -1.0f); - - //vertices[2].position = XMFLOAT3(1.0f, -1.0f, 0.0f); // Bottom right. - //vertices[2].texture = XMFLOAT2(1.0f, 1.0f); - //vertices[2].normal = XMFLOAT3(0.0f, 0.0f, -1.0f); - - //// Load the index array with data. - //indices[0] = 0; // Bottom left. - //indices[1] = 1; // Top middle. - //indices[2] = 2; // Bottom right. - // Set up the description of the static vertex buffer. vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT; vertexBufferDesc.ByteWidth = sizeof(VertexType) * m_vertexCount; diff --git a/enginecustom/modelclass.h b/enginecustom/modelclass.h index b86693a..5c97330 100644 --- a/enginecustom/modelclass.h +++ b/enginecustom/modelclass.h @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include using namespace DirectX; using namespace std; @@ -38,6 +41,23 @@ private: float nx, ny, nz; }; + struct Vertex { + float x, y, z; + }; + + struct Texture { + float u, v; + }; + + struct Normal { + float nx, ny, nz; + }; + + struct Face { + int v1, v2, v3; + int t1, t2, t3; + int n1, n2, n3; + }; public: ModelClass(); diff --git a/enginecustom/sphere.mtl b/enginecustom/sphere.mtl new file mode 100644 index 0000000..6d43325 --- /dev/null +++ b/enginecustom/sphere.mtl @@ -0,0 +1,2 @@ +# Blender 4.0.1 MTL File: 'None' +# www.blender.org diff --git a/enginecustom/sprite01.tga b/enginecustom/sprite01.tga new file mode 100644 index 0000000..468a482 Binary files /dev/null and b/enginecustom/sprite01.tga differ diff --git a/enginecustom/sprite02.tga b/enginecustom/sprite02.tga new file mode 100644 index 0000000..f9fcfbb Binary files /dev/null and b/enginecustom/sprite02.tga differ diff --git a/enginecustom/sprite03.tga b/enginecustom/sprite03.tga new file mode 100644 index 0000000..df005e1 Binary files /dev/null and b/enginecustom/sprite03.tga differ diff --git a/enginecustom/sprite04.tga b/enginecustom/sprite04.tga new file mode 100644 index 0000000..01639e8 Binary files /dev/null and b/enginecustom/sprite04.tga differ diff --git a/enginecustom/sprite_data_01.txt b/enginecustom/sprite_data_01.txt new file mode 100644 index 0000000..fadc998 --- /dev/null +++ b/enginecustom/sprite_data_01.txt @@ -0,0 +1,6 @@ +4 +sprite01.tga +sprite02.tga +sprite03.tga +sprite04.tga +250 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..0d534ae --- /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; +} \ No newline at end of file diff --git a/enginecustom/textureshaderclass.cpp b/enginecustom/textureshaderclass.cpp new file mode 100644 index 0000000..6eed3c7 --- /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 diff --git a/enginecustom/wall.tga b/enginecustom/wall.tga new file mode 100644 index 0000000..f2267a5 Binary files /dev/null and b/enginecustom/wall.tga differ