Multiple point lights

This commit is contained in:
StratiX0 2024-03-28 10:56:57 +01:00
parent 16db21608a
commit e5c88797b0
17 changed files with 4143 additions and 208 deletions

View File

@ -2,6 +2,10 @@
// Filename: light.ps // Filename: light.ps
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/////////////
// DEFINES //
/////////////
#define NUM_LIGHTS 4
///////////// /////////////
// GLOBALS // // GLOBALS //
@ -11,13 +15,17 @@ SamplerState SampleType : register(s0);
cbuffer LightBuffer cbuffer LightBuffer
{ {
float4 ambientColor; float4 ambientColor;
float4 diffuseColor;
float3 lightDirection; float3 lightDirection;
float padding; float padding;
float specularPower; float specularPower;
float4 specularColor; float4 specularColor;
}; };
cbuffer LightColorBuffer
{
float4 diffuseColor[NUM_LIGHTS];
};
////////////// //////////////
// TYPEDEFS // // TYPEDEFS //
@ -27,7 +35,7 @@ struct PixelInputType
float4 position : SV_POSITION; float4 position : SV_POSITION;
float2 tex : TEXCOORD0; float2 tex : TEXCOORD0;
float3 normal : NORMAL; float3 normal : NORMAL;
float3 viewDirection : TEXCOORD1; float3 lightPos[NUM_LIGHTS] : TEXCOORD1;
}; };
@ -38,48 +46,39 @@ float4 LightPixelShader(PixelInputType input) : SV_TARGET
{ {
float4 textureColor; float4 textureColor;
float3 lightDir; float3 lightDir;
float lightIntensity;
float4 color; float4 color;
float3 reflection; float3 reflection;
float4 specular; float4 specular;
float lightIntensity[NUM_LIGHTS];
float4 colorArray[NUM_LIGHTS];
float4 colorSum;
int i;
// Sample the pixel color from the texture using the sampler at this texture coordinate location. // Sample the pixel color from the texture using the sampler at this texture coordinate location.
textureColor = shaderTexture.Sample(SampleType, input.tex); textureColor = shaderTexture.Sample(SampleType, input.tex);
// Set the default output color to the ambient light value for all pixels. for(i=0; i<NUM_LIGHTS; i++)
color = ambientColor;
// Initialize the specular color.
specular = float4(0.0f, 0.0f, 0.0f, 0.0f);
// Invert the light direction for calculations.
lightDir = -lightDirection;
// Calculate the amount of light on this pixel.
lightIntensity = saturate(dot(input.normal, lightDir));
if(lightIntensity > 0.0f)
{ {
// Determine the final diffuse color based on the diffuse color and the amount of light intensity. // Calculate the different amounts of light on this pixel based on the positions of the lights.
color += (diffuseColor * lightIntensity); lightIntensity[i] = saturate(dot(input.normal, input.lightPos[i]));
// Saturate the ambient and diffuse color. // Determine the diffuse color amount of each of the four lights.
color = saturate(color); colorArray[i] = diffuseColor[i] * lightIntensity[i];
}
// Calculate the reflection vector based on the light intensity, normal vector, and light direction. // Initialize the sum of colors.
reflection = normalize(2.0f * lightIntensity * input.normal - lightDir); colorSum = float4(0.0f, 0.0f, 0.0f, 1.0f);
// Determine the amount of specular light based on the reflection vector, viewing direction, and specular power. // Add all of the light colors up.
specular = pow(saturate(dot(reflection, input.viewDirection)), specularPower); for(i=0; i<NUM_LIGHTS; i++)
{
colorSum.r += colorArray[i].r;
colorSum.g += colorArray[i].g;
colorSum.b += colorArray[i].b;
} }
// Multiply the texture pixel and the final diffuse color to get the final pixel color result. // Multiply the texture pixel by the combination of all four light colors to get the final result.
color = color * textureColor; color = saturate(colorSum) * textureColor;
// Add the specular component last to the output color.
color = saturate(color + specular);
return color; return color;
} }

View File

