From 5c9ee0180f6d436c5b676f21202e2b27837caff0 Mon Sep 17 00:00:00 2001 From: Mamitiana RASOLOJAONA Date: Fri, 22 Mar 2024 15:48:47 +0100 Subject: [PATCH] diffuse light --- enginecustom/applicationclass.cpp | 57 +++-- enginecustom/applicationclass.h | 10 +- enginecustom/enginecustom.vcxproj | 10 +- enginecustom/enginecustom.vcxproj.filters | 18 +- enginecustom/light.ps | 61 +++++ enginecustom/light.vs | 61 +++++ enginecustom/lightclass.cpp | 45 ++++ enginecustom/lightclass.h | 36 +++ ...reshaderclass.cpp => lightshaderclass.cpp} | 242 ++++++++++++------ ...extureshaderclass.h => lightshaderclass.h} | 31 ++- enginecustom/modelclass.cpp | 25 +- enginecustom/modelclass.h | 1 + enginecustom/texture.ps | 28 -- enginecustom/texture.vs | 47 ---- 14 files changed, 453 insertions(+), 219 deletions(-) create mode 100644 enginecustom/light.ps create mode 100644 enginecustom/light.vs create mode 100644 enginecustom/lightclass.cpp create mode 100644 enginecustom/lightclass.h rename enginecustom/{textureshaderclass.cpp => lightshaderclass.cpp} (50%) rename enginecustom/{textureshaderclass.h => lightshaderclass.h} (58%) delete mode 100644 enginecustom/texture.ps delete mode 100644 enginecustom/texture.vs diff --git a/enginecustom/applicationclass.cpp b/enginecustom/applicationclass.cpp index f953417..1b79d08 100644 --- a/enginecustom/applicationclass.cpp +++ b/enginecustom/applicationclass.cpp @@ -5,7 +5,8 @@ ApplicationClass::ApplicationClass() m_Direct3D = 0; m_Camera = 0; m_Model = 0; - m_TextureShader = 0; + m_LightShader = 0; + m_Light = 0; } @@ -49,7 +50,7 @@ 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, 0.0f); + m_Camera->SetRotation(0.0f, 0.0f, 10.0f); // Create and initialize the model object. m_Model = new ModelClass; @@ -62,15 +63,21 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) MessageBox(hwnd, L"Could not initialize the model object.", L"Error", MB_OK); return false; } - // Create and initialize the texture shader object. - m_TextureShader = new TextureShaderClass; - result = m_TextureShader->Initialize(m_Direct3D->GetDevice(), hwnd); + // Create and initialize the light shader object. + m_LightShader = new LightShaderClass; + + result = m_LightShader->Initialize(m_Direct3D->GetDevice(), hwnd); if (!result) { - MessageBox(hwnd, L"Could not initialize the texture shader object.", L"Error", MB_OK); + 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; + + m_Light->SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f); + m_Light->SetDirection(0.0f, 0.0f, 1.0f); return true; } @@ -78,12 +85,19 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) void ApplicationClass::Shutdown() { - // Release the texture shader object. - if (m_TextureShader) + // Release the light object. + if (m_Light) { - m_TextureShader->Shutdown(); - delete m_TextureShader; - m_TextureShader = 0; + delete m_Light; + m_Light = 0; + } + + // Release the light shader object. + if (m_LightShader) + { + m_LightShader->Shutdown(); + delete m_LightShader; + m_LightShader = 0; } // Release the model object. @@ -115,11 +129,19 @@ void ApplicationClass::Shutdown() bool ApplicationClass::Frame() { + static float rotation = 0.0f; bool result; + // Update the rotation variable each frame. + rotation -= 0.0174532925f * 0.1f; + if (rotation < 0.0f) + { + rotation += 360.0f; + } + // Render the graphics scene. - result = Render(); + result = Render(rotation); if (!result) { return false; @@ -129,7 +151,7 @@ bool ApplicationClass::Frame() } -bool ApplicationClass::Render() +bool ApplicationClass::Render(float rotation) { XMMATRIX worldMatrix, viewMatrix, projectionMatrix; bool result; @@ -145,16 +167,19 @@ bool ApplicationClass::Render() 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); // 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 texture shader. - result = m_TextureShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture()); + + // Render the model using the light shader. + result = m_LightShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(), + m_Light->GetDirection(), m_Light->GetDiffuseColor()); if (!result) { return false; } - // Present the rendered scene to the screen. m_Direct3D->EndScene(); diff --git a/enginecustom/applicationclass.h b/enginecustom/applicationclass.h index b0bf8f3..dbd6973 100644 --- a/enginecustom/applicationclass.h +++ b/enginecustom/applicationclass.h @@ -8,9 +8,8 @@ #include "d3dclass.h" #include "cameraclass.h" #include "modelclass.h" - -#include "textureshaderclass.h" - +#include "lightshaderclass.h" +#include "lightclass.h" ///////////// // GLOBALS // @@ -36,13 +35,14 @@ public: bool Frame(); private: - bool Render(); + bool Render(float); private: D3DClass* m_Direct3D; CameraClass* m_Camera; ModelClass* m_Model; - TextureShaderClass* m_TextureShader; + LightShaderClass* m_LightShader; + LightClass* m_Light; }; #endif diff --git a/enginecustom/enginecustom.vcxproj b/enginecustom/enginecustom.vcxproj index ba1ba40..a503734 100644 --- a/enginecustom/enginecustom.vcxproj +++ b/enginecustom/enginecustom.vcxproj @@ -25,27 +25,29 @@ + + - + + - + + - - diff --git a/enginecustom/enginecustom.vcxproj.filters b/enginecustom/enginecustom.vcxproj.filters index cc96857..6236202 100644 --- a/enginecustom/enginecustom.vcxproj.filters +++ b/enginecustom/enginecustom.vcxproj.filters @@ -48,10 +48,13 @@ Fichiers sources - + Fichiers sources - + + Fichiers sources + + Fichiers sources @@ -77,10 +80,13 @@ Fichiers d%27en-tête - + Fichiers d%27en-tête - + + Fichiers d%27en-tête + + Fichiers d%27en-tête @@ -92,10 +98,10 @@ shader - + texture - + texture diff --git a/enginecustom/light.ps b/enginecustom/light.ps new file mode 100644 index 0000000..1a2da4e --- /dev/null +++ b/enginecustom/light.ps @@ -0,0 +1,61 @@ +//////////////////////////////////////////////////////////////////////////////// +// 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)); + + // Change the diffuse color to red (0, 1, 0) + float3 greenDiffuseColor = float3(1, 0, 0); + + // 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; +} diff --git a/enginecustom/light.vs b/enginecustom/light.vs new file mode 100644 index 0000000..075270b --- /dev/null +++ b/enginecustom/light.vs @@ -0,0 +1,61 @@ +//////////////////////////////////////////////////////////////////////////////// +// 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..05dcb4c --- /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..d4c5273 --- /dev/null +++ b/enginecustom/lightclass.h @@ -0,0 +1,36 @@ +//////////////////////////////////////////////////////////////////////////////// +// 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 SetDiffuseColor(float, float, float, float); + void SetDirection(float, float, float); + + XMFLOAT4 GetDiffuseColor(); + XMFLOAT3 GetDirection(); + +private: + XMFLOAT4 m_diffuseColor; + XMFLOAT3 m_direction; +}; + +#endif \ No newline at end of file diff --git a/enginecustom/textureshaderclass.cpp b/enginecustom/lightshaderclass.cpp similarity index 50% rename from enginecustom/textureshaderclass.cpp rename to enginecustom/lightshaderclass.cpp index b28fed9..02df0ff 100644 --- a/enginecustom/textureshaderclass.cpp +++ b/enginecustom/lightshaderclass.cpp @@ -1,41 +1,47 @@ -#include "textureshaderclass.h" +//////////////////////////////////////////////////////////////////////////////// +// Filename: lightshaderclass.cpp +//////////////////////////////////////////////////////////////////////////////// +#include "lightshaderclass.h" -TextureShaderClass::TextureShaderClass() +LightShaderClass::LightShaderClass() { m_vertexShader = 0; m_pixelShader = 0; m_layout = 0; - m_matrixBuffer = 0; m_sampleState = 0; + m_matrixBuffer = 0; + m_lightBuffer = 0; } -TextureShaderClass::TextureShaderClass(const TextureShaderClass& other) +LightShaderClass::LightShaderClass(const LightShaderClass& other) { } -TextureShaderClass::~TextureShaderClass() +LightShaderClass::~LightShaderClass() { } -bool TextureShaderClass::Initialize(ID3D11Device* device, HWND hwnd) +bool LightShaderClass::Initialize(ID3D11Device* device, HWND hwnd) { - 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"texture.vs"); + error = wcscpy_s(vsFilename, 128, L"../enginecustom/light.vs"); if (error != 0) { return false; } // Set the filename of the pixel shader. - error = wcscpy_s(psFilename, 128, L"texture.ps"); + error = wcscpy_s(psFilename, 128, L"../enginecustom/light.ps"); if (error != 0) { return false; @@ -43,7 +49,7 @@ bool TextureShaderClass::Initialize(ID3D11Device* device, HWND hwnd) // Initialize the vertex and pixel shaders. result = InitializeShader(device, hwnd, vsFilename, psFilename); - if (!result) + if(!result) { return false; } @@ -51,7 +57,8 @@ bool TextureShaderClass::Initialize(ID3D11Device* device, HWND hwnd) return true; } -void TextureShaderClass::Shutdown() + +void LightShaderClass::Shutdown() { // Shutdown the vertex and pixel shaders as well as the related objects. ShutdownShader(); @@ -59,15 +66,16 @@ void TextureShaderClass::Shutdown() return; } -bool TextureShaderClass::Render(ID3D11DeviceContext * deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, - XMMATRIX projectionMatrix, ID3D11ShaderResourceView * texture) + +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); - if (!result) + result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, lightDirection, diffuseColor); + if(!result) { return false; } @@ -78,29 +86,31 @@ bool TextureShaderClass::Render(ID3D11DeviceContext * deviceContext, int indexCo return true; } -bool TextureShaderClass::InitializeShader(ID3D11Device * device, HWND hwnd, WCHAR * vsFilename, WCHAR * psFilename) + +bool LightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR* vsFilename, WCHAR* psFilename) { HRESULT result; ID3D10Blob* errorMessage; ID3D10Blob* vertexShaderBuffer; ID3D10Blob* pixelShaderBuffer; - D3D11_INPUT_ELEMENT_DESC polygonLayout[2]; + D3D11_INPUT_ELEMENT_DESC polygonLayout[3]; unsigned int numElements; + D3D11_SAMPLER_DESC samplerDesc; D3D11_BUFFER_DESC matrixBufferDesc; - D3D11_SAMPLER_DESC samplerDesc; + 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, "TextureVertexShader", "vs_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, - &vertexShaderBuffer, &errorMessage); - if (FAILED(result)) + + // 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) + if(errorMessage) { OutputShaderErrorMessage(errorMessage, hwnd, vsFilename); } @@ -113,13 +123,12 @@ bool TextureShaderClass::InitializeShader(ID3D11Device * device, HWND hwnd, WCHA 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)) + // 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) + if(errorMessage) { OutputShaderErrorMessage(errorMessage, hwnd, psFilename); } @@ -132,19 +141,20 @@ bool TextureShaderClass::InitializeShader(ID3D11Device * device, HWND hwnd, WCHA return false; } - // Create the vertex shader from the buffer. - result = device->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &m_vertexShader); - if (FAILED(result)) + // 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)) + // 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"; @@ -163,13 +173,21 @@ bool TextureShaderClass::InitializeShader(ID3D11Device * device, HWND hwnd, WCHA 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]); + 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)) + result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), + &m_layout); + if(FAILED(result)) { return false; } @@ -181,38 +199,55 @@ bool TextureShaderClass::InitializeShader(ID3D11Device * device, HWND hwnd, WCHA 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.Usage = D3D11_USAGE_DYNAMIC; matrixBufferDesc.ByteWidth = sizeof(MatrixBufferType); - matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - matrixBufferDesc.MiscFlags = 0; + 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)) + 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)) + // 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; } @@ -220,39 +255,46 @@ bool TextureShaderClass::InitializeShader(ID3D11Device * device, HWND hwnd, WCHA return true; } -void TextureShaderClass::ShutdownShader() -{ - // Release the sampler state. - if (m_sampleState) +void LightShaderClass::ShutdownShader() +{ + // Release the light constant buffer. + if(m_lightBuffer) { - m_sampleState->Release(); - m_sampleState = 0; + m_lightBuffer->Release(); + m_lightBuffer = 0; } // Release the matrix constant buffer. - if (m_matrixBuffer) + 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) + if(m_layout) { m_layout->Release(); m_layout = 0; } // Release the pixel shader. - if (m_pixelShader) + if(m_pixelShader) { m_pixelShader->Release(); m_pixelShader = 0; } // Release the vertex shader. - if (m_vertexShader) + if(m_vertexShader) { m_vertexShader->Release(); m_vertexShader = 0; @@ -261,10 +303,11 @@ void TextureShaderClass::ShutdownShader() return; } -void TextureShaderClass::OutputShaderErrorMessage(ID3D10Blob * errorMessage, HWND hwnd, WCHAR * shaderFilename) + +void LightShaderClass::OutputShaderErrorMessage(ID3D10Blob* errorMessage, HWND hwnd, WCHAR* shaderFilename) { char* compileErrors; - unsigned long long bufferSize, i; + unsigned __int64 bufferSize, i; ofstream fout; @@ -278,7 +321,7 @@ void TextureShaderClass::OutputShaderErrorMessage(ID3D10Blob * errorMessage, HWN fout.open("shader-error.txt"); // Write out the error message. - for (i = 0; i < bufferSize; i++) + for(i=0; iMap(m_matrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(result)) + if(FAILED(result)) { return false; } @@ -326,27 +371,54 @@ bool TextureShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, dataPtr->projection = projectionMatrix; // Unlock the constant buffer. - deviceContext->Unmap(m_matrixBuffer, 0); + 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); + // 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 TextureShaderClass::RenderShader(ID3D11DeviceContext * deviceContext, int indexCount) + +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 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); diff --git a/enginecustom/textureshaderclass.h b/enginecustom/lightshaderclass.h similarity index 58% rename from enginecustom/textureshaderclass.h rename to enginecustom/lightshaderclass.h index 6c88f59..f16b097 100644 --- a/enginecustom/textureshaderclass.h +++ b/enginecustom/lightshaderclass.h @@ -1,5 +1,8 @@ -#ifndef _TEXTURESHADERCLASS_H_ -#define _TEXTURESHADERCLASS_H_ +//////////////////////////////////////////////////////////////////////////////// +// Filename: lightshaderclass.h +//////////////////////////////////////////////////////////////////////////////// +#ifndef _LIGHTSHADERCLASS_H_ +#define _LIGHTSHADERCLASS_H_ ////////////// @@ -14,9 +17,9 @@ using namespace std; //////////////////////////////////////////////////////////////////////////////// -// Class name: TextureShaderClass +// Class name: LightShaderClass //////////////////////////////////////////////////////////////////////////////// -class TextureShaderClass +class LightShaderClass { private: struct MatrixBufferType @@ -26,29 +29,37 @@ private: 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: - TextureShaderClass(); - TextureShaderClass(const TextureShaderClass&); - ~TextureShaderClass(); + LightShaderClass(); + LightShaderClass(const LightShaderClass&); + ~LightShaderClass(); bool Initialize(ID3D11Device*, HWND); void Shutdown(); - bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*); + 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*); + bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4); void RenderShader(ID3D11DeviceContext*, int); private: ID3D11VertexShader* m_vertexShader; ID3D11PixelShader* m_pixelShader; ID3D11InputLayout* m_layout; - ID3D11Buffer* m_matrixBuffer; 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 d74d099..2c0cee4 100644 --- a/enginecustom/modelclass.cpp +++ b/enginecustom/modelclass.cpp @@ -94,33 +94,22 @@ bool ModelClass::InitializeBuffers(ID3D11Device* device) indices = new unsigned long[m_indexCount]; // Load the vertex array with data. - // Triangle 1 - vertices[0].position = XMFLOAT3(-1.0f, -1.0f, 0.0f); // Bottom Left. + 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(1.0f, 1.0f, 0.0f); // Top Right. - vertices[1].texture = XMFLOAT2(1.0f, 0.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].position = XMFLOAT3(1.0f, -1.0f, 0.0f); // Bottom right. vertices[2].texture = XMFLOAT2(1.0f, 1.0f); - - // Triangle 2 - vertices[3].position = XMFLOAT3(-1.0f, 1.0f, 0.0f); // Top Left. - vertices[3].texture = XMFLOAT2(0.0f, 0.0f); - - vertices[4].position = XMFLOAT3(1.0f, 1.0f, 0.0f); // Top Right. - vertices[4].texture = XMFLOAT2(1.0f, 0.0f); - - vertices[5].position = XMFLOAT3(-1.0f, -1.0f, 0.0f); // Bottom Left. - vertices[5].texture = XMFLOAT2(0.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. - indices[3] = 3; // Top left. - indices[4] = 4; // Top right. - indices[5] = 5; // Bottom left. // Set up the description of the static vertex buffer. vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT; diff --git a/enginecustom/modelclass.h b/enginecustom/modelclass.h index aee6989..d570397 100644 --- a/enginecustom/modelclass.h +++ b/enginecustom/modelclass.h @@ -26,6 +26,7 @@ private: { XMFLOAT3 position; XMFLOAT2 texture; + XMFLOAT3 normal; }; public: diff --git a/enginecustom/texture.ps b/enginecustom/texture.ps deleted file mode 100644 index 192f1fc..0000000 --- a/enginecustom/texture.ps +++ /dev/null @@ -1,28 +0,0 @@ -///////////// -// 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 deleted file mode 100644 index 41f1ab9..0000000 --- a/enginecustom/texture.vs +++ /dev/null @@ -1,47 +0,0 @@ -///////////// -// 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; -}