diff --git a/enginecustom/Multitexture.ps b/enginecustom/Multitexture.ps new file mode 100644 index 0000000..f4f160d --- /dev/null +++ b/enginecustom/Multitexture.ps @@ -0,0 +1,45 @@ +//////////////////////////////////////////////////////////////////////////////// +// Filename: multitexture.ps +//////////////////////////////////////////////////////////////////////////////// + + +///////////// +// GLOBALS // +///////////// + +Texture2D shaderTexture1 : register(t0); +Texture2D shaderTexture2 : register(t1); +SamplerState SampleType : register(s0); + + +////////////// +// TYPEDEFS // +////////////// +struct PixelInputType +{ + float4 position : SV_POSITION; + float2 tex : TEXCOORD0; +}; + + +//////////////////////////////////////////////////////////////////////////////// +// Pixel Shader +//////////////////////////////////////////////////////////////////////////////// +float4 MultiTexturePixelShader(PixelInputType input) : SV_TARGET +{ + float4 color1; + float4 color2; + float4 blendColor; + + // Sample the pixel color from the textures using the sampler at this texture coordinate location. + color1 = shaderTexture1.Sample(SampleType, input.tex); + color2 = shaderTexture2.Sample(SampleType, input.tex); + + // Combine the two textures together. + blendColor = color1 * color2 * 2.0; + + // Saturate the final color. + blendColor = saturate(blendColor); + + return blendColor; +} diff --git a/enginecustom/Multitexture.vs b/enginecustom/Multitexture.vs new file mode 100644 index 0000000..f1261a6 --- /dev/null +++ b/enginecustom/Multitexture.vs @@ -0,0 +1,54 @@ +//////////////////////////////////////////////////////////////////////////////// +// Filename: multitexture.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; +}; + + +//////////////////////////////////////////////////////////////////////////////// +// Vertex Shader +//////////////////////////////////////////////////////////////////////////////// +PixelInputType MultiTextureVertexShader(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; +} diff --git a/enginecustom/Multitextureshaderclass.cpp b/enginecustom/Multitextureshaderclass.cpp new file mode 100644 index 0000000..7a9f63d --- /dev/null +++ b/enginecustom/Multitextureshaderclass.cpp @@ -0,0 +1,373 @@ +//////////////////////////////////////////////////////////////////////////////// +// Filename: multitextureshaderclass.cpp +//////////////////////////////////////////////////////////////////////////////// +#include "multitextureshaderclass.h" + + +MultiTextureShaderClass::MultiTextureShaderClass() +{ + m_vertexShader = 0; + m_pixelShader = 0; + m_layout = 0; + m_matrixBuffer = 0; + m_sampleState = 0; +} + + +MultiTextureShaderClass::MultiTextureShaderClass(const MultiTextureShaderClass& other) +{ +} + + +MultiTextureShaderClass::~MultiTextureShaderClass() +{ +} + + +bool MultiTextureShaderClass::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"multitexture.vs"); + if (error != 0) + { + return false; + } + + // Set the filename of the pixel shader. + error = wcscpy_s(psFilename, 128, L"multitexture.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 MultiTextureShaderClass::Shutdown() +{ + // Shutdown the vertex and pixel shaders as well as the related objects. + ShutdownShader(); + + return; +} + +bool MultiTextureShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, + XMMATRIX projectionMatrix, ID3D11ShaderResourceView* texture1, ID3D11ShaderResourceView* texture2) +{ + bool result; + + + // Set the shader parameters that it will use for rendering. + result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture1, texture2); + if (!result) + { + return false; + } + + // Now render the prepared buffers with the shader. + RenderShader(deviceContext, indexCount); + + return true; +} + +bool MultiTextureShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR* vsFilename, WCHAR* psFilename) +{ + HRESULT result; + ID3D10Blob* errorMessage; + ID3D10Blob* vertexShaderBuffer; + ID3D10Blob* pixelShaderBuffer; + D3D11_INPUT_ELEMENT_DESC polygonLayout[3]; + unsigned int numElements; + D3D11_BUFFER_DESC matrixBufferDesc; + D3D11_SAMPLER_DESC samplerDesc; + + + // Initialize the pointers this function will use to null. + errorMessage = 0; + vertexShaderBuffer = 0; + pixelShaderBuffer = 0; + + // Compile the vertex shader code. + result = D3DCompileFromFile(vsFilename, NULL, NULL, "MultiTextureVertexShader", "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, "MultiTexturePixelShader", "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; + + // Get a count of the elements in the layout. + numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]); + + // Create the vertex input layout. + result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(), + vertexShaderBuffer->GetBufferSize(), &m_layout); + if (FAILED(result)) + { + return false; + } + + // Release the vertex shader buffer and pixel shader buffer since they are no longer needed. + vertexShaderBuffer->Release(); + vertexShaderBuffer = 0; + + pixelShaderBuffer->Release(); + pixelShaderBuffer = 0; + + // Setup the description of the dynamic matrix constant buffer that is in the vertex shader. + matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + matrixBufferDesc.ByteWidth = sizeof(MatrixBufferType); + matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + matrixBufferDesc.MiscFlags = 0; + matrixBufferDesc.StructureByteStride = 0; + + // Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class. + result = device->CreateBuffer(&matrixBufferDesc, NULL, &m_matrixBuffer); + if (FAILED(result)) + { + return false; + } + + // Create a texture sampler state description. + samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.MipLODBias = 0.0f; + samplerDesc.MaxAnisotropy = 1; + samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + samplerDesc.BorderColor[0] = 0; + samplerDesc.BorderColor[1] = 0; + samplerDesc.BorderColor[2] = 0; + samplerDesc.BorderColor[3] = 0; + samplerDesc.MinLOD = 0; + samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; + + // Create the texture sampler state. + result = device->CreateSamplerState(&samplerDesc, &m_sampleState); + if (FAILED(result)) + { + return false; + } + + return true; +} + +void MultiTextureShaderClass::ShutdownShader() +{ + // Release the sampler state. + if (m_sampleState) + { + m_sampleState->Release(); + m_sampleState = 0; + } + + // Release the matrix constant buffer. + if (m_matrixBuffer) + { + m_matrixBuffer->Release(); + m_matrixBuffer = 0; + } + + // Release the layout. + if (m_layout) + { + m_layout->Release(); + m_layout = 0; + } + + // Release the pixel shader. + if (m_pixelShader) + { + m_pixelShader->Release(); + m_pixelShader = 0; + } + + // Release the vertex shader. + if (m_vertexShader) + { + m_vertexShader->Release(); + m_vertexShader = 0; + } + + return; +} + +void MultiTextureShaderClass::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 MultiTextureShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, + XMMATRIX projectionMatrix, ID3D11ShaderResourceView* texture1, ID3D11ShaderResourceView* texture2) +{ + HRESULT result; + D3D11_MAPPED_SUBRESOURCE mappedResource; + MatrixBufferType* dataPtr; + unsigned int bufferNumber; + + + // Transpose the matrices to prepare them for the shader. + worldMatrix = XMMatrixTranspose(worldMatrix); + viewMatrix = XMMatrixTranspose(viewMatrix); + projectionMatrix = XMMatrixTranspose(projectionMatrix); + + // Lock the constant buffer so it can be written to. + result = deviceContext->Map(m_matrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return false; + } + + // Get a pointer to the data in the constant buffer. + dataPtr = (MatrixBufferType*)mappedResource.pData; + + // Copy the matrices into the constant buffer. + dataPtr->world = worldMatrix; + dataPtr->view = viewMatrix; + dataPtr->projection = projectionMatrix; + + // Unlock the constant buffer. + deviceContext->Unmap(m_matrixBuffer, 0); + + // Set the position of the constant buffer in the vertex shader. + bufferNumber = 0; + + // 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); + + return true; +} + +void MultiTextureShaderClass::RenderShader(ID3D11DeviceContext* deviceContext, int indexCount) +{ + // Set the vertex input layout. + deviceContext->IASetInputLayout(m_layout); + + // Set the vertex and pixel shaders that will be used to render this triangle. + deviceContext->VSSetShader(m_vertexShader, NULL, 0); + deviceContext->PSSetShader(m_pixelShader, NULL, 0); + + // Set the sampler state in the pixel shader. + deviceContext->PSSetSamplers(0, 1, &m_sampleState); + + // Render the triangle. + deviceContext->DrawIndexed(indexCount, 0, 0); + + return; +} diff --git a/enginecustom/Multitextureshaderclass.h b/enginecustom/Multitextureshaderclass.h new file mode 100644 index 0000000..c22ff53 --- /dev/null +++ b/enginecustom/Multitextureshaderclass.h @@ -0,0 +1,57 @@ +//////////////////////////////////////////////////////////////////////////////// +// Filename: multitextureshaderclass.h +//////////////////////////////////////////////////////////////////////////////// +#ifndef _MULTITEXTURESHADERCLASS_H_ +#define _MULTITEXTURESHADERCLASS_H_ + + +////////////// +// INCLUDES // +////////////// +#include +#include +#include +#include +using namespace DirectX; +using namespace std; + + +//////////////////////////////////////////////////////////////////////////////// +// Class name: MultiTextureShaderClass +//////////////////////////////////////////////////////////////////////////////// +class MultiTextureShaderClass +{ +private: + struct MatrixBufferType + { + XMMATRIX world; + XMMATRIX view; + XMMATRIX projection; + }; + +public: + MultiTextureShaderClass(); + MultiTextureShaderClass(const MultiTextureShaderClass&); + ~MultiTextureShaderClass(); + + bool Initialize(ID3D11Device*, HWND); + void Shutdown(); + bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*); + +private: + bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*); + void ShutdownShader(); + void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*); + + bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*); + void RenderShader(ID3D11DeviceContext*, int); + +private: + ID3D11VertexShader* m_vertexShader; + ID3D11PixelShader* m_pixelShader; + ID3D11InputLayout* m_layout; + ID3D11Buffer* m_matrixBuffer; + ID3D11SamplerState* m_sampleState; +}; + +#endif diff --git a/enginecustom/applicationclass.cpp b/enginecustom/applicationclass.cpp index 3084822..388e678 100644 --- a/enginecustom/applicationclass.cpp +++ b/enginecustom/applicationclass.cpp @@ -3,7 +3,8 @@ ApplicationClass::ApplicationClass() { m_Direct3D = 0; - m_Camera = 0; + m_Camera = 0; + m_MultiTextureShader = 0; m_Model = 0; m_LightShader = 0; m_Light = 0; @@ -22,8 +23,7 @@ ApplicationClass::~ApplicationClass() bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) { - char modelFilename[128]; - char textureFilename[128]; + char modelFilename[128], textureFilename1[128], textureFilename2[128]; bool result; @@ -53,22 +53,34 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) m_Camera->SetPosition(0.0f, 0.0f, -5.0f); m_Camera->SetRotation(0.0f, 0.0f, 10.0f); + // Create and initialize the multitexture shader object. + m_MultiTextureShader = new MultiTextureShaderClass; + + result = m_MultiTextureShader->Initialize(m_Direct3D->GetDevice(), hwnd); + if (!result) + { + MessageBox(hwnd, L"Could not initialize the multitexture shader object.", L"Error", MB_OK); + return false; + } + // Set the file name of the model. strcpy_s(modelFilename, "cube.txt"); - // Set the name of the texture file that we will be loading. - strcpy_s(textureFilename, "stone01.tga"); + // Set the file name of the textures. + strcpy_s(textureFilename1, "stone01.tga"); + strcpy_s(textureFilename2, "moss01.tga"); // Create and initialize the model object. m_Model = new ModelClass; - result = m_Model->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, textureFilename); + result = m_Model->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, textureFilename1, textureFilename2); if (!result) { MessageBox(hwnd, L"Could not initialize the model object.", L"Error", MB_OK); return false; } + // Create and initialize the light shader object. m_LightShader = new LightShaderClass; @@ -81,8 +93,9 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) // Create and initialize the light object. m_Light = new LightClass; + m_Light->SetAmbientColor(0.15f, 0.15f, 0.15f, 1.0f); m_Light->SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f); - m_Light->SetDirection(0.0f, 0.0f, 1.0f); + m_Light->SetDirection(1.0f, 0.0f, 0.0f); return true; } @@ -113,6 +126,14 @@ void ApplicationClass::Shutdown() m_Model = 0; } + // Release the multitexture shader object. + if (m_MultiTextureShader) + { + m_MultiTextureShader->Shutdown(); + delete m_MultiTextureShader; + m_MultiTextureShader = 0; + } + // Release the camera object. if (m_Camera) { @@ -161,7 +182,6 @@ bool ApplicationClass::Render(float rotation) XMMATRIX worldMatrix, viewMatrix, projectionMatrix; bool result; - // Clear the buffers to begin the scene. m_Direct3D->BeginScene(0.0f, 0.0f, 0.0f, 1.0f); @@ -175,18 +195,28 @@ bool ApplicationClass::Render(float rotation) // 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. + // Render the model using the multitexture shader. 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(), - m_Light->GetDirection(), m_Light->GetDiffuseColor()); + result = m_LightShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(0), + m_Light->GetDirection(), m_Light->GetAmbientColor(), m_Light->GetDiffuseColor()); if (!result) { return false; } + + // Render the model using the multitexture shader. + result = m_MultiTextureShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, + m_Model->GetTexture(0), m_Model->GetTexture(1)); + if (!result) + { + return false; + } + // Present the rendered scene to the screen. m_Direct3D->EndScene(); return true; -} \ No newline at end of file +} + diff --git a/enginecustom/applicationclass.h b/enginecustom/applicationclass.h index dbd6973..ac2f097 100644 --- a/enginecustom/applicationclass.h +++ b/enginecustom/applicationclass.h @@ -10,6 +10,8 @@ #include "modelclass.h" #include "lightshaderclass.h" #include "lightclass.h" +#include "multitextureshaderclass.h" +#include "modelclass.h" ///////////// // GLOBALS // @@ -40,9 +42,10 @@ private: private: D3DClass* m_Direct3D; CameraClass* m_Camera; - ModelClass* m_Model; LightShaderClass* m_LightShader; LightClass* m_Light; + MultiTextureShaderClass* m_MultiTextureShader; + ModelClass* m_Model; }; #endif diff --git a/enginecustom/enginecustom.vcxproj b/enginecustom/enginecustom.vcxproj index aa0bfa9..f0bb46b 100644 --- a/enginecustom/enginecustom.vcxproj +++ b/enginecustom/enginecustom.vcxproj @@ -29,24 +29,28 @@ + - + + + + @@ -68,6 +72,8 @@ + + diff --git a/enginecustom/enginecustom.vcxproj.filters b/enginecustom/enginecustom.vcxproj.filters index f23eb24..87a4e5e 100644 --- a/enginecustom/enginecustom.vcxproj.filters +++ b/enginecustom/enginecustom.vcxproj.filters @@ -57,6 +57,9 @@ Fichiers sources + + Fichiers sources + @@ -83,10 +86,13 @@ Fichiers d%27en-tête - + Fichiers d%27en-tête - + + Fichiers d%27en-tête + + Fichiers d%27en-tête @@ -104,11 +110,19 @@ texture + + assets + + assets + + + assets + diff --git a/enginecustom/light.ps b/enginecustom/light.ps index 1a2da4e..f0fe5fb 100644 --- a/enginecustom/light.ps +++ b/enginecustom/light.ps @@ -11,6 +11,7 @@ SamplerState SampleType : register(s0); cbuffer LightBuffer { + float4 ambientColor; float4 diffuseColor; float3 lightDirection; float padding; @@ -42,17 +43,23 @@ float4 LightPixelShader(PixelInputType input) : SV_TARGET // Sample the pixel color from the texture using the sampler at this texture coordinate location. textureColor = shaderTexture.Sample(SampleType, input.tex); + // Set the default output color to the ambient light value for all pixels. + color = ambientColor; + // 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); + if(lightIntensity > 0.0f) + { + // Determine the final diffuse color based on the diffuse color and the amount of light intensity. + color += (diffuseColor * lightIntensity); + } - // Determine the final amount of diffuse color based on the diffuse color combined with the light intensity. - color = saturate(diffuseColor * lightIntensity); + // Saturate the final light color. + color = saturate(color); // Multiply the texture pixel and the final diffuse color to get the final pixel color result. color = color * textureColor; diff --git a/enginecustom/light.vs b/enginecustom/light.vs index 075270b..4a0b1f3 100644 --- a/enginecustom/light.vs +++ b/enginecustom/light.vs @@ -8,9 +8,9 @@ ///////////// cbuffer MatrixBuffer { - matrix worldMatrix; - matrix viewMatrix; - matrix projectionMatrix; + matrix worldMatrix; + matrix viewMatrix; + matrix projectionMatrix; }; @@ -21,14 +21,14 @@ struct VertexInputType { float4 position : POSITION; float2 tex : TEXCOORD0; - float3 normal : NORMAL; + float3 normal : NORMAL; }; struct PixelInputType { float4 position : SV_POSITION; float2 tex : TEXCOORD0; - float3 normal : NORMAL; + float3 normal : NORMAL; }; @@ -40,18 +40,18 @@ PixelInputType LightVertexShader(VertexInputType input) PixelInputType output; - // 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; - // Calculate the position of the vertex against the world, view, and projection matrices. + // 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; + // Store the texture coordinates for the pixel shader. + output.tex = input.tex; - // Calculate the normal vector against the world matrix only. + // Calculate the normal vector against the world matrix only. output.normal = mul(input.normal, (float3x3)worldMatrix); // Normalize the normal vector. diff --git a/enginecustom/lightclass.cpp b/enginecustom/lightclass.cpp index 05dcb4c..1626027 100644 --- a/enginecustom/lightclass.cpp +++ b/enginecustom/lightclass.cpp @@ -18,6 +18,13 @@ LightClass::~LightClass() { } +void LightClass::SetAmbientColor(float red, float green, float blue, float alpha) +{ + m_ambientColor = XMFLOAT4(red, green, blue, alpha); + return; +} + + void LightClass::SetDiffuseColor(float red, float green, float blue, float alpha) { @@ -32,6 +39,11 @@ void LightClass::SetDirection(float x, float y, float z) return; } +XMFLOAT4 LightClass::GetAmbientColor() +{ + return m_ambientColor; +} + XMFLOAT4 LightClass::GetDiffuseColor() { diff --git a/enginecustom/lightclass.h b/enginecustom/lightclass.h index d4c5273..e17e066 100644 --- a/enginecustom/lightclass.h +++ b/enginecustom/lightclass.h @@ -22,13 +22,16 @@ public: LightClass(const LightClass&); ~LightClass(); + void SetAmbientColor(float, float, float, float); void SetDiffuseColor(float, float, float, float); void SetDirection(float, float, float); + XMFLOAT4 GetAmbientColor(); XMFLOAT4 GetDiffuseColor(); XMFLOAT3 GetDirection(); private: + XMFLOAT4 m_ambientColor; XMFLOAT4 m_diffuseColor; XMFLOAT3 m_direction; }; diff --git a/enginecustom/lightshaderclass.cpp b/enginecustom/lightshaderclass.cpp index 02df0ff..637f870 100644 --- a/enginecustom/lightshaderclass.cpp +++ b/enginecustom/lightshaderclass.cpp @@ -34,14 +34,14 @@ bool LightShaderClass::Initialize(ID3D11Device* device, HWND hwnd) // Set the filename of the vertex shader. - error = wcscpy_s(vsFilename, 128, L"../enginecustom/light.vs"); + error = wcscpy_s(vsFilename, 128, L"light.vs"); if (error != 0) { return false; } // Set the filename of the pixel shader. - error = wcscpy_s(psFilename, 128, L"../enginecustom/light.ps"); + error = wcscpy_s(psFilename, 128, L"light.ps"); if (error != 0) { return false; @@ -68,13 +68,13 @@ void LightShaderClass::Shutdown() bool LightShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix, - ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 diffuseColor) + ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 ambientColor, XMFLOAT4 diffuseColor) { bool result; // Set the shader parameters that it will use for rendering. - result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, lightDirection, diffuseColor); + result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, lightDirection, ambientColor, diffuseColor); if(!result) { return false; @@ -340,8 +340,8 @@ 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, XMFLOAT3 lightDirection, XMFLOAT4 ambientColor, XMFLOAT4 diffuseColor) { HRESULT result; D3D11_MAPPED_SUBRESOURCE mappedResource; @@ -393,6 +393,7 @@ bool LightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, X dataPtr2 = (LightBufferType*)mappedResource.pData; // Copy the lighting variables into the constant buffer. + dataPtr2->ambientColor = ambientColor; dataPtr2->diffuseColor = diffuseColor; dataPtr2->lightDirection = lightDirection; dataPtr2->padding = 0.0f; diff --git a/enginecustom/lightshaderclass.h b/enginecustom/lightshaderclass.h index f16b097..950bd93 100644 --- a/enginecustom/lightshaderclass.h +++ b/enginecustom/lightshaderclass.h @@ -31,6 +31,7 @@ private: struct LightBufferType { + XMFLOAT4 ambientColor; XMFLOAT4 diffuseColor; XMFLOAT3 lightDirection; float padding; // Added extra padding so structure is a multiple of 16 for CreateBuffer function requirements. @@ -43,14 +44,14 @@ 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*, XMFLOAT3, 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*, XMFLOAT3, XMFLOAT4, XMFLOAT4); void RenderShader(ID3D11DeviceContext*, int); private: diff --git a/enginecustom/modelclass.cpp b/enginecustom/modelclass.cpp index 25846f3..1487a20 100644 --- a/enginecustom/modelclass.cpp +++ b/enginecustom/modelclass.cpp @@ -5,7 +5,7 @@ ModelClass::ModelClass() { m_vertexBuffer = 0; m_indexBuffer = 0; - m_Texture = 0; + m_Textures = 0; m_model = 0; } @@ -19,7 +19,7 @@ ModelClass::~ModelClass() { } -bool ModelClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceContext, char* modelFilename, char* textureFilename) +bool ModelClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceContext, char* modelFilename, char* textureFilename1, char* textureFilename2) { bool result; @@ -36,8 +36,8 @@ bool ModelClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceCon { return false; } - // Load the texture for this model. - result = LoadTexture(device, deviceContext, textureFilename); + // Load the textures for this model. + result = LoadTextures(device, deviceContext, textureFilename1, textureFilename2); if (!result) { return false; @@ -49,8 +49,8 @@ bool ModelClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceCon void ModelClass::Shutdown() { - // Release the model texture. - ReleaseTexture(); + // Release the model textures. + ReleaseTextures(); // Shutdown the vertex and index buffers. ShutdownBuffers(); @@ -76,9 +76,9 @@ int ModelClass::GetIndexCount() return m_indexCount; } -ID3D11ShaderResourceView* ModelClass::GetTexture() +ID3D11ShaderResourceView* ModelClass::GetTexture(int index) { - return m_Texture->GetTexture(); + return m_Textures[index].GetTexture(); } @@ -225,15 +225,21 @@ void ModelClass::RenderBuffers(ID3D11DeviceContext* deviceContext) return; } -bool ModelClass::LoadTexture(ID3D11Device* device, ID3D11DeviceContext* deviceContext, char* filename) +bool ModelClass::LoadTextures(ID3D11Device* device, ID3D11DeviceContext* deviceContext, char* filename1, char* filename2) { bool result; - // Create and initialize the texture object. - m_Texture = new TextureClass; + // Create and initialize the texture object array. + m_Textures = new TextureClass[2]; - result = m_Texture->Initialize(device, deviceContext, filename); + result = m_Textures[0].Initialize(device, deviceContext, filename1); + if (!result) + { + return false; + } + + result = m_Textures[1].Initialize(device, deviceContext, filename2); if (!result) { return false; @@ -242,14 +248,16 @@ bool ModelClass::LoadTexture(ID3D11Device* device, ID3D11DeviceContext* deviceCo return true; } -void ModelClass::ReleaseTexture() +void ModelClass::ReleaseTextures() { - // Release the texture object. - if (m_Texture) + // Release the texture object array. + if (m_Textures) { - m_Texture->Shutdown(); - delete m_Texture; - m_Texture = 0; + m_Textures[0].Shutdown(); + m_Textures[1].Shutdown(); + + delete[] m_Textures; + m_Textures = 0; } return; diff --git a/enginecustom/modelclass.h b/enginecustom/modelclass.h index 9ffdcda..b86693a 100644 --- a/enginecustom/modelclass.h +++ b/enginecustom/modelclass.h @@ -44,20 +44,19 @@ public: ModelClass(const ModelClass&); ~ModelClass(); - bool Initialize(ID3D11Device*, ID3D11DeviceContext*, char*, char*); + bool Initialize(ID3D11Device*, ID3D11DeviceContext*, char*, char*, char*); void Shutdown(); void Render(ID3D11DeviceContext*); int GetIndexCount(); - - ID3D11ShaderResourceView* GetTexture(); + ID3D11ShaderResourceView* GetTexture(int); private: bool InitializeBuffers(ID3D11Device*); void ShutdownBuffers(); void RenderBuffers(ID3D11DeviceContext*); - bool LoadTexture(ID3D11Device*, ID3D11DeviceContext*, char*); - void ReleaseTexture(); + bool LoadTextures(ID3D11Device*, ID3D11DeviceContext*, char*, char*); + void ReleaseTextures(); bool LoadModel(char*); void ReleaseModel(); @@ -65,8 +64,7 @@ private: private: ID3D11Buffer* m_vertexBuffer, * m_indexBuffer; int m_vertexCount, m_indexCount; - TextureClass* m_Texture; - + TextureClass* m_Textures; ModelType* m_model; }; diff --git a/enginecustom/moss01.tga b/enginecustom/moss01.tga new file mode 100644 index 0000000..68fb9e3 Binary files /dev/null and b/enginecustom/moss01.tga differ diff --git a/enginecustom/papier.tga b/enginecustom/papier.tga new file mode 100644 index 0000000..4f0b9b9 Binary files /dev/null and b/enginecustom/papier.tga differ