@ -2,6 +2,10 @@
// Filename: light.vs // Filename: light.vs
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/////////////
// DEFINES //
/////////////
#define NUM_LIGHTS 4
///////////// /////////////
// GLOBALS // // GLOBALS //
@ -19,6 +23,11 @@ cbuffer CameraBuffer
float padding; float padding;
}; };
cbuffer LightPositionBuffer
{
float4 lightPosition[NUM_LIGHTS];
};
////////////// //////////////
// TYPEDEFS // // TYPEDEFS //
////////////// //////////////
@ -34,7 +43,7 @@ struct PixelInputType
float4 position : SV_POSITION; float4 position : SV_POSITION;
float2 tex : TEXCOORD0; float2 tex : TEXCOORD0;
float3 normal : NORMAL; float3 normal : NORMAL;
float3 viewDirection : TEXCOORD1; float3 lightPos[NUM_LIGHTS] : TEXCOORD1;
}; };
@ -45,7 +54,7 @@ PixelInputType LightVertexShader(VertexInputType input)
{ {
PixelInputType output; PixelInputType output;
float4 worldPosition; float4 worldPosition;
int i;
// Change the position vector to be 4 units for proper matrix calculations. // Change the position vector to be 4 units for proper matrix calculations.
input.position.w = 1.0f; input.position.w = 1.0f;
@ -67,11 +76,14 @@ PixelInputType LightVertexShader(VertexInputType input)
// Calculate the position of the vertex in the world. // Calculate the position of the vertex in the world.
worldPosition = mul(input.position, worldMatrix); worldPosition = mul(input.position, worldMatrix);
// Determine the viewing direction based on the position of the camera and the position of the vertex in the world. for(i=0; i<NUM_LIGHTS; i++)
output.viewDirection = cameraPosition.xyz - worldPosition.xyz; {
// Determine the light positions based on the position of the lights and the position of the vertex in the world.
// Normalize the viewing direction vector. output.lightPos[i] = lightPosition[i].xyz - worldPosition.xyz;
output.viewDirection = normalize(output.viewDirection);
// Normalize the light position vectors.
output.lightPos[i] = normalize(output.lightPos[i]);
}
return output; return output;
} }

View File

@ -52,6 +52,12 @@ void LightClass::SetSpecularPower(float power)
return; return;
} }
void LightClass::SetPosition(float x, float y, float z)
{
m_position = XMFLOAT4(x, y, z, 1.0f);
return;
}
XMFLOAT4 LightClass::GetAmbientColor() XMFLOAT4 LightClass::GetAmbientColor()
{ {
return m_ambientColor; return m_ambientColor;
@ -77,4 +83,9 @@ XMFLOAT4 LightClass::GetSpecularColor()
float LightClass::GetSpecularPower() float LightClass::GetSpecularPower()
{ {
return m_specularPower; return m_specularPower;
} }
XMFLOAT4 LightClass::GetPosition()
{
return m_position;
}

View File

@ -28,12 +28,14 @@ public:
void SetDirection(float, float, float); void SetDirection(float, float, float);
void SetSpecularColor(float, float, float, float); void SetSpecularColor(float, float, float, float);
void SetSpecularPower(float); void SetSpecularPower(float);
void SetPosition(float, float, float);
XMFLOAT4 GetAmbientColor(); XMFLOAT4 GetAmbientColor();
XMFLOAT4 GetDiffuseColor(); XMFLOAT4 GetDiffuseColor();
XMFLOAT3 GetDirection(); XMFLOAT3 GetDirection();
XMFLOAT4 GetSpecularColor(); XMFLOAT4 GetSpecularColor();
float GetSpecularPower(); float GetSpecularPower();
XMFLOAT4 GetPosition();
private: private:
XMFLOAT4 m_ambientColor; XMFLOAT4 m_ambientColor;
@ -41,6 +43,7 @@ private:
XMFLOAT3 m_direction; XMFLOAT3 m_direction;
XMFLOAT4 m_specularColor; XMFLOAT4 m_specularColor;
float m_specularPower; float m_specularPower;
XMFLOAT4 m_position;
}; };
#endif #endif

View File

