diff --git a/enginecustom/Cameraclass.h b/enginecustom/Cameraclass.h index ae334c8..e1bb227 100644 --- a/enginecustom/Cameraclass.h +++ b/enginecustom/Cameraclass.h @@ -28,6 +28,7 @@ public: XMFLOAT3 GetPosition(); XMFLOAT3 GetRotation(); + void Render(); XMMATRIX GetViewMatrix(); diff --git a/enginecustom/applicationclass.cpp b/enginecustom/applicationclass.cpp index bf3f417..1fb9a93 100644 --- a/enginecustom/applicationclass.cpp +++ b/enginecustom/applicationclass.cpp @@ -6,7 +6,7 @@ ApplicationClass::ApplicationClass() m_Camera = 0; m_Model = 0; m_LightShader = 0; - m_Light = 0; + m_Lights = 0; } @@ -48,7 +48,7 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) } // Set the initial position of the camera. - m_Camera->SetPosition(0.0f, 0.0f, -10.0f); + m_Camera->SetPosition(0.0f, 2.0f, -12.0f); m_Camera->SetRotation(0.0f, 0.0f, 10.0f); // Set the file name of the model. @@ -76,6 +76,24 @@ 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; } + // Set the number of lights we will use. + m_numLights = 4; + + // Create and initialize the light objects array. + m_Lights = new LightClass[m_numLights]; + + // Manually set the color and position of each light. + m_Lights[0].SetDiffuseColor(1.0f, 0.0f, 0.0f, 1.0f); // Red + m_Lights[0].SetPosition(-3.0f, 1.0f, 3.0f); + + m_Lights[1].SetDiffuseColor(0.0f, 1.0f, 0.0f, 1.0f); // Green + m_Lights[1].SetPosition(3.0f, 1.0f, 3.0f); + + m_Lights[2].SetDiffuseColor(0.0f, 0.0f, 1.0f, 1.0f); // Blue + m_Lights[2].SetPosition(-3.0f, 1.0f, -3.0f); + + m_Lights[3].SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f); // White + m_Lights[3].SetPosition(3.0f, 1.0f, -3.0f); // Create and initialize the light object. m_Light = new LightClass; @@ -89,10 +107,10 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) void ApplicationClass::Shutdown() { // Release the light object. - if (m_Light) + if (m_Lights) { - delete m_Light; - m_Light = 0; + delete m_Lights; + m_Lights = 0; } // Release the light shader object. @@ -163,7 +181,9 @@ bool ApplicationClass::Frame() bool ApplicationClass::Render(float rotation) { - XMMATRIX worldMatrix, rotateMatrix, translateMatrix, scaleMatrix, srMatrix; + XMMATRIX worldMatrix, rotateMatrix, translateMatrix, scaleMatrix, srMatrix, viewMatrix, projectionMatrix;; + XMFLOAT4 diffuseColor[4], lightPosition[4]; + int i; bool result; @@ -175,6 +195,21 @@ bool ApplicationClass::Render(float rotation) // Get the world, view, and projection matrices from the camera and d3d objects. m_Direct3D->GetWorldMatrix(worldMatrix); + viewMatrix = m_Camera->GetViewMatrix(); + m_Direct3D->GetProjectionMatrix(projectionMatrix); + + // Get the light properties. + for (i = 0; i < m_numLights; i++) + { + // Create the diffuse color array from the four light colors. + diffuseColor[i] = m_Lights[i].GetDiffuseColor(); + + // Create the light position array from the four light positions. + lightPosition[i] = m_Lights[i].GetPosition(); + } + // Put the model vertex and index buffers on the graphics pipeline to prepare them for drawing. + m_Model->Render(m_Direct3D->GetDeviceContext()); + for (auto cube : m_cubes) { @@ -186,8 +221,8 @@ bool ApplicationClass::Render(float rotation) srMatrix = XMMatrixMultiply(scaleMatrix, rotateMatrix); worldMatrix = XMMatrixMultiply(srMatrix, translateMatrix); - result = m_LightShader->Render(m_Direct3D->GetDeviceContext(), cube->GetIndexCount(), worldMatrix, m_Camera->GetViewMatrix(), m_Direct3D->GetProjectionMatrix(), cube->GetTexture(), - m_Light->GetDirection(), m_Light->GetDiffuseColor()); + result = m_LightShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(), + diffuseColor, lightPosition); if (!result) { return false; diff --git a/enginecustom/applicationclass.h b/enginecustom/applicationclass.h index 8f837f6..1404d51 100644 --- a/enginecustom/applicationclass.h +++ b/enginecustom/applicationclass.h @@ -59,6 +59,8 @@ private: float speed = 0.1f; std::vector m_cubes; Object* m_SelectedObject; + LightClass* m_Lights; + int m_numLights; }; #endif diff --git a/enginecustom/d3dclass.cpp b/enginecustom/d3dclass.cpp index e0a1ff2..b7af78b 100644 --- a/enginecustom/d3dclass.cpp +++ b/enginecustom/d3dclass.cpp @@ -463,8 +463,9 @@ ID3D11DeviceContext* D3DClass::GetDeviceContext() } -XMMATRIX D3DClass::GetProjectionMatrix() +XMMATRIX D3DClass::GetProjectionMatrix(XMMATRIX& projectionMatrix) { + projectionMatrix = m_projectionMatrix; return m_projectionMatrix; } diff --git a/enginecustom/d3dclass.h b/enginecustom/d3dclass.h index 3aa278a..da6c73f 100644 --- a/enginecustom/d3dclass.h +++ b/enginecustom/d3dclass.h @@ -40,6 +40,7 @@ public: ID3D11Device* GetDevice(); ID3D11DeviceContext* GetDeviceContext(); + XMMATRIX GetProjectionMatrix(XMMATRIX& projectionMatrix); IDXGISwapChain* m_swapChain; IDXGISwapChain* GetSwapChain(); void ResizeSwapChain(int, int); diff --git a/enginecustom/imgui.ini b/enginecustom/imgui.ini index 48f8c8b..480aee3 100644 --- a/enginecustom/imgui.ini +++ b/enginecustom/imgui.ini @@ -3,10 +3,10 @@ Pos=60,60 Size=400,400 [Window][Khaotic Engine] -Pos=765,19 +Pos=500,27 Size=694,367 [Window][Objects] -Pos=44,57 -Size=492,353 +Pos=8,44 +Size=298,297 diff --git a/enginecustom/light.ps b/enginecustom/light.ps index 1a2da4e..d105334 100644 --- a/enginecustom/light.ps +++ b/enginecustom/light.ps @@ -3,17 +3,21 @@ //////////////////////////////////////////////////////////////////////////////// +///////////// +// DEFINES // +///////////// +#define NUM_LIGHTS 4 + + ///////////// // GLOBALS // ///////////// Texture2D shaderTexture : register(t0); SamplerState SampleType : register(s0); -cbuffer LightBuffer +cbuffer LightColorBuffer { - float4 diffuseColor; - float3 lightDirection; - float padding; + float4 diffuseColor[NUM_LIGHTS]; }; @@ -24,7 +28,8 @@ struct PixelInputType { float4 position : SV_POSITION; float2 tex : TEXCOORD0; - float3 normal : NORMAL; + float3 normal : NORMAL; + float3 lightPos[NUM_LIGHTS] : TEXCOORD1; }; @@ -34,28 +39,38 @@ struct PixelInputType float4 LightPixelShader(PixelInputType input) : SV_TARGET { float4 textureColor; - float3 lightDir; - float lightIntensity; - float4 color; + float lightIntensity[NUM_LIGHTS]; + float4 colorArray[NUM_LIGHTS]; + float4 colorSum; + float4 color; + int i; - // Sample the pixel color from the texture using the sampler at this texture coordinate location. - textureColor = shaderTexture.Sample(SampleType, input.tex); + // Sample the texture pixel at this location. + textureColor = shaderTexture.Sample(SampleType, input.tex); - // Invert the light direction for calculations. - lightDir = -lightDirection; + for(i=0; iCreateBuffer(&lightColorBufferDesc, NULL, &m_lightColorBuffer); + if (FAILED(result)) + { + return false; + } + // Setup the description of the dynamic constant buffer that is in the vertex shader. + lightPositionBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + lightPositionBufferDesc.ByteWidth = sizeof(LightPositionBufferType); + lightPositionBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + lightPositionBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + lightPositionBufferDesc.MiscFlags = 0; + lightPositionBufferDesc.StructureByteStride = 0; + + // Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class. + result = device->CreateBuffer(&lightPositionBufferDesc, NULL, &m_lightPositionBuffer); + 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. @@ -258,6 +291,18 @@ bool LightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR* void LightShaderClass::ShutdownShader() { + // Release the light constant buffers. + if (m_lightColorBuffer) + { + m_lightColorBuffer->Release(); + m_lightColorBuffer = 0; + } + + if (m_lightPositionBuffer) + { + m_lightPositionBuffer->Release(); + m_lightPositionBuffer = 0; + } // Release the light constant buffer. if(m_lightBuffer) { @@ -340,14 +385,15 @@ void LightShaderClass::OutputShaderErrorMessage(ID3D10Blob* errorMessage, HWND h } -bool LightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix, - ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 diffuseColor) +bool LightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix, + ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[]) { HRESULT result; - D3D11_MAPPED_SUBRESOURCE mappedResource; + D3D11_MAPPED_SUBRESOURCE mappedResource; unsigned int bufferNumber; MatrixBufferType* dataPtr; - LightBufferType* dataPtr2; + LightPositionBufferType* dataPtr2; + LightColorBufferType* dataPtr3; // Transpose the matrices to prepare them for the shader. @@ -357,7 +403,7 @@ bool LightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, X // 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)) + if (FAILED(result)) { return false; } @@ -371,40 +417,66 @@ bool LightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, X 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; // Now set the constant buffer in the vertex shader with the updated values. - deviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_matrixBuffer); + 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)) + // Lock the light position constant buffer so it can be written to. + result = deviceContext->Map(m_lightPositionBuffer, 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; + dataPtr2 = (LightPositionBufferType*)mappedResource.pData; - // Copy the lighting variables into the constant buffer. - dataPtr2->diffuseColor = diffuseColor; - dataPtr2->lightDirection = lightDirection; - dataPtr2->padding = 0.0f; + // Copy the light position variables into the constant buffer. + dataPtr2->lightPosition[0] = lightPosition[0]; + dataPtr2->lightPosition[1] = lightPosition[1]; + dataPtr2->lightPosition[2] = lightPosition[2]; + dataPtr2->lightPosition[3] = lightPosition[3]; // Unlock the constant buffer. - deviceContext->Unmap(m_lightBuffer, 0); + deviceContext->Unmap(m_lightPositionBuffer, 0); - // Set the position of the light constant buffer in the pixel shader. + // Set the position of the constant buffer in the vertex shader. + bufferNumber = 1; + + // Finally set the constant buffer in the vertex shader with the updated values. + deviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_lightPositionBuffer); + + // Set shader texture resource in the pixel shader. + deviceContext->PSSetShaderResources(0, 1, &texture); + + // Lock the light color constant buffer so it can be written to. + result = deviceContext->Map(m_lightColorBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return false; + } + + // Get a pointer to the data in the constant buffer. + dataPtr3 = (LightColorBufferType*)mappedResource.pData; + + // Copy the light color variables into the constant buffer. + dataPtr3->diffuseColor[0] = diffuseColor[0]; + dataPtr3->diffuseColor[1] = diffuseColor[1]; + dataPtr3->diffuseColor[2] = diffuseColor[2]; + dataPtr3->diffuseColor[3] = diffuseColor[3]; + + // Unlock the constant buffer. + deviceContext->Unmap(m_lightColorBuffer, 0); + + // Set the position of the 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 constant buffer in the pixel shader with the updated values. + deviceContext->PSSetConstantBuffers(bufferNumber, 1, &m_lightColorBuffer); return true; } diff --git a/enginecustom/lightshaderclass.h b/enginecustom/lightshaderclass.h index f16b097..0dd1925 100644 --- a/enginecustom/lightshaderclass.h +++ b/enginecustom/lightshaderclass.h @@ -4,6 +4,11 @@ #ifndef _LIGHTSHADERCLASS_H_ #define _LIGHTSHADERCLASS_H_ +///////////// +// GLOBALS // +///////////// +const int NUM_LIGHTS = 4; + ////////////// // INCLUDES // @@ -28,6 +33,16 @@ private: XMMATRIX view; XMMATRIX projection; }; + struct LightColorBufferType + { + XMFLOAT4 diffuseColor[NUM_LIGHTS]; + }; + + struct LightPositionBufferType + { + XMFLOAT4 lightPosition[NUM_LIGHTS]; + }; + struct LightBufferType { @@ -43,14 +58,15 @@ public: bool Initialize(ID3D11Device*, HWND); void Shutdown(); - bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4); + bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4[], XMFLOAT4[]); + private: bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*); void ShutdownShader(); void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*); - bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4); + bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4[], XMFLOAT4[]); void RenderShader(ID3D11DeviceContext*, int); private: @@ -60,6 +76,9 @@ private: ID3D11SamplerState* m_sampleState; ID3D11Buffer* m_matrixBuffer; ID3D11Buffer* m_lightBuffer; + + ID3D11Buffer* m_lightColorBuffer; + ID3D11Buffer* m_lightPositionBuffer; }; #endif \ No newline at end of file diff --git a/enginecustom/shader-error.txt b/enginecustom/shader-error.txt new file mode 100644 index 0000000..4c786cf Binary files /dev/null and b/enginecustom/shader-error.txt differ