diff --git a/enginecustom/applicationclass.cpp b/enginecustom/applicationclass.cpp
index d8c8f81..8ea3373 100644
--- a/enginecustom/applicationclass.cpp
+++ b/enginecustom/applicationclass.cpp
@@ -23,7 +23,7 @@ ApplicationClass::ApplicationClass()
m_Fps = 0;
m_FpsString = 0;
m_NormalMapShader = 0;
-
+ m_SpecMapShader = 0;
}
@@ -74,6 +74,16 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
m_Camera->SetPosition(0.0f, 0.0f, -12.0f);
m_Camera->SetRotation(0.0f, 0.0f, 0.0f);
+ // Create and initialize the specular map shader object.
+ m_SpecMapShader = new SpecMapShaderClass;
+
+ result = m_SpecMapShader->Initialize(m_Direct3D->GetDevice(), hwnd);
+ if (!result)
+ {
+ MessageBox(hwnd, L"Could not initialize the specular map shader object.", L"Error", MB_OK);
+ return false;
+ }
+
// Create and initialize the normal map shader object.
m_NormalMapShader = new NormalMapShaderClass;
@@ -221,6 +231,7 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
strcpy_s(textureFilename1, "stone01.tga");
strcpy_s(textureFilename2, "normal01.tga");
strcpy_s(textureFilename3, "alpha01.tga");
+ // A FAIRE: Ajouter une nouvelle texture pour le multitexturing
// Create and initialize the model object.
m_Model = new ModelClass;
@@ -248,6 +259,8 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
m_Light->SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f);
m_Light->SetDirection(0.0f, 0.0f, 1.0f);
+ m_Light->SetSpecularColor(1.0f, 1.0f, 1.0f, 1.0f);
+ m_Light->SetSpecularPower(16.0f);
// Set the number of lights we will use.
m_numLights = 4;
@@ -414,6 +427,14 @@ void ApplicationClass::Shutdown()
m_Model = 0;
}
+ // Release the specular map shader object.
+ if (m_SpecMapShader)
+ {
+ m_SpecMapShader->Shutdown();
+ delete m_SpecMapShader;
+ m_SpecMapShader = 0;
+ }
+
// Release the normal map shader object.
if (m_NormalMapShader)
{
@@ -704,9 +725,18 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z)
return false;
}*/
- //Normal Mapping
- result = m_NormalMapShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix,
- m_Model->GetTexture(0), m_Model->GetTexture(1), m_Light->GetDirection(), m_Light->GetDiffuseColor());
+ ////Normal Mapping
+ //result = m_NormalMapShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix,
+ // m_Model->GetTexture(0), m_Model->GetTexture(1), m_Light->GetDirection(), m_Light->GetDiffuseColor());
+ //if (!result)
+ //{
+ // return false;
+ //}
+
+ //Specular Mapping
+ result = m_SpecMapShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix,
+ m_Model->GetTexture(0), m_Model->GetTexture(1), m_Model->GetTexture(2), m_Light->GetDirection(), m_Light->GetDiffuseColor(),
+ m_Camera->GetPosition(), m_Light->GetSpecularColor(), m_Light->GetSpecularPower());
if (!result)
{
return false;
diff --git a/enginecustom/applicationclass.h b/enginecustom/applicationclass.h
index 90f5d47..1c3bc25 100644
--- a/enginecustom/applicationclass.h
+++ b/enginecustom/applicationclass.h
@@ -23,6 +23,7 @@
#include "fpsclass.h"
#include "inputclass.h"
#include "normalmapshaderclass.h"
+#include "specmapshaderclass.h"
/////////////
@@ -76,6 +77,7 @@ private:
TextClass* m_FpsString;
int m_previousFps;
NormalMapShaderClass* m_NormalMapShader;
+ SpecMapShaderClass* m_SpecMapShader;
};
#endif
diff --git a/enginecustom/enginecustom.vcxproj b/enginecustom/enginecustom.vcxproj
index ab41f30..2d54fd5 100644
--- a/enginecustom/enginecustom.vcxproj
+++ b/enginecustom/enginecustom.vcxproj
@@ -37,6 +37,7 @@
+
@@ -61,6 +62,7 @@
+
@@ -82,6 +84,8 @@
+
+
diff --git a/enginecustom/enginecustom.vcxproj.filters b/enginecustom/enginecustom.vcxproj.filters
index 5d19cc1..1a53214 100644
--- a/enginecustom/enginecustom.vcxproj.filters
+++ b/enginecustom/enginecustom.vcxproj.filters
@@ -96,6 +96,9 @@
Fichiers sources
+
+ Fichiers sources
+
@@ -164,6 +167,9 @@
Fichiers d%27en-tĂȘte
+
+ Fichiers d%27en-tĂȘte
+
@@ -244,6 +250,12 @@
shader
+
+ shader
+
+
+ shader
+
diff --git a/enginecustom/modelclass.cpp b/enginecustom/modelclass.cpp
index ff2f5ce..38dcfa7 100644
--- a/enginecustom/modelclass.cpp
+++ b/enginecustom/modelclass.cpp
@@ -19,8 +19,7 @@ ModelClass::~ModelClass()
{
}
-bool ModelClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceContext, char* modelFilename, char* textureFilename1, char* textureFilename2,
- char* textureFilename3)
+bool ModelClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceContext, char* modelFilename, char* textureFilename1, char* textureFilename2, char* textureFilename3)
{
bool result;
diff --git a/enginecustom/specmap.ps b/enginecustom/specmap.ps
new file mode 100644
index 0000000..7e49723
--- /dev/null
+++ b/enginecustom/specmap.ps
@@ -0,0 +1,93 @@
+/////////////
+// GLOBALS //
+/////////////
+
+Texture2D shaderTexture1 : register(t0);
+Texture2D shaderTexture2 : register(t1);
+Texture2D shaderTexture3 : register(t2);
+SamplerState SampleType : register(s0);
+
+cbuffer LightBuffer
+{
+ float4 diffuseColor;
+ float4 specularColor;
+ float specularPower;
+ float3 lightDirection;
+};
+
+//////////////
+// TYPEDEFS //
+//////////////
+struct PixelInputType
+{
+ float4 position : SV_POSITION;
+ float2 tex : TEXCOORD0;
+ float3 normal : NORMAL;
+ float3 tangent : TANGENT;
+ float3 binormal : BINORMAL;
+ float3 viewDirection : TEXCOORD1;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Pixel Shader
+////////////////////////////////////////////////////////////////////////////////
+float4 SpecMapPixelShader(PixelInputType input) : SV_TARGET
+{
+ float4 textureColor;
+ float4 bumpMap;
+ float3 bumpNormal;
+ float3 lightDir;
+ float lightIntensity;
+ float4 color;
+ float4 specularIntensity;
+ float3 reflection;
+ float4 specular;
+
+ // Sample the pixel color from the color texture at this location.
+ textureColor = shaderTexture1.Sample(SampleType, input.tex);
+
+ // Sample the pixel from the normal map.
+ bumpMap = shaderTexture2.Sample(SampleType, input.tex);
+
+ // Expand the range of the normal value from (0, +1) to (-1, +1).
+ bumpMap = (bumpMap * 2.0f) - 1.0f;
+
+ // Calculate the normal from the data in the normal map.
+ bumpNormal = (bumpMap.x * input.tangent) + (bumpMap.y * input.binormal) + (bumpMap.z * input.normal);
+
+ // Normalize the resulting bump normal.
+ bumpNormal = normalize(bumpNormal);
+
+ // Invert the light direction for calculations.
+ lightDir = -lightDirection;
+
+ // Calculate the amount of light on this pixel based on the normal map value.
+ lightIntensity = saturate(dot(bumpNormal, lightDir));
+
+ // Determine the final amount of diffuse color based on the diffuse color combined with the light intensity.
+ color = saturate(diffuseColor * lightIntensity);
+
+ // Combine the final light color with the texture color.
+ color = color * textureColor;
+
+ if(lightIntensity > 0.0f)
+ {
+ // Sample the pixel from the specular map texture.
+ specularIntensity = shaderTexture3.Sample(SampleType, input.tex);
+
+ // Calculate the reflection vector based on the light intensity, normal vector, and light direction.
+ reflection = normalize(2 * lightIntensity * bumpNormal - lightDir);
+
+ // Determine the amount of specular light based on the reflection vector, viewing direction, and specular power.
+ specular = pow(saturate(dot(reflection, input.viewDirection)), specularPower);
+
+ // Use the specular map to determine the intensity of specular light at this pixel.
+ specular = specular * specularIntensity;
+
+ // Add the specular component last to the output color.
+ color = saturate(color + specular);
+ }
+
+ return color;
+}
\ No newline at end of file
diff --git a/enginecustom/specmap.vs b/enginecustom/specmap.vs
new file mode 100644
index 0000000..2983ab6
--- /dev/null
+++ b/enginecustom/specmap.vs
@@ -0,0 +1,83 @@
+/////////////
+// GLOBALS //
+/////////////
+cbuffer MatrixBuffer
+{
+ matrix worldMatrix;
+ matrix viewMatrix;
+ matrix projectionMatrix;
+};
+
+cbuffer CameraBuffer
+{
+ float3 cameraPosition;
+ float padding;
+};
+
+
+//////////////
+// TYPEDEFS //
+//////////////
+struct VertexInputType
+{
+ float4 position : POSITION;
+ float2 tex : TEXCOORD0;
+ float3 normal : NORMAL;
+ float3 tangent : TANGENT;
+ float3 binormal : BINORMAL;
+};
+
+struct PixelInputType
+{
+ float4 position : SV_POSITION;
+ float2 tex : TEXCOORD0;
+ float3 normal : NORMAL;
+ float3 tangent : TANGENT;
+ float3 binormal : BINORMAL;
+ float3 viewDirection : TEXCOORD1;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Vertex Shader
+////////////////////////////////////////////////////////////////////////////////
+PixelInputType SpecMapVertexShader(VertexInputType input)
+{
+ PixelInputType output;
+ float4 worldPosition;
+
+
+ // 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 and then normalize the final value.
+ output.normal = mul(input.normal, (float3x3)worldMatrix);
+ output.normal = normalize(output.normal);
+
+ // Calculate the tangent vector against the world matrix only and then normalize the final value.
+ output.tangent = mul(input.tangent, (float3x3)worldMatrix);
+ output.tangent = normalize(output.tangent);
+
+ // Calculate the binormal vector against the world matrix only and then normalize the final value.
+ output.binormal = mul(input.binormal, (float3x3)worldMatrix);
+ output.binormal = normalize(output.binormal);
+
+ // Calculate the position of the vertex in the world.
+ 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.
+ output.viewDirection = cameraPosition.xyz - worldPosition.xyz;
+
+ // Normalize the viewing direction vector.
+ output.viewDirection = normalize(output.viewDirection);
+
+ return output;
+}
diff --git a/enginecustom/specmapshaderclass.cpp b/enginecustom/specmapshaderclass.cpp
new file mode 100644
index 0000000..0d1ff07
--- /dev/null
+++ b/enginecustom/specmapshaderclass.cpp
@@ -0,0 +1,492 @@
+#include "specmapshaderclass.h"
+
+
+SpecMapShaderClass::SpecMapShaderClass()
+{
+ m_vertexShader = 0;
+ m_pixelShader = 0;
+ m_layout = 0;
+ m_matrixBuffer = 0;
+ m_sampleState = 0;
+ m_lightBuffer = 0;
+ m_cameraBuffer = 0;
+}
+
+
+SpecMapShaderClass::SpecMapShaderClass(const SpecMapShaderClass& other)
+{
+}
+
+
+SpecMapShaderClass::~SpecMapShaderClass()
+{
+}
+
+
+bool SpecMapShaderClass::Initialize(ID3D11Device* device, HWND hwnd)
+{
+ bool result;
+ wchar_t vsFilename[128];
+ wchar_t psFilename[128];
+ int error;
+
+ // Set the filename of the vertex shader.
+ error = wcscpy_s(vsFilename, 128, L"specmap.vs");
+ if (error != 0)
+ {
+ return false;
+ }
+
+ // Set the filename of the pixel shader.
+ error = wcscpy_s(psFilename, 128, L"specmap.ps");
+ if (error != 0)
+ {
+ return false;
+ }
+
+ // Initialize the vertex and pixel shaders.
+ result = InitializeShader(device, hwnd, vsFilename, psFilename);
+ if (!result)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+void SpecMapShaderClass::Shutdown()
+{
+ // Shutdown the vertex and pixel shaders as well as the related objects.
+ ShutdownShader();
+
+ return;
+}
+
+bool SpecMapShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
+ ID3D11ShaderResourceView* texture1, ID3D11ShaderResourceView* texture2, ID3D11ShaderResourceView* texture3,
+ XMFLOAT3 lightDirection, XMFLOAT4 diffuseColor, XMFLOAT3 cameraPosition, XMFLOAT4 specularColor, float specularPower)
+{
+ bool result;
+
+
+ // Set the shader parameters that it will use for rendering.
+ result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture1, texture2, texture3, lightDirection, diffuseColor,
+ cameraPosition, specularColor, specularPower);
+ if (!result)
+ {
+ return false;
+ }
+
+ // Now render the prepared buffers with the shader.
+ RenderShader(deviceContext, indexCount);
+
+ return true;
+}
+
+
+bool SpecMapShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR* vsFilename, WCHAR* psFilename)
+{
+ HRESULT result;
+ ID3D10Blob* errorMessage;
+ ID3D10Blob* vertexShaderBuffer;
+ ID3D10Blob* pixelShaderBuffer;
+ D3D11_INPUT_ELEMENT_DESC polygonLayout[5];
+ unsigned int numElements;
+ D3D11_BUFFER_DESC matrixBufferDesc;
+ D3D11_SAMPLER_DESC samplerDesc;
+ D3D11_BUFFER_DESC lightBufferDesc;
+ D3D11_BUFFER_DESC cameraBufferDesc;
+
+
+ // 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, "SpecMapVertexShader", "vs_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0,
+ &vertexShaderBuffer, &errorMessage);
+ if (FAILED(result))
+ {
+ // If the shader failed to compile it should have writen something to the error message.
+ if (errorMessage)
+ {
+ OutputShaderErrorMessage(errorMessage, hwnd, vsFilename);
+ }
+ // If there was nothing in the error message then it simply could not find the shader file itself.
+ else
+ {
+ MessageBox(hwnd, vsFilename, L"Missing Shader File", MB_OK);
+ }
+
+ return false;
+ }
+
+ // Compile the pixel shader code.
+ result = D3DCompileFromFile(psFilename, NULL, NULL, "SpecMapPixelShader", "ps_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0,
+ &pixelShaderBuffer, &errorMessage);
+ if (FAILED(result))
+ {
+ // If the shader failed to compile it should have writen something to the error message.
+ if (errorMessage)
+ {
+ OutputShaderErrorMessage(errorMessage, hwnd, psFilename);
+ }
+ // If there was nothing in the error message then it simply could not find the file itself.
+ else
+ {
+ MessageBox(hwnd, psFilename, L"Missing Shader File", MB_OK);
+ }
+
+ return false;
+ }
+
+ // Create the vertex shader from the buffer.
+ result = device->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &m_vertexShader);
+ if (FAILED(result))
+ {
+ return false;
+ }
+
+ // Create the pixel shader from the buffer.
+ result = device->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &m_pixelShader);
+ if (FAILED(result))
+ {
+ return false;
+ }
+
+ // Create the vertex input layout description.
+ polygonLayout[0].SemanticName = "POSITION";
+ polygonLayout[0].SemanticIndex = 0;
+ polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
+ polygonLayout[0].InputSlot = 0;
+ polygonLayout[0].AlignedByteOffset = 0;
+ polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
+ polygonLayout[0].InstanceDataStepRate = 0;
+
+ polygonLayout[1].SemanticName = "TEXCOORD";
+ polygonLayout[1].SemanticIndex = 0;
+ polygonLayout[1].Format = DXGI_FORMAT_R32G32_FLOAT;
+ polygonLayout[1].InputSlot = 0;
+ polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
+ polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
+ polygonLayout[1].InstanceDataStepRate = 0;
+
+ polygonLayout[2].SemanticName = "NORMAL";
+ polygonLayout[2].SemanticIndex = 0;
+ polygonLayout[2].Format = DXGI_FORMAT_R32G32B32_FLOAT;
+ polygonLayout[2].InputSlot = 0;
+ polygonLayout[2].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
+ polygonLayout[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
+ polygonLayout[2].InstanceDataStepRate = 0;
+
+ polygonLayout[3].SemanticName = "TANGENT";
+ polygonLayout[3].SemanticIndex = 0;
+ polygonLayout[3].Format = DXGI_FORMAT_R32G32B32_FLOAT;
+ polygonLayout[3].InputSlot = 0;
+ polygonLayout[3].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
+ polygonLayout[3].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
+ polygonLayout[3].InstanceDataStepRate = 0;
+
+ polygonLayout[4].SemanticName = "BINORMAL";
+ polygonLayout[4].SemanticIndex = 0;
+ polygonLayout[4].Format = DXGI_FORMAT_R32G32B32_FLOAT;
+ polygonLayout[4].InputSlot = 0;
+ polygonLayout[4].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
+ polygonLayout[4].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
+ polygonLayout[4].InstanceDataStepRate = 0;
+
+ // Get a count of the elements in the layout.
+ numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);
+
+ // Create the vertex input layout.
+ result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(),
+ vertexShaderBuffer->GetBufferSize(), &m_layout);
+ if (FAILED(result))
+ {
+ return false;
+ }
+
+ // Release the vertex shader buffer and pixel shader buffer since they are no longer needed.
+ vertexShaderBuffer->Release();
+ vertexShaderBuffer = 0;
+
+ pixelShaderBuffer->Release();
+ pixelShaderBuffer = 0;
+
+ // Setup the description of the dynamic matrix constant buffer that is in the vertex shader.
+ matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+ matrixBufferDesc.ByteWidth = sizeof(MatrixBufferType);
+ matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ matrixBufferDesc.MiscFlags = 0;
+ matrixBufferDesc.StructureByteStride = 0;
+
+ // Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class.
+ result = device->CreateBuffer(&matrixBufferDesc, NULL, &m_matrixBuffer);
+ if (FAILED(result))
+ {
+ return false;
+ }
+
+ // Create a texture sampler state description.
+ samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
+ samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
+ samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
+ samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
+ samplerDesc.MipLODBias = 0.0f;
+ samplerDesc.MaxAnisotropy = 1;
+ samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
+ samplerDesc.BorderColor[0] = 0;
+ samplerDesc.BorderColor[1] = 0;
+ samplerDesc.BorderColor[2] = 0;
+ samplerDesc.BorderColor[3] = 0;
+ samplerDesc.MinLOD = 0;
+ samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
+
+ // Create the texture sampler state.
+ result = device->CreateSamplerState(&samplerDesc, &m_sampleState);
+ if (FAILED(result))
+ {
+ return false;
+ }
+
+ // Setup the description of the light dynamic constant buffer that is in the pixel shader.
+ 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;
+ }
+
+ // Setup the description of the camera dynamic constant buffer that is in the vertex shader.
+ cameraBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+ cameraBufferDesc.ByteWidth = sizeof(CameraBufferType);
+ cameraBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ cameraBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ cameraBufferDesc.MiscFlags = 0;
+ cameraBufferDesc.StructureByteStride = 0;
+
+ // Create the camera constant buffer pointer so we can access the vertex shader constant buffer from within this class.
+ result = device->CreateBuffer(&cameraBufferDesc, NULL, &m_cameraBuffer);
+ if (FAILED(result))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+void SpecMapShaderClass::ShutdownShader()
+{
+ // Release the camera constant buffer.
+ if (m_cameraBuffer)
+ {
+ m_cameraBuffer->Release();
+ m_cameraBuffer = 0;
+ }
+
+ // Release the light constant buffer.
+ if (m_lightBuffer)
+ {
+ m_lightBuffer->Release();
+ m_lightBuffer = 0;
+ }
+
+ // Release the sampler state.
+ if (m_sampleState)
+ {
+ m_sampleState->Release();
+ m_sampleState = 0;
+ }
+
+ // Release the matrix constant buffer.
+ if (m_matrixBuffer)
+ {
+ m_matrixBuffer->Release();
+ m_matrixBuffer = 0;
+ }
+
+ // Release the layout.
+ if (m_layout)
+ {
+ m_layout->Release();
+ m_layout = 0;
+ }
+
+ // Release the pixel shader.
+ if (m_pixelShader)
+ {
+ m_pixelShader->Release();
+ m_pixelShader = 0;
+ }
+
+ // Release the vertex shader.
+ if (m_vertexShader)
+ {
+ m_vertexShader->Release();
+ m_vertexShader = 0;
+ }
+
+ return;
+}
+
+
+void SpecMapShaderClass::OutputShaderErrorMessage(ID3D10Blob* errorMessage, HWND hwnd, WCHAR* shaderFilename)
+{
+ char* compileErrors;
+ unsigned long long bufferSize, i;
+ ofstream fout;
+
+
+ // Get a pointer to the error message text buffer.
+ compileErrors = (char*)(errorMessage->GetBufferPointer());
+
+ // Get the length of the message.
+ bufferSize = errorMessage->GetBufferSize();
+
+ // Open a file to write the error message to.
+ fout.open("shader-error.txt");
+
+ // Write out the error message.
+ for (i = 0; i < bufferSize; i++)
+ {
+ fout << compileErrors[i];
+ }
+
+ // Close the file.
+ fout.close();
+
+ // Release the error message.
+ errorMessage->Release();
+ errorMessage = 0;
+
+ // Pop a message up on the screen to notify the user to check the text file for compile errors.
+ MessageBox(hwnd, L"Error compiling shader. Check shader-error.txt for message.", shaderFilename, MB_OK);
+
+ return;
+}
+
+bool SpecMapShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
+ ID3D11ShaderResourceView* texture1, ID3D11ShaderResourceView* texture2, ID3D11ShaderResourceView* texture3,
+ XMFLOAT3 lightDirection, XMFLOAT4 diffuseColor, XMFLOAT3 cameraPosition, XMFLOAT4 specularColor, float specularPower)
+{
+ HRESULT result;
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ MatrixBufferType* dataPtr;
+ unsigned int bufferNumber;
+ LightBufferType* dataPtr2;
+ CameraBufferType* dataPtr3;
+
+
+ // Transpose the matrices to prepare them for the shader.
+ worldMatrix = XMMatrixTranspose(worldMatrix);
+ viewMatrix = XMMatrixTranspose(viewMatrix);
+ projectionMatrix = XMMatrixTranspose(projectionMatrix);
+
+ // Lock the constant buffer so it can be written to.
+ result = deviceContext->Map(m_matrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ return false;
+ }
+
+ // Get a pointer to the data in the constant buffer.
+ dataPtr = (MatrixBufferType*)mappedResource.pData;
+
+ // Copy the matrices into the constant buffer.
+ dataPtr->world = worldMatrix;
+ dataPtr->view = viewMatrix;
+ dataPtr->projection = projectionMatrix;
+
+ // Unlock the constant buffer.
+ deviceContext->Unmap(m_matrixBuffer, 0);
+
+ // Set the position of the constant buffer in the vertex shader.
+ bufferNumber = 0;
+
+ // Finally set the constant buffer in the vertex shader with the updated values.
+ deviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_matrixBuffer);
+
+ // Set shader texture resources in the pixel shader.
+ deviceContext->PSSetShaderResources(0, 1, &texture1);
+ deviceContext->PSSetShaderResources(1, 1, &texture2);
+ deviceContext->PSSetShaderResources(2, 1, &texture3);
+
+ // 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->specularColor = specularColor;
+ dataPtr2->specularPower = specularPower;
+
+ // 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);
+
+ // Lock the camera constant buffer so it can be written to.
+ result = deviceContext->Map(m_cameraBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ return false;
+ }
+
+ // Get a pointer to the data in the constant buffer.
+ dataPtr3 = (CameraBufferType*)mappedResource.pData;
+
+ // Copy the camera position into the constant buffer.
+ dataPtr3->cameraPosition = cameraPosition;
+
+ // Unlock the camera constant buffer.
+ deviceContext->Unmap(m_cameraBuffer, 0);
+
+ // Set the position of the camera constant buffer in the vertex shader as the second buffer.
+ bufferNumber = 1;
+
+ // Now set the camera constant buffer in the vertex shader with the updated values.
+ deviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_cameraBuffer);
+
+ return true;
+}
+
+
+void SpecMapShaderClass::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 model.
+ deviceContext->VSSetShader(m_vertexShader, NULL, 0);
+ deviceContext->PSSetShader(m_pixelShader, NULL, 0);
+
+ // Set the sampler state in the pixel shader.
+ deviceContext->PSSetSamplers(0, 1, &m_sampleState);
+
+ // Render the model.
+ deviceContext->DrawIndexed(indexCount, 0, 0);
+
+ return;
+}
\ No newline at end of file
diff --git a/enginecustom/specmapshaderclass.h b/enginecustom/specmapshaderclass.h
new file mode 100644
index 0000000..e076c88
--- /dev/null
+++ b/enginecustom/specmapshaderclass.h
@@ -0,0 +1,72 @@
+#ifndef _SPECMAPSHADERCLASS_H_
+#define _SPECMAPSHADERCLASS_H_
+
+
+//////////////
+// INCLUDES //
+//////////////
+#include
+#include
+#include
+#include
+using namespace DirectX;
+using namespace std;
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Class name: SpecMapShaderClass
+////////////////////////////////////////////////////////////////////////////////
+class SpecMapShaderClass
+{
+private:
+ struct MatrixBufferType
+ {
+ XMMATRIX world;
+ XMMATRIX view;
+ XMMATRIX projection;
+ };
+
+ struct LightBufferType
+ {
+ XMFLOAT4 diffuseColor;
+ XMFLOAT4 specularColor;
+ float specularPower;
+ XMFLOAT3 lightDirection;
+ };
+
+ struct CameraBufferType
+ {
+ XMFLOAT3 cameraPosition;
+ float padding;
+ };
+
+public:
+ SpecMapShaderClass();
+ SpecMapShaderClass(const SpecMapShaderClass&);
+ ~SpecMapShaderClass();
+
+ bool Initialize(ID3D11Device*, HWND);
+ void Shutdown();
+ bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*,
+ XMFLOAT3, XMFLOAT4, XMFLOAT3, XMFLOAT4, float);
+
+private:
+ bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*);
+ void ShutdownShader();
+ void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*);
+
+ bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*,
+ XMFLOAT3, XMFLOAT4, XMFLOAT3, XMFLOAT4, float);
+ void RenderShader(ID3D11DeviceContext*, int);
+
+private:
+ ID3D11VertexShader* m_vertexShader;
+ ID3D11PixelShader* m_pixelShader;
+ ID3D11InputLayout* m_layout;
+ ID3D11Buffer* m_matrixBuffer;
+ ID3D11SamplerState* m_sampleState;
+ ID3D11Buffer* m_lightBuffer;
+ ID3D11Buffer* m_cameraBuffer;
+};
+
+#endif
\ No newline at end of file