@ -13,6 +13,8 @@ LightShaderClass::LightShaderClass()
m_matrixBuffer = 0; m_matrixBuffer = 0;
m_cameraBuffer = 0; m_cameraBuffer = 0;
m_lightBuffer = 0; m_lightBuffer = 0;
m_lightColorBuffer = 0;
m_lightPositionBuffer = 0;
} }
@ -66,15 +68,13 @@ void LightShaderClass::Shutdown()
} }
bool LightShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix, bool LightShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 ambientColor, XMFLOAT4 diffuseColor, ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[])
XMFLOAT3 cameraPosition, XMFLOAT4 specularColor, float specularPower)
{ {
bool result; bool result;
// Set the shader parameters that it will use for rendering. // Set the shader parameters that it will use for rendering.
result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, lightDirection, ambientColor, diffuseColor, result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, diffuseColor, lightPosition);
cameraPosition, specularColor, specularPower);
if(!result) if(!result)
{ {
return false; return false;
@ -98,7 +98,8 @@ bool LightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR*
D3D11_SAMPLER_DESC samplerDesc; D3D11_SAMPLER_DESC samplerDesc;
D3D11_BUFFER_DESC matrixBufferDesc; D3D11_BUFFER_DESC matrixBufferDesc;
D3D11_BUFFER_DESC cameraBufferDesc; D3D11_BUFFER_DESC cameraBufferDesc;
D3D11_BUFFER_DESC lightBufferDesc; D3D11_BUFFER_DESC lightColorBufferDesc;
D3D11_BUFFER_DESC lightPositionBufferDesc;
// Initialize the pointers this function will use to null. // Initialize the pointers this function will use to null.
@ -237,6 +238,8 @@ bool LightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR*
return false; return false;
} }
// Setup the description of the camera dynamic constant buffer that is in the vertex shader. // Setup the description of the camera dynamic constant buffer that is in the vertex shader.
cameraBufferDesc.Usage = D3D11_USAGE_DYNAMIC; cameraBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
cameraBufferDesc.ByteWidth = sizeof(CameraBufferType); cameraBufferDesc.ByteWidth = sizeof(CameraBufferType);
@ -252,17 +255,31 @@ bool LightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR*
return false; return false;
} }
// Setup the description of the light dynamic constant buffer that is in the pixel shader. // Setup the description of the 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. lightColorBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
lightBufferDesc.Usage = D3D11_USAGE_DYNAMIC; lightColorBufferDesc.ByteWidth = sizeof(LightColorBufferType);
lightBufferDesc.ByteWidth = sizeof(LightBufferType) + 12 ; lightColorBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
lightBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; lightColorBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
lightBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; lightColorBufferDesc.MiscFlags = 0;
lightBufferDesc.MiscFlags = 0; lightColorBufferDesc.StructureByteStride = 0;
lightBufferDesc.StructureByteStride = 0;
// Create the constant buffer pointer so we can access the pixel shader constant buffer from within this class.
result = device->CreateBuffer(&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. // 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); result = device->CreateBuffer(&lightPositionBufferDesc, NULL, &m_lightPositionBuffer);
if (FAILED(result)) if (FAILED(result))
{ {
return false; return false;
@ -274,6 +291,19 @@ bool LightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR*
void LightShaderClass::ShutdownShader() 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. // Release the light constant buffer.
if (m_lightBuffer) if (m_lightBuffer)
{ {
@ -364,15 +394,14 @@ void LightShaderClass::OutputShaderErrorMessage(ID3D10Blob* errorMessage, HWND h
bool LightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix, bool LightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 ambientColor, XMFLOAT4 diffuseColor, ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[])
XMFLOAT3 cameraPosition, XMFLOAT4 specularColor, float specularPower)
{ {
HRESULT result; HRESULT result;
D3D11_MAPPED_SUBRESOURCE mappedResource; D3D11_MAPPED_SUBRESOURCE mappedResource;
unsigned int bufferNumber; unsigned int bufferNumber;
MatrixBufferType* dataPtr; MatrixBufferType* dataPtr;
LightBufferType* dataPtr2; LightPositionBufferType* dataPtr2;
CameraBufferType* dataPtr3; LightColorBufferType* dataPtr3;
// Transpose the matrices to prepare them for the shader. // Transpose the matrices to prepare them for the shader.
worldMatrix = XMMatrixTranspose(worldMatrix); worldMatrix = XMMatrixTranspose(worldMatrix);
@ -410,51 +439,59 @@ bool LightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, X
return false; return false;
} }
// Get a pointer to the data in the constant buffer. // Lock the light position constant buffer so it can be written to.
dataPtr3 = (CameraBufferType*)mappedResource.pData; result = deviceContext->Map(m_lightPositionBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
// Copy the camera position into the constant buffer.
dataPtr3->cameraPosition = cameraPosition;
dataPtr3->padding = 0.0f;
// Unlock the camera constant buffer.
deviceContext->Unmap(m_cameraBuffer, 0);
// Set the position of the camera constant buffer in the vertex shader.
bufferNumber = 1;
// Now set the camera constant buffer in the vertex shader with the updated values.
deviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_cameraBuffer);
// 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)) if (FAILED(result))
{ {
return false; return false;
} }
// Get a pointer to the data in the constant buffer. // 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. // Copy the light position variables into the constant buffer.
dataPtr2->ambientColor = ambientColor; dataPtr2->lightPosition[0] = lightPosition[0];
dataPtr2->diffuseColor = diffuseColor; dataPtr2->lightPosition[1] = lightPosition[1];
dataPtr2->lightDirection = lightDirection; dataPtr2->lightPosition[2] = lightPosition[2];
dataPtr2->specularColor = specularColor; dataPtr2->lightPosition[3] = lightPosition[3];
dataPtr2->specularPower = specularPower;
//dataPtr2->padding = 0.0f;
// Unlock the constant buffer. // 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; bufferNumber = 0;
// Finally set the light constant buffer in the pixel shader with the updated values. // Finally set the constant buffer in the pixel shader with the updated values.
deviceContext->PSSetConstantBuffers(bufferNumber, 1, &m_lightBuffer); deviceContext->PSSetConstantBuffers(bufferNumber, 1, &m_lightColorBuffer);
return true; return true;
} }

View File

@ -5,6 +5,11 @@
#define _LIGHTSHADERCLASS_H_ #define _LIGHTSHADERCLASS_H_
/////////////
// GLOBALS //
/////////////
const int NUM_LIGHTS = 4;
////////////// //////////////
// INCLUDES // // INCLUDES //
////////////// //////////////
@ -45,6 +50,16 @@ private:
XMFLOAT4 specularColor; XMFLOAT4 specularColor;
}; };
struct LightColorBufferType
{
XMFLOAT4 diffuseColor[NUM_LIGHTS];
};
struct LightPositionBufferType
{
XMFLOAT4 lightPosition[NUM_LIGHTS];
};
public: public:
LightShaderClass(); LightShaderClass();
LightShaderClass(const LightShaderClass&); LightShaderClass(const LightShaderClass&);
@ -52,14 +67,14 @@ public:
bool Initialize(ID3D11Device*, HWND); bool Initialize(ID3D11Device*, HWND);
void Shutdown(); void Shutdown();
bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4, XMFLOAT4, XMFLOAT3, XMFLOAT4, float); bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4[], XMFLOAT4[]);
private: private:
bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*); bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*);
void ShutdownShader(); void ShutdownShader();
void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*); void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*);
bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4, XMFLOAT4, XMFLOAT3, XMFLOAT4, float); bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4[], XMFLOAT4[]);
void RenderShader(ID3D11DeviceContext*, int); void RenderShader(ID3D11DeviceContext*, int);
private: private:
@ -70,6 +85,8 @@ private:
ID3D11Buffer* m_matrixBuffer; ID3D11Buffer* m_matrixBuffer;
ID3D11Buffer* m_cameraBuffer; ID3D11Buffer* m_cameraBuffer;
ID3D11Buffer* m_lightBuffer; ID3D11Buffer* m_lightBuffer;
ID3D11Buffer* m_lightColorBuffer;
ID3D11Buffer* m_lightPositionBuffer;
}; };
#endif #endif

View File

@ -12,6 +12,7 @@ ApplicationClass::ApplicationClass()
m_Bitmap = 0; m_Bitmap = 0;
m_Sprite = 0; m_Sprite = 0;
m_Timer = 0; m_Timer = 0;
m_Lights = 0;
} }
@ -57,7 +58,7 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
} }
// Set the initial position of the camera. // 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, 0.0f); m_Camera->SetRotation(0.0f, 0.0f, 0.0f);
// Create and initialize the texture shader object. // Create and initialize the texture shader object.
@ -114,7 +115,7 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
} }
// Set the file name of the model. // Set the file name of the model.
strcpy_s(modelFilename, "sphere.txt"); strcpy_s(modelFilename, "plane.txt");
// Set the file name of the textures. // Set the file name of the textures.
strcpy_s(textureFilename1, "stone01.tga"); strcpy_s(textureFilename1, "stone01.tga");
@ -141,14 +142,24 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
return false; return false;
} }
// Create and initialize the light object. // Set the number of lights we will use.
m_Light = new LightClass; m_numLights = 4;
m_Light->SetAmbientColor(0.15f, 0.15f, 0.15f, 1.0f); // Create and initialize the light objects array.
m_Light->SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f); m_Lights = new LightClass[m_numLights];
m_Light->SetDirection(1.0f, 0.0f, 1.0f);
m_Light->SetSpecularColor(1.0f, 1.0f, 1.0f, 1.0f); // Manually set the color and position of each light.
m_Light->SetSpecularPower(32.0f); 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);
return true; return true;
} }
@ -171,12 +182,12 @@ void ApplicationClass::Shutdown()
m_Sprite = 0; m_Sprite = 0;
} }
// Release the light object. // Release the light objects.
if (m_Light) if(m_Lights)
{ {
delete m_Light; delete [] m_Lights;
m_Light = 0; m_Lights = 0;
} }
// Release the light shader object. // Release the light shader object.
if (m_LightShader) if (m_LightShader)
@ -292,6 +303,8 @@ bool ApplicationClass::Frame()
bool ApplicationClass::Render(float rotation, float x, float y, float z) bool ApplicationClass::Render(float rotation, float x, float y, float z)
{ {
XMMATRIX worldMatrix, viewMatrix, orthoMatrix, projectionMatrix, rotateMatrix, translateMatrix, scaleMatrix, srMatrix; XMMATRIX worldMatrix, viewMatrix, orthoMatrix, projectionMatrix, rotateMatrix, translateMatrix, scaleMatrix, srMatrix;
XMFLOAT4 diffuseColor[4], lightPosition[4];
int i;
bool result; bool result;
// Clear the buffers to begin the scene. // Clear the buffers to begin the scene.
@ -339,7 +352,15 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z)
return false; return false;
} }
// 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();
}
// Render the model using the multitexture shader. // Render the model using the multitexture shader.
result = m_MultiTextureShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, result = m_MultiTextureShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix,
@ -356,15 +377,6 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z)
// Render the model using the multitexture shader. // Render the model using the multitexture shader.
m_Model->Render(m_Direct3D->GetDeviceContext()); 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(),
m_Camera->GetPosition(), m_Light->GetSpecularColor(), m_Light->GetSpecularPower());
if (!result)
{
return false;
}
scaleMatrix = XMMatrixScaling(2.0f, 2.0f, 2.0f); // Build the scaling matrix. scaleMatrix = XMMatrixScaling(2.0f, 2.0f, 2.0f); // Build the scaling matrix.
rotateMatrix = XMMatrixRotationY(-rotation); // Build the rotation matrix. rotateMatrix = XMMatrixRotationY(-rotation); // Build the rotation matrix.
translateMatrix = XMMatrixTranslation(-x, -y, -z); // Build the translation matrix. translateMatrix = XMMatrixTranslation(-x, -y, -z); // Build the translation matrix.
@ -376,6 +388,14 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z)
// Put the model vertex and index buffers on the graphics pipeline to prepare them for drawing. // Put the model vertex and index buffers on the graphics pipeline to prepare them for drawing.
m_Model->Render(m_Direct3D->GetDeviceContext()); 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),
diffuseColor, lightPosition);
if (!result)
{
return false;
}
// Turn the Z buffer back on now that all 2D rendering has completed. // Turn the Z buffer back on now that all 2D rendering has completed.
m_Direct3D->TurnZBufferOn(); m_Direct3D->TurnZBufferOn();

View File

@ -52,6 +52,8 @@ private:
BitmapClass* m_Bitmap; BitmapClass* m_Bitmap;
SpriteClass* m_Sprite; SpriteClass* m_Sprite;
TimerClass* m_Timer; TimerClass* m_Timer;
LightClass* m_Lights;
int m_numLights;
}; };
#endif #endif

View File

@ -89,6 +89,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Text Include="cube.txt" /> <Text Include="cube.txt" />
<Text Include="plane.txt" />
<Text Include="sphere.txt" /> <Text Include="sphere.txt" />
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">

View File

@ -2,6 +2,10 @@
// Filename: light.ps // Filename: light.ps
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/////////////
// DEFINES //
/////////////
#define NUM_LIGHTS 4
///////////// /////////////
// GLOBALS // // GLOBALS //
@ -11,13 +15,17 @@ SamplerState SampleType : register(s0);
cbuffer LightBuffer cbuffer LightBuffer
{ {
float4 ambientColor; float4 ambientColor;
float4 diffuseColor;
float3 lightDirection; float3 lightDirection;
float padding; float padding;
float specularPower; float specularPower;
float4 specularColor; float4 specularColor;
}; };
cbuffer LightColorBuffer
{
float4 diffuseColor[NUM_LIGHTS];
};
////////////// //////////////
// TYPEDEFS // // TYPEDEFS //
@ -27,7 +35,7 @@ struct PixelInputType
float4 position : SV_POSITION; float4 position : SV_POSITION;
float2 tex : TEXCOORD0; float2 tex : TEXCOORD0;
float3 normal : NORMAL; float3 normal : NORMAL;
float3 viewDirection : TEXCOORD1; float3 lightPos[NUM_LIGHTS] : TEXCOORD1;
}; };
@ -38,48 +46,39 @@ float4 LightPixelShader(PixelInputType input) : SV_TARGET
{ {
float4 textureColor; float4 textureColor;
float3 lightDir; float3 lightDir;
float lightIntensity;
float4 color; float4 color;
float3 reflection; float3 reflection;
float4 specular; float4 specular;
float lightIntensity[NUM_LIGHTS];
float4 colorArray[NUM_LIGHTS];
float4 colorSum;
int i;
// Sample the pixel color from the texture using the sampler at this texture coordinate location. // Sample the pixel color from the texture using the sampler at this texture coordinate location.
textureColor = shaderTexture.Sample(SampleType, input.tex); textureColor = shaderTexture.Sample(SampleType, input.tex);
// Set the default output color to the ambient light value for all pixels. for(i=0; i<NUM_LIGHTS; i++)
color = ambientColor;
// Initialize the specular color.
specular = float4(0.0f, 0.0f, 0.0f, 0.0f);
// Invert the light direction for calculations.
lightDir = -lightDirection;
// Calculate the amount of light on this pixel.
lightIntensity = saturate(dot(input.normal, lightDir));
if(lightIntensity > 0.0f)
{ {
// Determine the final diffuse color based on the diffuse color and the amount of light intensity. // Calculate the different amounts of light on this pixel based on the positions of the lights.
color += (diffuseColor * lightIntensity); lightIntensity[i] = saturate(dot(input.normal, input.lightPos[i]));
// Saturate the ambient and diffuse color. // Determine the diffuse color amount of each of the four lights.
color = saturate(color); colorArray[i] = diffuseColor[i] * lightIntensity[i];
}
// Calculate the reflection vector based on the light intensity, normal vector, and light direction. // Initialize the sum of colors.
reflection = normalize(2.0f * lightIntensity * input.normal - lightDir); colorSum = float4(0.0f, 0.0f, 0.0f, 1.0f);
// Determine the amount of specular light based on the reflection vector, viewing direction, and specular power. // Add all of the light colors up.
specular = pow(saturate(dot(reflection, input.viewDirection)), specularPower); for(i=0; i<NUM_LIGHTS; i++)
{
colorSum.r += colorArray[i].r;
colorSum.g += colorArray[i].g;
colorSum.b += colorArray[i].b;
} }
// Multiply the texture pixel and the final diffuse color to get the final pixel color result. // Multiply the texture pixel by the combination of all four light colors to get the final result.
color = color * textureColor; color = saturate(colorSum) * textureColor;
// Add the specular component last to the output color.
color = saturate(color + specular);
return color; return color;
} }

View File

@ -2,6 +2,10 @@
// Filename: light.vs // Filename: light.vs
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/////////////
// DEFINES //
/////////////
#define NUM_LIGHTS 4
///////////// /////////////
// GLOBALS // // GLOBALS //
@ -19,6 +23,11 @@ cbuffer CameraBuffer
float padding; float padding;
}; };
cbuffer LightPositionBuffer
{
float4 lightPosition[NUM_LIGHTS];
};
////////////// //////////////
// TYPEDEFS // // TYPEDEFS //
////////////// //////////////
@ -34,7 +43,7 @@ struct PixelInputType
float4 position : SV_POSITION; float4 position : SV_POSITION;
float2 tex : TEXCOORD0; float2 tex : TEXCOORD0;
float3 normal : NORMAL; float3 normal : NORMAL;
float3 viewDirection : TEXCOORD1; float3 lightPos[NUM_LIGHTS] : TEXCOORD1;
}; };
@ -45,7 +54,7 @@ PixelInputType LightVertexShader(VertexInputType input)
{ {
PixelInputType output; PixelInputType output;
float4 worldPosition; float4 worldPosition;
int i;
// Change the position vector to be 4 units for proper matrix calculations. // Change the position vector to be 4 units for proper matrix calculations.
input.position.w = 1.0f; input.position.w = 1.0f;
@ -67,11 +76,14 @@ PixelInputType LightVertexShader(VertexInputType input)
// Calculate the position of the vertex in the world. // Calculate the position of the vertex in the world.
worldPosition = mul(input.position, worldMatrix); worldPosition = mul(input.position, worldMatrix);
// Determine the viewing direction based on the position of the camera and the position of the vertex in the world. for(i=0; i<NUM_LIGHTS; i++)
output.viewDirection = cameraPosition.xyz - worldPosition.xyz; {
// Determine the light positions based on the position of the lights and the position of the vertex in the world.
// Normalize the viewing direction vector. output.lightPos[i] = lightPosition[i].xyz - worldPosition.xyz;
output.viewDirection = normalize(output.viewDirection);
// Normalize the light position vectors.
output.lightPos[i] = normalize(output.lightPos[i]);
}
return output; return output;
} }

View File

@ -52,6 +52,12 @@ void LightClass::SetSpecularPower(float power)
return; return;
} }
void LightClass::SetPosition(float x, float y, float z)
{
m_position = XMFLOAT4(x, y, z, 1.0f);
return;
}
XMFLOAT4 LightClass::GetAmbientColor() XMFLOAT4 LightClass::GetAmbientColor()
{ {
return m_ambientColor; return m_ambientColor;
@ -77,4 +83,9 @@ XMFLOAT4 LightClass::GetSpecularColor()
float LightClass::GetSpecularPower() float LightClass::GetSpecularPower()
{ {
return m_specularPower; return m_specularPower;
} }
XMFLOAT4 LightClass::GetPosition()
{
return m_position;
}

View File

@ -28,12 +28,14 @@ public:
void SetDirection(float, float, float); void SetDirection(float, float, float);
void SetSpecularColor(float, float, float, float); void SetSpecularColor(float, float, float, float);
void SetSpecularPower(float); void SetSpecularPower(float);
void SetPosition(float, float, float);
XMFLOAT4 GetAmbientColor(); XMFLOAT4 GetAmbientColor();
XMFLOAT4 GetDiffuseColor(); XMFLOAT4 GetDiffuseColor();
XMFLOAT3 GetDirection(); XMFLOAT3 GetDirection();
XMFLOAT4 GetSpecularColor(); XMFLOAT4 GetSpecularColor();
float GetSpecularPower(); float GetSpecularPower();
XMFLOAT4 GetPosition();
private: private:
XMFLOAT4 m_ambientColor; XMFLOAT4 m_ambientColor;
@ -41,6 +43,7 @@ private:
XMFLOAT3 m_direction; XMFLOAT3 m_direction;
XMFLOAT4 m_specularColor; XMFLOAT4 m_specularColor;
float m_specularPower; float m_specularPower;
XMFLOAT4 m_position;
}; };
#endif #endif

View File

@ -13,6 +13,8 @@ LightShaderClass::LightShaderClass()
m_matrixBuffer = 0; m_matrixBuffer = 0;
m_cameraBuffer = 0; m_cameraBuffer = 0;
m_lightBuffer = 0; m_lightBuffer = 0;
m_lightColorBuffer = 0;
m_lightPositionBuffer = 0;
} }
@ -66,15 +68,13 @@ void LightShaderClass::Shutdown()
} }
bool LightShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix, bool LightShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 ambientColor, XMFLOAT4 diffuseColor, ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[])
XMFLOAT3 cameraPosition, XMFLOAT4 specularColor, float specularPower)
{ {
bool result; bool result;
// Set the shader parameters that it will use for rendering. // Set the shader parameters that it will use for rendering.
result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, lightDirection, ambientColor, diffuseColor, result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, diffuseColor, lightPosition);
cameraPosition, specularColor, specularPower);
if(!result) if(!result)
{ {
return false; return false;
@ -98,7 +98,8 @@ bool LightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR*
D3D11_SAMPLER_DESC samplerDesc; D3D11_SAMPLER_DESC samplerDesc;
D3D11_BUFFER_DESC matrixBufferDesc; D3D11_BUFFER_DESC matrixBufferDesc;
D3D11_BUFFER_DESC cameraBufferDesc; D3D11_BUFFER_DESC cameraBufferDesc;
D3D11_BUFFER_DESC lightBufferDesc; D3D11_BUFFER_DESC lightColorBufferDesc;
D3D11_BUFFER_DESC lightPositionBufferDesc;
// Initialize the pointers this function will use to null. // Initialize the pointers this function will use to null.
@ -237,6 +238,8 @@ bool LightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR*
return false; return false;
} }
// Setup the description of the camera dynamic constant buffer that is in the vertex shader. // Setup the description of the camera dynamic constant buffer that is in the vertex shader.
cameraBufferDesc.Usage = D3D11_USAGE_DYNAMIC; cameraBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
cameraBufferDesc.ByteWidth = sizeof(CameraBufferType); cameraBufferDesc.ByteWidth = sizeof(CameraBufferType);
@ -252,17 +255,31 @@ bool LightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR*
return false; return false;
} }
// Setup the description of the light dynamic constant buffer that is in the pixel shader. // Setup the description of the 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. lightColorBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
lightBufferDesc.Usage = D3D11_USAGE_DYNAMIC; lightColorBufferDesc.ByteWidth = sizeof(LightColorBufferType);
lightBufferDesc.ByteWidth = sizeof(LightBufferType) + 12 ; lightColorBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
lightBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; lightColorBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
lightBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; lightColorBufferDesc.MiscFlags = 0;
lightBufferDesc.MiscFlags = 0; lightColorBufferDesc.StructureByteStride = 0;
lightBufferDesc.StructureByteStride = 0;
// Create the constant buffer pointer so we can access the pixel shader constant buffer from within this class.
result = device->CreateBuffer(&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. // 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); result = device->CreateBuffer(&lightPositionBufferDesc, NULL, &m_lightPositionBuffer);
if (FAILED(result)) if (FAILED(result))
{ {
return false; return false;
@ -274,6 +291,19 @@ bool LightShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR*
void LightShaderClass::ShutdownShader() 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. // Release the light constant buffer.
if (m_lightBuffer) if (m_lightBuffer)
{ {
@ -364,15 +394,14 @@ void LightShaderClass::OutputShaderErrorMessage(ID3D10Blob* errorMessage, HWND h
bool LightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix, bool LightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 ambientColor, XMFLOAT4 diffuseColor, ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[])
XMFLOAT3 cameraPosition, XMFLOAT4 specularColor, float specularPower)
{ {
HRESULT result; HRESULT result;
D3D11_MAPPED_SUBRESOURCE mappedResource; D3D11_MAPPED_SUBRESOURCE mappedResource;
unsigned int bufferNumber; unsigned int bufferNumber;
MatrixBufferType* dataPtr; MatrixBufferType* dataPtr;
LightBufferType* dataPtr2; LightPositionBufferType* dataPtr2;
CameraBufferType* dataPtr3; LightColorBufferType* dataPtr3;
// Transpose the matrices to prepare them for the shader. // Transpose the matrices to prepare them for the shader.
worldMatrix = XMMatrixTranspose(worldMatrix); worldMatrix = XMMatrixTranspose(worldMatrix);
@ -410,51 +439,59 @@ bool LightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, X
return false; return false;
} }
// Get a pointer to the data in the constant buffer. // Lock the light position constant buffer so it can be written to.
dataPtr3 = (CameraBufferType*)mappedResource.pData; result = deviceContext->Map(m_lightPositionBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
// Copy the camera position into the constant buffer.
dataPtr3->cameraPosition = cameraPosition;
dataPtr3->padding = 0.0f;
// Unlock the camera constant buffer.
deviceContext->Unmap(m_cameraBuffer, 0);
// Set the position of the camera constant buffer in the vertex shader.
bufferNumber = 1;
// Now set the camera constant buffer in the vertex shader with the updated values.
deviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_cameraBuffer);
// 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)) if (FAILED(result))
{ {
return false; return false;
} }
// Get a pointer to the data in the constant buffer. // 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. // Copy the light position variables into the constant buffer.
dataPtr2->ambientColor = ambientColor; dataPtr2->lightPosition[0] = lightPosition[0];
dataPtr2->diffuseColor = diffuseColor; dataPtr2->lightPosition[1] = lightPosition[1];
dataPtr2->lightDirection = lightDirection; dataPtr2->lightPosition[2] = lightPosition[2];
dataPtr2->specularColor = specularColor; dataPtr2->lightPosition[3] = lightPosition[3];
dataPtr2->specularPower = specularPower;
//dataPtr2->padding = 0.0f;
// Unlock the constant buffer. // 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; bufferNumber = 0;
// Finally set the light constant buffer in the pixel shader with the updated values. // Finally set the constant buffer in the pixel shader with the updated values.
deviceContext->PSSetConstantBuffers(bufferNumber, 1, &m_lightBuffer); deviceContext->PSSetConstantBuffers(bufferNumber, 1, &m_lightColorBuffer);
return true; return true;
} }

View File

@ -5,6 +5,11 @@
#define _LIGHTSHADERCLASS_H_ #define _LIGHTSHADERCLASS_H_
/////////////
// GLOBALS //
/////////////
const int NUM_LIGHTS = 4;
////////////// //////////////
// INCLUDES // // INCLUDES //
////////////// //////////////
@ -45,6 +50,16 @@ private:
XMFLOAT4 specularColor; XMFLOAT4 specularColor;
}; };
struct LightColorBufferType
{
XMFLOAT4 diffuseColor[NUM_LIGHTS];
};
struct LightPositionBufferType
{
XMFLOAT4 lightPosition[NUM_LIGHTS];
};
public: public:
LightShaderClass(); LightShaderClass();
LightShaderClass(const LightShaderClass&); LightShaderClass(const LightShaderClass&);
@ -52,14 +67,14 @@ public:
bool Initialize(ID3D11Device*, HWND); bool Initialize(ID3D11Device*, HWND);
void Shutdown(); void Shutdown();
bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4, XMFLOAT4, XMFLOAT3, XMFLOAT4, float); bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4[], XMFLOAT4[]);
private: private:
bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*); bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*);
void ShutdownShader(); void ShutdownShader();
void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*); void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*);
bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4, XMFLOAT4, XMFLOAT3, XMFLOAT4, float); bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4[], XMFLOAT4[]);
void RenderShader(ID3D11DeviceContext*, int); void RenderShader(ID3D11DeviceContext*, int);
private: private:
@ -70,6 +85,8 @@ private:
ID3D11Buffer* m_matrixBuffer; ID3D11Buffer* m_matrixBuffer;
ID3D11Buffer* m_cameraBuffer; ID3D11Buffer* m_cameraBuffer;
ID3D11Buffer* m_lightBuffer; ID3D11Buffer* m_lightBuffer;
ID3D11Buffer* m_lightColorBuffer;
ID3D11Buffer* m_lightPositionBuffer;
}; };
#endif #endif

3754
enginecustom/plane.txt Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.