Merge branch 'main' into ImGui-V2

This commit is contained in:
CatChow0 2024-04-05 14:49:07 +02:00
commit 7cc9de3910
49 changed files with 5607 additions and 101 deletions

View File

@ -0,0 +1,68 @@
#include "modellistclass.h"
ModelListClass::ModelListClass()
{
m_ModelInfoList = 0;
}
ModelListClass::ModelListClass(const ModelListClass& other)
{
}
ModelListClass::~ModelListClass()
{
}
void ModelListClass::Initialize(int numModels)
{
int i;
// Store the number of models.
m_modelCount = numModels;
// Create a list array of the model information.
m_ModelInfoList = new ModelInfoType[m_modelCount];
// Seed the random generator with the current time.
srand((unsigned int)time(NULL));
// Go through all the models and randomly generate the position.
for (i = 0; i < m_modelCount; i++)
{
// Generate a random position in front of the viewer for the mode.
m_ModelInfoList[i].positionX = (((float)rand() - (float)rand()) / RAND_MAX) * 10.0f;
m_ModelInfoList[i].positionY = (((float)rand() - (float)rand()) / RAND_MAX) * 10.0f;
m_ModelInfoList[i].positionZ = ((((float)rand() - (float)rand()) / RAND_MAX) * 10.0f) + 5.0f;
}
return;
}
void ModelListClass::Shutdown()
{
// Release the model information list.
if (m_ModelInfoList)
{
delete[] m_ModelInfoList;
m_ModelInfoList = 0;
}
return;
}
int ModelListClass::GetModelCount()
{
return m_modelCount;
}
void ModelListClass::GetData(int index, float& positionX, float& positionY, float& positionZ)
{
positionX = m_ModelInfoList[index].positionX;
positionY = m_ModelInfoList[index].positionY;
positionZ = m_ModelInfoList[index].positionZ;
return;
}

View File

@ -0,0 +1,39 @@
#ifndef _MODELLISTCLASS_H_
#define _MODELLISTCLASS_H_
//////////////
// INCLUDES //
//////////////
#include <stdlib.h>
#include <time.h>
///////////////////////////////////////////////////////////////////////////////
// Class name: ModelListClass
///////////////////////////////////////////////////////////////////////////////
class ModelListClass
{
private:
struct ModelInfoType
{
float positionX, positionY, positionZ;
};
public:
ModelListClass();
ModelListClass(const ModelListClass&);
~ModelListClass();
void Initialize(int);
void Shutdown();
int GetModelCount();
void GetData(int, float&, float&, float&);
private:
int m_modelCount;
ModelInfoType* m_ModelInfoList;
};
#endif

View File

@ -0,0 +1,202 @@
#include "positionclass.h"
PositionClass::PositionClass()
{
m_frameTime = 0.0f;
m_rotationY = 0.0f;
m_rotationX = 0.0f;
m_positionX = 0.0f;
m_positionY = 0.0f;
m_positionZ = 0.0f;
m_leftTurnSpeed = 0.0f;
m_rightTurnSpeed = 0.0f;
}
PositionClass::PositionClass(const PositionClass& other)
{
}
PositionClass::~PositionClass()
{
}
void PositionClass::SetFrameTime(float time)
{
m_frameTime = time;
return;
}
void PositionClass::GetRotation(float& y, float& x)
{
y = m_rotationY;
x = m_rotationX;
return;
}
void PositionClass::GetPosition(float& x, float& y, float& z)
{
x = m_positionX;
y = m_positionY;
z = m_positionZ;
return;
}
void PositionClass::TurnLeft(bool keydown)
{
// If the key is pressed increase the speed at which the camera turns left. If not slow down the turn speed.
if (keydown)
{
m_leftTurnSpeed += m_frameTime * 1.5f;
if (m_leftTurnSpeed > (m_frameTime * 200.0f))
{
m_leftTurnSpeed = m_frameTime * 200.0f;
}
}
else
{
m_leftTurnSpeed -= m_frameTime * 1.0f;
if (m_leftTurnSpeed < 0.0f)
{
m_leftTurnSpeed = 0.0f;
}
}
// Update the rotation using the turning speed.
m_rotationY -= m_leftTurnSpeed;
if (m_rotationY < 0.0f)
{
m_rotationY += 360.0f;
}
return;
}
void PositionClass::TurnRight(bool keydown)
{
// If the key is pressed increase the speed at which the camera turns right. If not slow down the turn speed.
if (keydown)
{
m_rightTurnSpeed += m_frameTime * 1.5f;
if (m_rightTurnSpeed > (m_frameTime * 200.0f))
{
m_rightTurnSpeed = m_frameTime * 200.0f;
}
}
else
{
m_rightTurnSpeed -= m_frameTime * 1.0f;
if (m_rightTurnSpeed < 0.0f)
{
m_rightTurnSpeed = 0.0f;
}
}
// Update the rotation using the turning speed.
m_rotationY += m_rightTurnSpeed;
if (m_rotationY > 360.0f)
{
m_rotationY -= 360.0f;
}
return;
}
void PositionClass::TurnMouse(float deltaX, float deltaY)
{
float speed = 0.1f;
// The turning speed is proportional to the horizontal mouse movement
m_horizontalTurnSpeed = deltaX * speed;
// Update the rotation using the turning speed
m_rotationY += m_horizontalTurnSpeed;
if (m_rotationY < 0.0f)
{
m_rotationY += 360.0f;
}
else if (m_rotationY > 360.0f)
{
m_rotationY -= 360.0f;
}
// The turning speed is proportional to the vertical mouse movement
m_verticalTurnSpeed = deltaY * speed;
// Update the rotation using the turning speed
m_rotationX += m_verticalTurnSpeed;
if (m_rotationX < -90.0f)
{
m_rotationX = -90.0f;
}
else if (m_rotationX > 90.0f)
{
m_rotationX = 90.0f;
}
return;
}
void PositionClass::MoveCamera(bool forward, bool backward, bool left, bool right, bool up, bool down)
{
float radiansY, radiansX;
float speed;
// Set the speed of the camera.
speed = 2.0f * m_frameTime;
// Convert degrees to radians.
radiansY = m_rotationY * 0.0174532925f;
radiansX = m_rotationX * 0.0174532925f;
// Update the position.
// If moving forward, the position moves in the direction of the camera and accordingly to its angle.
if (forward)
{
m_positionX += sinf(radiansY) * cosf(radiansX) * speed;
m_positionZ += cosf(radiansY) * cosf(radiansX) * speed;
m_positionY -= sinf(radiansX) * speed;
}
// If moving backward, the position moves in the opposite direction of the camera and accordingly to its angle.
if (backward)
{
m_positionX -= sinf(radiansY) * cosf(radiansX) * speed;
m_positionZ -= cosf(radiansY) * cosf(radiansX) * speed;
m_positionY += sinf(radiansX) * speed;
}
// If moving left, the position moves to the left of the camera and accordingly to its angle.
if (left)
{
m_positionX -= cosf(radiansY) * speed;
m_positionZ += sinf(radiansY) * speed;
}
// If moving right, the position moves to the right of the camera and accordingly to its angle.
if (right)
{
m_positionX += cosf(radiansY) * speed;
m_positionZ -= sinf(radiansY) * speed;
}
// If moving up, the position moves up.
if (up)
{
m_positionY += speed;
}
// If moving down, the position moves down.
if (down)
{
m_positionY -= speed;
}
return;
}

View File

@ -0,0 +1,37 @@
#ifndef _POSITIONCLASS_H_
#define _POSITIONCLASS_H_
//////////////
// INCLUDES //
//////////////
#include <math.h>
////////////////////////////////////////////////////////////////////////////////
// Class name: PositionClass
////////////////////////////////////////////////////////////////////////////////
class PositionClass
{
public:
PositionClass();
PositionClass(const PositionClass&);
~PositionClass();
void SetFrameTime(float);
void GetRotation(float&, float&);
void GetPosition(float&, float&, float&);
void TurnLeft(bool);
void TurnRight(bool);
void TurnMouse(float, float);
void MoveCamera(bool, bool, bool, bool, bool, bool);
private:
float m_frameTime;
float m_rotationY, m_rotationX;
float m_positionX, m_positionY, m_positionZ;
float m_leftTurnSpeed, m_rightTurnSpeed, m_horizontalTurnSpeed, m_verticalTurnSpeed;
};
#endif

View File

@ -39,7 +39,12 @@ bool SystemClass::Initialize()
// Create and initialize the input object. This object will be used to handle reading the keyboard input from the user.
m_Input = new InputClass;
m_Input->Initialize();
result = m_Input->Initialize(m_hinstance, m_hwnd, screenWidth, screenHeight);
if (!result)
{
return false;
}
// Create and initialize the application class object. This object will handle rendering all the graphics for this application.
m_Application = new ApplicationClass;
@ -140,15 +145,15 @@ bool SystemClass::Frame()
{
bool result;
// Check if the user pressed escape and wants to exit the application.
if (m_Input->IsKeyDown(VK_ESCAPE))
// Do the input frame processing.
result = m_Input->Frame();
if (!result)
{
return false;
}
// Do the frame processing for the application class object.
result = m_Application->Frame();
result = m_Application->Frame(m_Input);
if (!result)
{
return false;

View File

@ -0,0 +1,13 @@
<Page
x:Class="enginecustom.Translate"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:enginecustom"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button x:Name="Button" Click="ClickHandler">Click Me</Button>
</StackPanel>
</Page>

BIN
enginecustom/alpha01.tga Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

45
enginecustom/alphamap.ps Normal file
View File

@ -0,0 +1,45 @@
/////////////
// GLOBALS //
/////////////
Texture2D shaderTexture1 : register(t0);
Texture2D shaderTexture2 : register(t1);
Texture2D shaderTexture3 : register(t2);
SamplerState SampleType : register(s0);
//////////////
// TYPEDEFS //
//////////////
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
};
////////////////////////////////////////////////////////////////////////////////
// Pixel Shader
////////////////////////////////////////////////////////////////////////////////
float4 AlphaMapPixelShader(PixelInputType input) : SV_TARGET
{
float4 color1;
float4 color2;
float4 alphaValue;
float4 blendColor;
// Get the pixel color from the first texture.
color1 = shaderTexture1.Sample(SampleType, input.tex);
// Get the pixel color from the second texture.
color2 = shaderTexture2.Sample(SampleType, input.tex);
// Get the pixel color from the alpha texture.
alphaValue = shaderTexture3.Sample(SampleType, input.tex);
// Combine the two textures based on the alpha value.
blendColor = (alphaValue * color1) + ((1.0 - alphaValue) * color2);
// Saturate the final color value.
blendColor = saturate(blendColor);
return blendColor;
}

49
enginecustom/alphamap.vs Normal file
View File

@ -0,0 +1,49 @@
/////////////
// 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 AlphaMapVertexShader(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;
}

View File

@ -0,0 +1,378 @@
#include "alphamapshaderclass.h"
AlphaMapShaderClass::AlphaMapShaderClass()
{
m_vertexShader = 0;
m_pixelShader = 0;
m_layout = 0;
m_matrixBuffer = 0;
m_sampleState = 0;
}
AlphaMapShaderClass::AlphaMapShaderClass(const AlphaMapShaderClass& other)
{
}
AlphaMapShaderClass::~AlphaMapShaderClass()
{
}
bool AlphaMapShaderClass::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"alphamap.vs");
if (error != 0)
{
return false;
}
// Set the filename of the pixel shader.
error = wcscpy_s(psFilename, 128, L"alphamap.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 AlphaMapShaderClass::Shutdown()
{
// Shutdown the vertex and pixel shaders as well as the related objects.
ShutdownShader();
return;
}
bool AlphaMapShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture1, ID3D11ShaderResourceView* texture2, ID3D11ShaderResourceView* texture3)
{
bool result;
// Set the shader parameters that it will use for rendering.
result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture1, texture2, texture3);
if (!result)
{
return false;
}
// Now render the prepared buffers with the shader.
RenderShader(deviceContext, indexCount);
return true;
}
bool AlphaMapShaderClass::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, "AlphaMapVertexShader", "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, "AlphaMapPixelShader", "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 AlphaMapShaderClass::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 AlphaMapShaderClass::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 AlphaMapShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture1, ID3D11ShaderResourceView* texture2, ID3D11ShaderResourceView* texture3)
{
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);
deviceContext->PSSetShaderResources(2, 1, &texture3);
return true;
}
void AlphaMapShaderClass::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;
}

View File

@ -0,0 +1,54 @@
#ifndef _ALPHAMAPSHADERCLASS_H_
#define _ALPHAMAPSHADERCLASS_H_
//////////////
// INCLUDES //
//////////////
#include <d3d11.h>
#include <d3dcompiler.h>
#include <directxmath.h>
#include <fstream>
using namespace DirectX;
using namespace std;
////////////////////////////////////////////////////////////////////////////////
// Class name: AlphaMapShaderClass
////////////////////////////////////////////////////////////////////////////////
class AlphaMapShaderClass
{
private:
struct MatrixBufferType
{
XMMATRIX world;
XMMATRIX view;
XMMATRIX projection;
};
public:
AlphaMapShaderClass();
AlphaMapShaderClass(const AlphaMapShaderClass&);
~AlphaMapShaderClass();
bool Initialize(ID3D11Device*, HWND);
void Shutdown();
bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*);
private:
bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*);
void ShutdownShader();
void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*);
bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*);
void RenderShader(ID3D11DeviceContext*, int);
private:
ID3D11VertexShader* m_vertexShader;
ID3D11PixelShader* m_pixelShader;
ID3D11InputLayout* m_layout;
ID3D11Buffer* m_matrixBuffer;
ID3D11SamplerState* m_sampleState;
};
#endif

View File

@ -5,14 +5,16 @@ ApplicationClass::ApplicationClass()
m_Direct3D = 0;
m_Camera = 0;
m_MultiTextureShader = 0;
m_AlphaMapShader = 0;
m_Model = 0;
m_LightShader = 0;
m_LightMapShader = 0;
m_Light = 0;
m_TextureShader = 0;
m_Bitmap = 0;
m_Sprite = 0;
m_Timer = 0;
m_Lights = 0;
m_MouseStrings = 0;
m_FontShader = 0;
m_Font = 0;
m_TextString1 = 0;
@ -20,6 +22,13 @@ ApplicationClass::ApplicationClass()
m_TextString3 = 0;
m_Fps = 0;
m_FpsString = 0;
m_NormalMapShader = 0;
m_SpecMapShader = 0;
m_RenderCountString = 0;
m_ModelList = 0;
m_Position = 0;
m_Frustum = 0;
m_DisplayPlane = 0;
}
@ -35,14 +44,17 @@ ApplicationClass::~ApplicationClass()
bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
{
char mouseString1[32], mouseString2[32], mouseString3[32];
char testString1[32], testString2[32], testString3[32];
char modelFilename[128];
char textureFilename1[128], textureFilename2[128];
char modelFilename[128], textureFilename1[128], textureFilename2[128], textureFilename3[128], renderString[32];
char bitmapFilename[128];
char spriteFilename[128];
char fpsString[32];
bool result;
m_screenWidth = screenWidth;
m_screenHeight = screenHeight;
// Create the Direct3D object.
m_Direct3D = new D3DClass;
if (!m_Direct3D)
@ -69,6 +81,28 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
// Set the initial position of the camera.
m_Camera->SetPosition(0.0f, 0.0f, -12.0f);
m_Camera->SetRotation(0.0f, 0.0f, 0.0f);
m_Camera->Render();
m_Camera->GetViewMatrix(m_baseViewMatrix);
// 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;
result = m_NormalMapShader->Initialize(m_Direct3D->GetDevice(), hwnd);
if (!result)
{
MessageBox(hwnd, L"Could not initialize the normal map shader object.", L"Error", MB_OK);
return false;
}
// Create and initialize the font shader object.
m_FontShader = new FontShaderClass;
@ -131,6 +165,25 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
return false;
}
// Create and initialize the render to texture object.
m_RenderTexture = new RenderTextureClass;
result = m_RenderTexture->Initialize(m_Direct3D->GetDevice(), 256, 256, SCREEN_DEPTH, SCREEN_NEAR, 1);
if (!result)
{
return false;
}
// Create and initialize the display plane object.
m_DisplayPlane = new DisplayPlaneClass;
result = m_DisplayPlane->Initialize(m_Direct3D->GetDevice(), 1.0f, 1.0f);
if (!result)
{
return false;
}
// Set the sprite info file we will be using.
strcpy_s(spriteFilename, "sprite_data_01.txt");
@ -143,10 +196,27 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
return false;
}
// Create and initialize the timer object.
m_Timer = new TimerClass;
// Set the initial mouse strings.
strcpy_s(mouseString1, "Mouse X: 0");
strcpy_s(mouseString2, "Mouse Y: 0");
strcpy_s(mouseString3, "Mouse Button: No");
result = m_Timer->Initialize();
// Create and initialize the text objects for the mouse strings.
m_MouseStrings = new TextClass[3];
result = m_MouseStrings[0].Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), screenWidth, screenHeight, 32, m_Font, mouseString1, 10, 10, 1.0f, 1.0f, 1.0f);
if (!result)
{
return false;
}
result = m_MouseStrings[1].Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), screenWidth, screenHeight, 32, m_Font, mouseString1, 10, 35, 1.0f, 1.0f, 1.0f);
if (!result)
{
return false;
}
result = m_MouseStrings[2].Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), screenWidth, screenHeight, 32, m_Font, mouseString1, 10, 60, 1.0f, 1.0f, 1.0f);
if (!result)
{
return false;
@ -179,12 +249,14 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
// Set the file name of the textures.
strcpy_s(textureFilename1, "stone01.tga");
strcpy_s(textureFilename2, "moss01.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;
result = m_Model->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, textureFilename1, textureFilename2);
result = m_Model->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, textureFilename1, textureFilename2, textureFilename3);
if (!result)
{
MessageBox(hwnd, L"Could not initialize the model object.", L"Error", MB_OK);
@ -202,6 +274,14 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
return false;
}
// Create and initialize the light object.
m_Light = new LightClass;
m_Light->SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f);
m_Light->SetDirection(0.0f, 0.0f, 1.0f);
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;
@ -221,6 +301,76 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
m_Lights[3].SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f); // White
m_Lights[3].SetPosition(3.0f, 1.0f, -3.0f);
// Create and initialize the light map shader object.
m_LightMapShader = new LightMapShaderClass;
result = m_LightMapShader->Initialize(m_Direct3D->GetDevice(), hwnd);
if (!result)
{
MessageBox(hwnd, L"Could not initialize the light map shader object.", L"Error", MB_OK);
return false;
}
// Create and initialize the alpha map shader object.
m_AlphaMapShader = new AlphaMapShaderClass;
result = m_AlphaMapShader->Initialize(m_Direct3D->GetDevice(), hwnd);
if (!result)
{
MessageBox(hwnd, L"Could not initialize the alpha map shader object.", L"Error", MB_OK);
return false;
}
// Create and initialize the font shader object.
m_FontShader = new FontShaderClass;
result = m_FontShader->Initialize(m_Direct3D->GetDevice(), hwnd);
if (!result)
{
MessageBox(hwnd, L"Could not initialize the font shader object.", L"Error", MB_OK);
return false;
}
// Create and initialize the font object.
m_Font = new FontClass;
result = m_Font->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), 0);
if (!result)
{
return false;
}
// Set the initial render count string.
strcpy_s(renderString, "Render Count: 0");
// Create and initialize the text object for the render count string.
m_RenderCountString = new TextClass;
result = m_RenderCountString->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), screenWidth, screenHeight, 32, m_Font, renderString, 10, 10, 1.0f, 1.0f, 1.0f);
if (!result)
{
return false;
}
// Create and initialize the model list object.
m_ModelList = new ModelListClass;
m_ModelList->Initialize(25);
// Create and initialize the timer object.
m_Timer = new TimerClass;
result = m_Timer->Initialize();
if (!result)
{
return false;
}
// Create the position class object.
m_Position = new PositionClass;
// Create the frustum class object.
m_Frustum = new FrustumClass;
// Create and initialize the fps object.
m_Fps = new FpsClass();
@ -246,6 +396,54 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
void ApplicationClass::Shutdown()
{
// Release the frustum class object.
if (m_Frustum)
{
delete m_Frustum;
m_Frustum = 0;
}
// Release the display plane object.
if (m_DisplayPlane)
{
m_DisplayPlane->Shutdown();
delete m_DisplayPlane;
m_DisplayPlane = 0;
}
// Release the position object.
if (m_Position)
{
delete m_Position;
m_Position = 0;
}
// Release the model list object.
if (m_ModelList)
{
m_ModelList->Shutdown();
delete m_ModelList;
m_ModelList = 0;
}
// Release the text objects for the render count string.
if (m_RenderCountString)
{
m_RenderCountString->Shutdown();
delete m_RenderCountString;
m_RenderCountString = 0;
}
// Release the text objects for the mouse strings.
if (m_MouseStrings)
{
m_MouseStrings[0].Shutdown();
m_MouseStrings[1].Shutdown();
m_MouseStrings[2].Shutdown();
delete[] m_MouseStrings;
m_MouseStrings = 0;
}
// Release the text object for the fps string.
if (m_FpsString)
{
@ -261,7 +459,6 @@ void ApplicationClass::Shutdown()
m_Fps = 0;
}
// Release the text string objects.
if (m_TextString3)
{
@ -330,20 +527,20 @@ void ApplicationClass::Shutdown()
m_LightShader = 0;
}
// Release the light shader object.
if (m_LightShader)
// Release the specular map shader object.
if (m_SpecMapShader)
{
m_LightShader->Shutdown();
delete m_LightShader;
m_LightShader = 0;
m_SpecMapShader->Shutdown();
delete m_SpecMapShader;
m_SpecMapShader = 0;
}
// Release the model object.
if (m_Model)
// Release the normal map shader object.
if (m_NormalMapShader)
{
m_Model->Shutdown();
delete m_Model;
m_Model = 0;
m_NormalMapShader->Shutdown();
delete m_NormalMapShader;
m_NormalMapShader = 0;
}
// Liberez la memoire pour chaque cube
@ -408,17 +605,93 @@ void ApplicationClass::Shutdown()
return;
}
// Release the alpha map shader object.
if (m_AlphaMapShader)
{
m_AlphaMapShader->Shutdown();
delete m_AlphaMapShader;
m_AlphaMapShader = 0;
}
}
bool ApplicationClass::Frame()
bool ApplicationClass::Frame(InputClass* Input)
{
int mouseX, mouseY, currentMouseX, currentMouseY;
bool result, mouseDown, keyDown, buttonQ, buttonD, buttonZ, buttonS, buttonA, buttonE;
float rotationY, rotationX, positionX, positionY, positionZ;
float frameTime;
static float rotation = 0.0f;
static float x = 2.f;
static float y = 0.f;
static int lastMouseX = 0, lastMouseY = 0;
static float rotation = 360.0f;
static float x = 6.f;
static float y = 3.f;
static float z = 0.f;
bool result;
// Update the system stats.
m_Timer->Frame();
// Get the current frame time.
frameTime = m_Timer->GetTime();
// Check if the user pressed escape and wants to exit the application.
if (Input->IsEscapePressed())
{
return false;
}
// Get the location of the mouse from the input object,
Input->GetMouseLocation(mouseX, mouseY);
currentMouseX = mouseX;
float deltaX = currentMouseX - lastMouseX; // Calculez le d<>placement de la souris
lastMouseX = currentMouseX; // Mettez <20> jour la derni<6E>re position de la souris pour la prochaine image
currentMouseY = mouseY;
float deltaY = currentMouseY - lastMouseY; // Calculez le d<>placement de la souris
lastMouseY = currentMouseY; // Mettez <20> jour la derni<6E>re position de la souris pour la prochaine image
// Set the frame time for calculating the updated position.
m_Position->SetFrameTime(m_Timer->GetTime());
// Check if the left or right arrow key has been pressed, if so rotate the camera accordingly.
keyDown = Input->IsLeftArrowPressed();
m_Position->TurnLeft(keyDown);
keyDown = Input->IsRightArrowPressed();
m_Position->TurnRight(keyDown);
m_Position->TurnMouse(deltaX, deltaY);
// Get the current view point rotation.
m_Position->GetRotation(rotationY, rotationX);
// Check if the a(q), d, w(z), s, q(a), e have been pressed, if so move the camera accordingly.
buttonQ = Input->IsAPressed();
buttonD = Input->IsDPressed();
buttonZ = Input->IsWPressed();
buttonS = Input->IsSPressed();
buttonA = Input->IsQPressed();
buttonE = Input->IsEPressed();
m_Position->MoveCamera(buttonZ, buttonS, buttonQ, buttonD, buttonE, buttonA);
m_Position->GetPosition(positionX, positionY, positionZ);
// Set the postion and rotation of the camera.
m_Camera->SetPosition(positionX, positionY, positionZ);
m_Camera->SetRotation(rotationX, rotationY, 0.0f);
m_Camera->Render();
// Render the graphics scene.
result = Render(rotation, x, y, z);
if (!result)
{
return false;
}
// Update the frames per second each frame.
result = UpdateFps();
@ -435,13 +708,19 @@ bool ApplicationClass::Frame()
}
// Update the x position variable each frame.
x -= 0.0174532925f * 0.54672f;
x -= 0.0174532925f * 0.6f;
y -= 0.0174532925f * 0.8972f;
y -= 0.0174532925f * 0.2f;
// Update the z position variable each frame.
z -= 0.0174532925f * 0.8972f;
z -= 0.0174532925f * 0.2f;
// Render the scene to a render texture.
result = RenderSceneToTexture(rotation);
if (!result)
{
return false;
}
// Render the graphics scene.
result = Render(rotation, x, y, z);
@ -450,11 +729,15 @@ bool ApplicationClass::Frame()
return false;
}
// Update the system stats.
m_Timer->Frame();
// Check if the mouse has been pressed.
mouseDown = Input->IsMousePressed();
// Get the current frame time.
frameTime = m_Timer->GetTime();
// Update the mouse strings each frame.
result = UpdateMouseStrings(mouseX, mouseY, mouseDown);
if (!result)
{
return false;
}
// Update the sprite object using the frame time.
m_Sprite->Update(frameTime);
@ -462,34 +745,180 @@ bool ApplicationClass::Frame()
return true;
}
bool ApplicationClass::RenderSceneToTexture(float rotation)
{
XMMATRIX worldMatrix, viewMatrix, projectionMatrix;
bool result;
// Set the render target to be the render texture and clear it.
m_RenderTexture->SetRenderTarget(m_Direct3D->GetDeviceContext());
m_RenderTexture->ClearRenderTarget(m_Direct3D->GetDeviceContext(), 0.0f, 0.5f, 1.0f, 1.0f);
// Set the position of the camera for viewing the cube.
m_Camera->SetPosition(0.0f, 0.0f, -5.0f);
m_Camera->Render();
// Get the matrices.
m_Direct3D->GetWorldMatrix(worldMatrix);
m_Camera->GetViewMatrix(viewMatrix);
m_RenderTexture->GetProjectionMatrix(projectionMatrix);
// Rotate the world matrix by the rotation value so that the cube will spin.
worldMatrix = XMMatrixRotationY(rotation);
// Render the model using the texture shader.
m_Model->Render(m_Direct3D->GetDeviceContext());
result = m_TextureShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(1));
if (!result)
{
return false;
}
// Reset the render target back to the original back buffer and not the render to texture anymore. And reset the viewport back to the original.
m_Direct3D->SetBackBufferRenderTarget();
m_Direct3D->ResetViewport();
return true;
}
bool ApplicationClass::Render(float rotation, float x, float y, float z)
{
XMMATRIX worldMatrix, viewMatrix, orthoMatrix, projectionMatrix, rotateMatrix, translateMatrix, scaleMatrix, srMatrix;
float positionX, positionY, positionZ, radius;
XMFLOAT4 diffuseColor[4], lightPosition[4];
int i;
bool result;
int modelCount, renderCount, i;
bool result, renderModel;
// Clear the buffers to begin the scene.
m_Direct3D->BeginScene(0.0f, 0.0f, 0.0f, 1.0f);
// Generate the view matrix based on the camera's position.
m_Camera->SetPosition(0.0f, 0.0f, -10.0f);
m_Camera->Render();
// Get the world, view, and projection matrices from the camera and d3d objects.
m_Direct3D->GetWorldMatrix(worldMatrix);
viewMatrix = m_Camera->GetViewMatrix();
m_Camera->GetViewMatrix(viewMatrix);
m_Direct3D->GetProjectionMatrix(projectionMatrix);
m_Direct3D->GetOrthoMatrix(orthoMatrix);
// Setup matrices - Top display plane.
worldMatrix = XMMatrixTranslation(0.0f, 1.5f, 0.0f);
// Render the display plane using the texture shader and the render texture resource.
m_DisplayPlane->Render(m_Direct3D->GetDeviceContext());
result = m_TextureShader->Render(m_Direct3D->GetDeviceContext(), m_DisplayPlane->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_RenderTexture->GetShaderResourceView());
if (!result)
{
return false;
}
// Setup matrices - Bottom left display plane.
worldMatrix = XMMatrixTranslation(-1.5f, -1.5f, 0.0f);
// Render the display plane using the texture shader and the render texture resource.
m_DisplayPlane->Render(m_Direct3D->GetDeviceContext());
result = m_TextureShader->Render(m_Direct3D->GetDeviceContext(), m_DisplayPlane->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_RenderTexture->GetShaderResourceView());
if (!result)
{
return false;
}
// Setup matrices - Bottom right display plane.
worldMatrix = XMMatrixTranslation(1.5f, -1.5f, 0.0f);
// Render the display plane using the texture shader and the render texture resource.
m_DisplayPlane->Render(m_Direct3D->GetDeviceContext());
result = m_TextureShader->Render(m_Direct3D->GetDeviceContext(), m_DisplayPlane->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_RenderTexture->GetShaderResourceView());
if (!result)
{
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();
}
// Construct the frustum.
m_Frustum->ConstructFrustum(viewMatrix, projectionMatrix, SCREEN_DEPTH);
// Get the number of models that will be rendered.
modelCount = m_ModelList->GetModelCount();
// Initialize the count of models that have been rendered.
renderCount = 0;
// Go through all the models and render them only if they can be seen by the camera view.
for (i = 0; i < modelCount; i++)
{
// Get the position and color of the sphere model at this index.
m_ModelList->GetData(i, positionX, positionY, positionZ);
// Set the radius of the sphere to 1.0 since this is already known.
radius = 1.0f;
// Check if the sphere model is in the view frustum.
renderModel = m_Frustum->CheckSphere(positionX, positionY, positionZ, radius);
// If it can be seen then render it, if not skip this model and check the next sphere.
if (renderModel)
{
// Move the model to the location it should be rendered at.
worldMatrix = XMMatrixTranslation(positionX, positionY, positionZ);
// Render the model using the light shader.
m_Model->Render(m_Direct3D->GetDeviceContext());
result = m_LightShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix,
m_Model->GetTexture(0), diffuseColor, lightPosition);
if (!result)
{
return false;
}
// Since this model was rendered then increase the count for this frame.
renderCount++;
}
}
// Update the render count text.
result = UpdateRenderCountString(renderCount);
if (!result)
{
return false;
}
// Disable the Z buffer and enable alpha blending for 2D rendering.
m_Direct3D->TurnZBufferOff();
m_Direct3D->EnableAlphaBlending();
// Reset the world matrix.
m_Direct3D->GetWorldMatrix(worldMatrix);
// Render the render count text string using the font shader.
m_RenderCountString->Render(m_Direct3D->GetDeviceContext());
result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_RenderCountString->GetIndexCount(), worldMatrix, m_baseViewMatrix, orthoMatrix,
m_Font->GetTexture(), m_RenderCountString->GetPixelColor());
if (!result)
{
return false;
}
// Render the fps text string using the font shader.
m_FpsString->Render(m_Direct3D->GetDeviceContext());
result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_FpsString->GetIndexCount(), worldMatrix, viewMatrix, orthoMatrix,
result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_FpsString->GetIndexCount(), worldMatrix, m_baseViewMatrix, orthoMatrix,
m_Font->GetTexture(), m_FpsString->GetPixelColor());
if (!result)
{
@ -499,7 +928,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z)
// Render the first text string using the font shader.
m_TextString1->Render(m_Direct3D->GetDeviceContext());
result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_TextString1->GetIndexCount(), worldMatrix, viewMatrix, orthoMatrix,
result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_TextString1->GetIndexCount(), worldMatrix, m_baseViewMatrix, orthoMatrix,
m_Font->GetTexture(), m_TextString1->GetPixelColor());
if (!result)
{
@ -509,7 +938,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z)
// Render the second text string using the font shader.
m_TextString2->Render(m_Direct3D->GetDeviceContext());
result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_TextString2->GetIndexCount(), worldMatrix, viewMatrix, orthoMatrix,
result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_TextString2->GetIndexCount(), worldMatrix, m_baseViewMatrix, orthoMatrix,
m_Font->GetTexture(), m_TextString2->GetPixelColor());
if (!result)
{
@ -519,13 +948,26 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z)
// Render the second text string using the font shader.
m_TextString3->Render(m_Direct3D->GetDeviceContext());
result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_TextString3->GetIndexCount(), worldMatrix, viewMatrix, orthoMatrix,
result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_TextString3->GetIndexCount(), worldMatrix, m_baseViewMatrix, orthoMatrix,
m_Font->GetTexture(), m_TextString3->GetPixelColor());
if (!result)
{
return false;
}
// Render the mouse text strings using the font shader.
for (i = 0; i < 3; i++)
{
m_MouseStrings[i].Render(m_Direct3D->GetDeviceContext());
result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_MouseStrings[i].GetIndexCount(), worldMatrix, m_baseViewMatrix, orthoMatrix,
m_Font->GetTexture(), m_MouseStrings[i].GetPixelColor());
if (!result)
{
return false;
}
}
// Put the sprite vertex and index buffers on the graphics pipeline to prepare them for drawing.
result = m_Sprite->Render(m_Direct3D->GetDeviceContext());
if (!result)
@ -556,15 +998,13 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z)
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();
//scaleMatrix = XMMatrixScaling(0.75f, 0.75f, 0.75f); // Build the scaling matrix.
//rotateMatrix = XMMatrixRotationY(rotation); // Build the rotation matrix.
//translateMatrix = XMMatrixTranslation(x, y, z); // Build the translation matrix.
// Create the light position array from the four light positions.
lightPosition[i] = m_Lights[i].GetPosition();
}
//// Multiply the scale, rotation, and translation matrices together to create the final world transformation matrix.
//srMatrix = XMMatrixMultiply(scaleMatrix, rotateMatrix);
//worldMatrix = XMMatrixMultiply(srMatrix, translateMatrix);
// Render the model using the multitexture shader.
m_Model->Render(m_Direct3D->GetDeviceContext());
@ -674,23 +1114,44 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z)
}
}
// 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));
//// Render the model using the multitexture shader.
//m_Model->Render(m_Direct3D->GetDeviceContext());
// Lighting, utilise plusieurs lights donc Multiple Points Lighting
//result = m_LightShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(0),
// diffuseColor, lightPosition);
//if (!result)
//{
// return false;
//}
// Lightmapping, utiliser light01.tga en deuxieme texture
//result = m_LightMapShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix,
// m_Model->GetTexture(0), m_Model->GetTexture(1));
//if (!result)
//{
// return false;
//}
// MultiTexturing
//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;
//}
// Alphamapping
/*result = m_AlphaMapShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix,
m_Model->GetTexture(0), m_Model->GetTexture(1), m_Model->GetTexture(2));
if (!result)
{
return false;
}
if (!result)
{
return false;
}
}*/
// Enable the Z buffer and disable alpha blending now that 2D rendering is complete.
m_Direct3D->TurnZBufferOn();
@ -722,10 +1183,12 @@ void ApplicationClass::GenerateTerrain()
char modelFilename[128];
char textureFilename[128];
char textureFilename2[128];
char textureFilename3[128];
// Set the file name of the model.
strcpy_s(modelFilename, "plane.txt");
strcpy_s(textureFilename, "stone01.tga");
strcpy_s(textureFilename2, "moss01.tga");
strcpy_s(textureFilename3, "alpha01.tga");
// for loop to generate terrain chunks for a 10x10 grid
for (int i = -5; i < 5; i++)
@ -733,7 +1196,7 @@ void ApplicationClass::GenerateTerrain()
for (int j = -5; j < 5; j++)
{
Object* newTerrain = new Object();
newTerrain->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, textureFilename, textureFilename2);
newTerrain->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, textureFilename, textureFilename2, textureFilename3);
newTerrain->SetTranslateMatrix(XMMatrixTranslation(i*10, -5.0f, j*10));
@ -749,6 +1212,7 @@ void ApplicationClass::AddKobject(WCHAR* filepath)
char modelFilename[128];
char textureFilename[128];
char textureFilename2[128];
char textureFilename3[128];
filesystem::path p(filepath);
string filename = p.stem().string();
@ -759,9 +1223,10 @@ void ApplicationClass::AddKobject(WCHAR* filepath)
// Set the name of the texture file that we will be loading.
strcpy_s(textureFilename, "stone01.tga");
strcpy_s(textureFilename2, "moss01.tga");
strcpy_s(textureFilename3, "alpha01.tga");
Object* newObject = new Object();
newObject->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, textureFilename, textureFilename2);
newObject->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, textureFilename, textureFilename2, textureFilename3);
newObject->SetTranslateMatrix(XMMatrixTranslation(0.0f, 0.0f, 0.0f));
newObject->SetName(filename);
@ -774,6 +1239,7 @@ void ApplicationClass::AddCube()
char modelFilename[128];
char textureFilename[128];
char textureFilename2[128];
char textureFilename3[128];
// Set the file name of the model.
strcpy_s(modelFilename, "cube.txt");
@ -781,10 +1247,11 @@ void ApplicationClass::AddCube()
// Set the name of the texture file that we will be loading.
strcpy_s(textureFilename, "stone01.tga");
strcpy_s(textureFilename2, "moss01.tga");
strcpy_s(textureFilename3, "alpha01.tga");
static int cubeCount = 0;
float position = cubeCount * 2.0f;
Object* newCube = new Object();
newCube->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, textureFilename, textureFilename2);
newCube->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, textureFilename, textureFilename2, textureFilename3);
newCube->SetTranslateMatrix(XMMatrixTranslation(position, 0.0f, 0.0f));
@ -809,7 +1276,54 @@ void ApplicationClass::DeleteTerrain()
delete cube;
}
m_terrainChunk.clear();
}
bool ApplicationClass::UpdateMouseStrings(int mouseX, int mouseY, bool mouseDown)
{
char tempString[16], finalString[32];
bool result;
// Convert the mouse X integer to string format.
sprintf_s(tempString, "%d", mouseX);
// Setup the mouse X string.
strcpy_s(finalString, "Mouse X: ");
strcat_s(finalString, tempString);
// Update the sentence vertex buffer with the new string information.
result = m_MouseStrings[0].UpdateText(m_Direct3D->GetDeviceContext(), m_Font, finalString, 10, 50, 1.0f, 1.0f, 1.0f);
if (!result)
{
return false;
}
// Convert the mouse Y integer to string format.
sprintf_s(tempString, "%d", mouseY);
// Setup the mouse Y string.
strcpy_s(finalString, "Mouse Y: ");
strcat_s(finalString, tempString);
// Update the sentence vertex buffer with the new string information.
result = m_MouseStrings[1].UpdateText(m_Direct3D->GetDeviceContext(), m_Font, finalString, 10, 75, 1.0f, 1.0f, 1.0f);
if (!result)
{
return false;
}
// Setup the mouse button string.
if (mouseDown)
{
strcpy_s(finalString, "Mouse Button: Yes");
}
else
{
strcpy_s(finalString, "Mouse Button: No");
}
// Update the sentence vertex buffer with the new string information.
result = m_MouseStrings[2].UpdateText(m_Direct3D->GetDeviceContext(), m_Font, finalString, 10, 100, 1.0f, 1.0f, 1.0f);
}
bool ApplicationClass::UpdateFps()
@ -879,5 +1393,28 @@ bool ApplicationClass::UpdateFps()
return false;
}
return true;
}
bool ApplicationClass::UpdateRenderCountString(int renderCount)
{
char tempString[16], finalString[32];
bool result;
// Convert the render count integer to string format.
sprintf_s(tempString, "%d", renderCount);
// Setup the render count string.
strcpy_s(finalString, "Render Count: ");
strcat_s(finalString, tempString);
// Update the sentence vertex buffer with the new string information.
result = m_RenderCountString->UpdateText(m_Direct3D->GetDeviceContext(), m_Font, finalString, 10, 30, 1.0f, 1.0f, 1.0f);
if (!result)
{
return false;
}
return true;
}

View File

@ -13,7 +13,9 @@
#include <vector>
#include <filesystem>
#include "lightmapshaderclass.h"
#include "multitextureshaderclass.h"
#include "alphamapshaderclass.h"
#include "bitmapclass.h"
#include "textureshaderclass.h"
#include "spriteclass.h"
@ -22,6 +24,16 @@
#include "fontclass.h"
#include "textclass.h"
#include "fpsclass.h"
#include "inputclass.h"
#include "normalmapshaderclass.h"
#include "specmapshaderclass.h"
#include "modellistclass.h"
#include "positionclass.h"
#include "frustumclass.h"
#include "rendertextureclass.h"
#include "displayplaneclass.h"
#include "translateshaderclass.h"
/////////////
// GLOBALS //
@ -45,7 +57,7 @@ public:
bool Initialize(int, int, HWND);
void Shutdown();
bool Frame();
bool Frame(InputClass*);
int GetScreenWidth() const;
int GetScreenHeight() const;
@ -67,7 +79,11 @@ public:
private:
bool Render(float, float, float, float);
bool UpdateMouseStrings(int, int, bool);
bool UpdateFps();
bool UpdateRenderCountString(int);
bool RenderSceneToTexture(float);
private:
D3DClass* m_Direct3D;
CameraClass* m_Camera;
@ -78,21 +94,35 @@ private:
std::vector<Object*> m_terrainChunk;
LightShaderClass* m_LightShader;
LightClass* m_Light;
LightMapShaderClass* m_LightMapShader;
MultiTextureShaderClass* m_MultiTextureShader;
AlphaMapShaderClass* m_AlphaMapShader;
ModelClass* m_Model;
TextureShaderClass* m_TextureShader;
BitmapClass* m_Bitmap;
SpriteClass* m_Sprite;
TimerClass* m_Timer;
TextClass* m_MouseStrings;
LightClass* m_Lights;
int m_numLights;
FontShaderClass* m_FontShader;
TextClass* m_RenderCountString;
FontClass* m_Font;
TextClass *m_TextString1, *m_TextString2, *m_TextString3;
FpsClass* m_Fps;
TextClass* m_FpsString;
int m_previousFps;
std::vector<Object*> m_object;
NormalMapShaderClass* m_NormalMapShader;
SpecMapShaderClass* m_SpecMapShader;
ModelListClass* m_ModelList;
PositionClass* m_Position;
FrustumClass* m_Frustum;
XMMATRIX m_baseViewMatrix;
RenderTextureClass* m_RenderTexture;
DisplayPlaneClass* m_DisplayPlane;
float m_screenWidth, m_screenHeight;
TranslateShaderClass* m_TranslateShader;
};
#endif

BIN
enginecustom/dirt01.tga Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@ -0,0 +1,199 @@
#include "displayplaneclass.h"
DisplayPlaneClass::DisplayPlaneClass()
{
m_vertexBuffer = 0;
m_indexBuffer = 0;
}
DisplayPlaneClass::DisplayPlaneClass(const DisplayPlaneClass& other)
{
}
DisplayPlaneClass::~DisplayPlaneClass()
{
}
bool DisplayPlaneClass::Initialize(ID3D11Device* device, float width, float height)
{
bool result;
// Initialize the vertex and index buffer that hold the geometry for the button.
result = InitializeBuffers(device, width, height);
if (!result)
{
return false;
}
return true;
}
void DisplayPlaneClass::Shutdown()
{
// Release the vertex and index buffers.
ShutdownBuffers();
return;
}
void DisplayPlaneClass::Render(ID3D11DeviceContext* deviceContext)
{
// Put the vertex and index buffers on the graphics pipeline to prepare them for drawing.
RenderBuffers(deviceContext);
return;
}
int DisplayPlaneClass::GetIndexCount()
{
return m_indexCount;
}
bool DisplayPlaneClass::InitializeBuffers(ID3D11Device* device, float width, float height)
{
VertexType* vertices;
unsigned long* indices;
D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc;
D3D11_SUBRESOURCE_DATA vertexData, indexData;
HRESULT result;
int i;
// Set the number of vertices in the vertex array.
m_vertexCount = 6;
// Set the number of indices in the index array.
m_indexCount = m_vertexCount;
// Create the vertex array.
vertices = new VertexType[m_vertexCount];
// Create the index array.
indices = new unsigned long[m_indexCount];
// Load the vertex array with data.
// First triangle.
vertices[0].position = XMFLOAT3(-width, height, 0.0f); // Top left.
vertices[0].texture = XMFLOAT2(0.0f, 0.0f);
vertices[1].position = XMFLOAT3(width, -height, 0.0f); // Bottom right.
vertices[1].texture = XMFLOAT2(1.0f, 1.0f);
vertices[2].position = XMFLOAT3(-width, -height, 0.0f); // Bottom left.
vertices[2].texture = XMFLOAT2(0.0f, 1.0f);
// Second triangle.
vertices[3].position = XMFLOAT3(-width, height, 0.0f); // Top left.
vertices[3].texture = XMFLOAT2(0.0f, 0.0f);
vertices[4].position = XMFLOAT3(width, height, 0.0f); // Top right.
vertices[4].texture = XMFLOAT2(1.0f, 0.0f);
vertices[5].position = XMFLOAT3(width, -height, 0.0f); // Bottom right.
vertices[5].texture = XMFLOAT2(1.0f, 1.0f);
// Load the index array with data.
for (i = 0; i < m_indexCount; i++)
{
indices[i] = i;
}
// Set up the description of the vertex buffer.
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc.ByteWidth = sizeof(VertexType) * m_vertexCount;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.MiscFlags = 0;
vertexBufferDesc.StructureByteStride = 0;
// Give the subresource structure a pointer to the vertex data.
vertexData.pSysMem = vertices;
vertexData.SysMemPitch = 0;
vertexData.SysMemSlicePitch = 0;
// Now finally create the vertex buffer.
result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &m_vertexBuffer);
if (FAILED(result))
{
return false;
}
// Set up the description of the index buffer.
indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
indexBufferDesc.ByteWidth = sizeof(unsigned long) * m_indexCount;
indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexBufferDesc.CPUAccessFlags = 0;
indexBufferDesc.MiscFlags = 0;
indexBufferDesc.StructureByteStride = 0;
// Give the subresource structure a pointer to the index data.
indexData.pSysMem = indices;
indexData.SysMemPitch = 0;
indexData.SysMemSlicePitch = 0;
// Create the index buffer.
result = device->CreateBuffer(&indexBufferDesc, &indexData, &m_indexBuffer);
if (FAILED(result))
{
return false;
}
// Release the arrays now that the vertex and index buffers have been created and loaded.
delete[] vertices;
vertices = 0;
delete[] indices;
indices = 0;
return true;
}
void DisplayPlaneClass::ShutdownBuffers()
{
// Release the index buffer.
if (m_indexBuffer)
{
m_indexBuffer->Release();
m_indexBuffer = 0;
}
// Release the vertex buffer.
if (m_vertexBuffer)
{
m_vertexBuffer->Release();
m_vertexBuffer = 0;
}
return;
}
void DisplayPlaneClass::RenderBuffers(ID3D11DeviceContext* deviceContext)
{
unsigned int stride;
unsigned int offset;
// Set vertex buffer stride and offset.
stride = sizeof(VertexType);
offset = 0;
// Set the vertex buffer to active in the input assembler so it can be rendered.
deviceContext->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset);
// Set the index buffer to active in the input assembler so it can be rendered.
deviceContext->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0);
// Set the type of primitive that should be rendered from this vertex buffer, in this case triangles.
deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
return;
}

View File

@ -0,0 +1,44 @@
#ifndef _DISPLAYPLANECLASS_H_
#define _DISPLAYPLANECLASS_H_
///////////////////////
// MY CLASS INCLUDES //
///////////////////////
#include "d3dclass.h"
////////////////////////////////////////////////////////////////////////////////
// Class name: DisplayPlaneClass
////////////////////////////////////////////////////////////////////////////////
class DisplayPlaneClass
{
private:
struct VertexType
{
XMFLOAT3 position;
XMFLOAT2 texture;
};
public:
DisplayPlaneClass();
DisplayPlaneClass(const DisplayPlaneClass&);
~DisplayPlaneClass();
bool Initialize(ID3D11Device*, float, float);
void Shutdown();
void Render(ID3D11DeviceContext*);
int GetIndexCount();
private:
bool InitializeBuffers(ID3D11Device*, float, float);
void ShutdownBuffers();
void RenderBuffers(ID3D11DeviceContext*);
private:
ID3D11Buffer* m_vertexBuffer, * m_indexBuffer;
int m_vertexCount, m_indexCount;
};
#endif

View File

@ -20,6 +20,7 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="alphamapshaderclass.cpp" />
<ClCompile Include="applicationclass.cpp" />
<ClCompile Include="bitmapclass.cpp" />
<ClCompile Include="Cameraclass.cpp" />
@ -33,24 +34,38 @@
<ClCompile Include="include\imgui_draw.cpp" />
<ClCompile Include="include\imgui_tables.cpp" />
<ClCompile Include="include\imgui_widgets.cpp" />
<ClCompile Include="displayplaneclass.cpp" />
<ClCompile Include="fontclass.cpp" />
<ClCompile Include="fontshaderclass.cpp" />
<ClCompile Include="fpsclass.cpp" />
<ClCompile Include="frustumclass.cpp" />
<ClCompile Include="inputclass.cpp" />
<ClCompile Include="Lightclass.cpp" />
<ClCompile Include="lightmapshaderclass.cpp" />
<ClCompile Include="Lightshaderclass.cpp" />
<ClCompile Include="Main.cpp" />
<ClCompile Include="modelclass.cpp" />
<ClCompile Include="object.cpp" />
<ClCompile Include="modellistclass.cpp" />
<ClCompile Include="Multitextureshaderclass.cpp" />
<ClCompile Include="normalmapshaderclass.cpp" />
<ClCompile Include="positionclass.cpp" />
<ClCompile Include="rendertextureclass.cpp" />
<ClCompile Include="specmapshaderclass.cpp" />
<ClCompile Include="Spriteclass.cpp" />
<ClCompile Include="Systemclass.cpp" />
<ClCompile Include="textclass.cpp" />
<ClCompile Include="textureclass.cpp" />
<ClCompile Include="textureshaderclass.cpp" />
<ClCompile Include="Timerclass.cpp" />
<ClCompile Include="translate.cpp">
<DependentUpon>translate.vs</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
<ClCompile Include="translateshaderclass.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="alphamapshaderclass.h" />
<ClInclude Include="applicationclass.h" />
<ClInclude Include="bitmapclass.h" />
<ClInclude Include="Cameraclass.h" />
@ -65,30 +80,51 @@
<ClInclude Include="include\imstb_rectpack.h" />
<ClInclude Include="include\imstb_textedit.h" />
<ClInclude Include="include\imstb_truetype.h" />
<ClInclude Include="displayplaneclass.h" />
<ClInclude Include="fontclass.h" />
<ClInclude Include="fontshaderclass.h" />
<ClInclude Include="fpsclass.h" />
<ClInclude Include="frustumclass.h" />
<ClInclude Include="inputclass.h" />
<ClInclude Include="lightclass.h" />
<ClInclude Include="lightmapshaderclass.h" />
<ClInclude Include="lightshaderclass.h" />
<ClInclude Include="modelclass.h" />
<ClInclude Include="object.h" />
<ClInclude Include="modellistclass.h" />
<ClInclude Include="Multitextureshaderclass.h" />
<ClInclude Include="normalmapshaderclass.h" />
<ClInclude Include="positionclass.h" />
<ClInclude Include="rendertextureclass.h" />
<ClInclude Include="specmapshaderclass.h" />
<ClInclude Include="Spriteclass.h" />
<ClInclude Include="systemclass.h" />
<ClInclude Include="textclass.h" />
<ClInclude Include="textureclass.h" />
<ClInclude Include="textureshaderclass.h" />
<ClInclude Include="Timerclass.h" />
<ClInclude Include="translate.h">
<DependentUpon>translate.vs</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="translateshaderclass.h" />
</ItemGroup>
<ItemGroup>
<None Include="alphamap.ps" />
<None Include="alphamap.vs" />
<None Include="font.ps" />
<None Include="font.vs" />
<None Include="light.ps" />
<None Include="light.vs" />
<None Include="lightmap.ps" />
<None Include="lightmap.vs" />
<None Include="Multitexture.ps" />
<None Include="Multitexture.vs" />
<None Include="normalmap.ps" />
<None Include="normalmap.vs" />
<None Include="packages.config" />
<None Include="specmap.ps" />
<None Include="specmap.vs" />
<None Include="texture.ps" />
<None Include="texture.vs" />
</ItemGroup>
@ -112,8 +148,12 @@
</ItemGroup>
<ItemGroup>
<Image Include="..\..\..\..\Downloads\grass.tga" />
<Image Include="alpha01.tga" />
<Image Include="dirt01.tga" />
<Image Include="font01.tga" />
<Image Include="light01.tga" />
<Image Include="moss01.tga" />
<Image Include="normal01.tga" />
<Image Include="papier.tga" />
<Image Include="stone01.tga" />
<Image Include="wall.tga" />
@ -124,6 +164,17 @@
<Text Include="font01.txt" />
<Text Include="plane.txt" />
<Text Include="sphere.txt" />
<Text Include="square.txt" />
</ItemGroup>
<ItemGroup>
<None Include="translate.ps">
<SubType>Designer</SubType>
<FileType>Document</FileType>
</None>
<None Include="translate.vs">
<SubType>Designer</SubType>
<FileType>Document</FileType>
</None>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>

View File

@ -120,6 +120,39 @@
<ClCompile Include="Timerclass.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="fpsclass.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="lightmapshaderclass.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="alphamapshaderclass.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="normalmapshaderclass.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="specmapshaderclass.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="frustumclass.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="modellistclass.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="positionclass.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="displayplaneclass.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="rendertextureclass.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="translateshaderclass.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="systemclass.h">
@ -209,6 +242,71 @@
<ClInclude Include="Timerclass.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="fpsclass.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="lightmapshaderclass.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="alphamapshaderclass.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="normalmapshaderclass.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="specmapshaderclass.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="frustumclass.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="modellistclass.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="positionclass.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="displayplaneclass.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="rendertextureclass.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="translateshaderclass.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="font01.tga">
<Filter>fonts</Filter>
</Image>
<Image Include="wall.tga">
<Filter>assets</Filter>
</Image>
<Image Include="papier.tga">
<Filter>assets</Filter>
</Image>
<Image Include="moss01.tga">
<Filter>assets</Filter>
</Image>
<Image Include="stone01.tga">
<Filter>assets</Filter>
</Image>
<Image Include="light01.tga">
<Filter>assets</Filter>
</Image>
<Image Include="dirt01.tga">
<Filter>assets</Filter>
</Image>
<Image Include="alpha01.tga">
<Filter>assets</Filter>
</Image>
<Image Include="normal01.tga">
<Filter>assets</Filter>
</Image>
<Image Include="..\..\..\..\Downloads\grass.tga">
<Filter>Assets</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
@ -230,11 +328,29 @@
<None Include="light.vs">
<Filter>shader</Filter>
</None>
<None Include="Multitexture.ps">
<Filter>Texture</Filter>
<None Include="lightmap.vs">
<Filter>shader</Filter>
</None>
<None Include="Multitexture.vs">
<Filter>Texture</Filter>
<None Include="lightmap.ps">
<Filter>shader</Filter>
</None>
<None Include="alphamap.vs">
<Filter>texture</Filter>
</None>
<None Include="alphamap.ps">
<Filter>texture</Filter>
</None>
<None Include="normalmap.vs">
<Filter>shader</Filter>
</None>
<None Include="normalmap.ps">
<Filter>shader</Filter>
</None>
<None Include="specmap.vs">
<Filter>shader</Filter>
</None>
<None Include="specmap.ps">
<Filter>shader</Filter>
</None>
<None Include="texture.ps">
<Filter>Texture</Filter>
@ -242,26 +358,18 @@
<None Include="texture.vs">
<Filter>Texture</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Image Include="font01.tga">
<Filter>Fonts</Filter>
</Image>
<Image Include="..\..\..\..\Downloads\grass.tga">
<Filter>Assets</Filter>
</Image>
<Image Include="moss01.tga">
<Filter>Assets</Filter>
</Image>
<Image Include="papier.tga">
<Filter>Assets</Filter>
</Image>
<Image Include="stone01.tga">
<Filter>Assets</Filter>
</Image>
<Image Include="wall.tga">
<Filter>Assets</Filter>
</Image>
<None Include="Multitexture.ps">
<Filter>Texture</Filter>
</None>
<None Include="Multitexture.vs">
<Filter>Texture</Filter>
</None>
<None Include="translate.vs">
<Filter>shader</Filter>
</None>
<None Include="translate.ps">
<Filter>shader</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Text Include="font01.txt">
@ -279,5 +387,8 @@
<Text Include="plane.txt">
<Filter>Assets</Filter>
</Text>
<Text Include="square.txt">
<Filter>assets</Filter>
</Text>
</ItemGroup>
</Project>

View File

@ -0,0 +1,296 @@
#include "frustumclass.h"
FrustumClass::FrustumClass()
{
}
FrustumClass::FrustumClass(const FrustumClass& other)
{
}
FrustumClass::~FrustumClass()
{
}
void FrustumClass::ConstructFrustum(XMMATRIX viewMatrix, XMMATRIX projectionMatrix, float screenDepth)
{
XMMATRIX finalMatrix;
XMFLOAT4X4 projMatrix, matrix;
float zMinimum, r, t;
// Load the projection matrix into a XMFLOAT4X4 structure.
XMStoreFloat4x4(&projMatrix, projectionMatrix);
// Calculate the minimum Z distance in the frustum.
zMinimum = -projMatrix._43 / projMatrix._33;
r = screenDepth / (screenDepth - zMinimum);
projMatrix._33 = r;
projMatrix._43 = -r * zMinimum;
// Load the updated XMFLOAT4X4 back into the original projection matrix.
projectionMatrix = XMLoadFloat4x4(&projMatrix);
// Create the frustum matrix from the view matrix and updated projection matrix.
finalMatrix = XMMatrixMultiply(viewMatrix, projectionMatrix);
// Load the final matrix into a XMFLOAT4X4 structure.
XMStoreFloat4x4(&matrix, finalMatrix);
// Get the near plane of the frustum.
m_planes[0].x = matrix._13;
m_planes[0].y = matrix._23;
m_planes[0].z = matrix._33;
m_planes[0].w = matrix._43;
// Normalize it.
t = (float)sqrt((m_planes[0].x * m_planes[0].x) + (m_planes[0].y * m_planes[0].y) + (m_planes[0].z * m_planes[0].z));
m_planes[0].x /= t;
m_planes[0].y /= t;
m_planes[0].z /= t;
m_planes[0].w /= t;
// Calculate the far plane of frustum.
m_planes[1].x = matrix._14 - matrix._13;
m_planes[1].y = matrix._24 - matrix._23;
m_planes[1].z = matrix._34 - matrix._33;
m_planes[1].w = matrix._44 - matrix._43;
// Normalize it.
t = (float)sqrt((m_planes[1].x * m_planes[1].x) + (m_planes[1].y * m_planes[1].y) + (m_planes[1].z * m_planes[1].z));
m_planes[1].x /= t;
m_planes[1].y /= t;
m_planes[1].z /= t;
m_planes[1].w /= t;
// Calculate the left plane of frustum.
m_planes[2].x = matrix._14 + matrix._11;
m_planes[2].y = matrix._24 + matrix._21;
m_planes[2].z = matrix._34 + matrix._31;
m_planes[2].w = matrix._44 + matrix._41;
// Normalize it.
t = (float)sqrt((m_planes[2].x * m_planes[2].x) + (m_planes[2].y * m_planes[2].y) + (m_planes[2].z * m_planes[2].z));
m_planes[2].x /= t;
m_planes[2].y /= t;
m_planes[2].z /= t;
m_planes[2].w /= t;
// Calculate the right plane of frustum.
m_planes[3].x = matrix._14 - matrix._11;
m_planes[3].y = matrix._24 - matrix._21;
m_planes[3].z = matrix._34 - matrix._31;
m_planes[3].w = matrix._44 - matrix._41;
// Normalize it.
t = (float)sqrt((m_planes[3].x * m_planes[3].x) + (m_planes[3].y * m_planes[3].y) + (m_planes[3].z * m_planes[3].z));
m_planes[3].x /= t;
m_planes[3].y /= t;
m_planes[3].z /= t;
m_planes[3].w /= t;
// Calculate the top plane of frustum.
m_planes[4].x = matrix._14 - matrix._12;
m_planes[4].y = matrix._24 - matrix._22;
m_planes[4].z = matrix._34 - matrix._32;
m_planes[4].w = matrix._44 - matrix._42;
// Normalize it.
t = (float)sqrt((m_planes[4].x * m_planes[4].x) + (m_planes[4].y * m_planes[4].y) + (m_planes[4].z * m_planes[4].z));
m_planes[4].x /= t;
m_planes[4].y /= t;
m_planes[4].z /= t;
m_planes[4].w /= t;
// Calculate the bottom plane of frustum.
m_planes[5].x = matrix._14 + matrix._12;
m_planes[5].y = matrix._24 + matrix._22;
m_planes[5].z = matrix._34 + matrix._32;
m_planes[5].w = matrix._44 + matrix._42;
// Normalize it.
t = (float)sqrt((m_planes[5].x * m_planes[5].x) + (m_planes[5].y * m_planes[5].y) + (m_planes[5].z * m_planes[5].z));
m_planes[5].x /= t;
m_planes[5].y /= t;
m_planes[5].z /= t;
m_planes[5].w /= t;
return;
}
bool FrustumClass::CheckPoint(float x, float y, float z)
{
int i;
// Check if the point is inside all six planes of the view frustum.
for (i = 0; i < 6; i++)
{
if (((m_planes[i].x * x) + (m_planes[i].y * y) + (m_planes[i].z * z) + m_planes[i].w) < 0.0f)
{
return false;
}
}
return true;
}
bool FrustumClass::CheckCube(float xCenter, float yCenter, float zCenter, float radius)
{
int i;
// Check if any one point of the cube is in the view frustum.
for (i = 0; i < 6; i++)
{
if (m_planes[i].x * (xCenter - radius) +
m_planes[i].y * (yCenter - radius) +
m_planes[i].z * (zCenter - radius) + m_planes[i].w >= 0.0f)
{
continue;
}
if (m_planes[i].x * (xCenter + radius) +
m_planes[i].y * (yCenter - radius) +
m_planes[i].z * (zCenter - radius) + m_planes[i].w >= 0.0f)
{
continue;
}
if (m_planes[i].x * (xCenter - radius) +
m_planes[i].y * (yCenter + radius) +
m_planes[i].z * (zCenter - radius) + m_planes[i].w >= 0.0f)
{
continue;
}
if (m_planes[i].x * (xCenter + radius) +
m_planes[i].y * (yCenter + radius) +
m_planes[i].z * (zCenter - radius) + m_planes[i].w >= 0.0f)
{
continue;
}
if (m_planes[i].x * (xCenter - radius) +
m_planes[i].y * (yCenter - radius) +
m_planes[i].z * (zCenter + radius) + m_planes[i].w >= 0.0f)
{
continue;
}
if (m_planes[i].x * (xCenter + radius) +
m_planes[i].y * (yCenter - radius) +
m_planes[i].z * (zCenter + radius) + m_planes[i].w >= 0.0f)
{
continue;
}
if (m_planes[i].x * (xCenter - radius) +
m_planes[i].y * (yCenter + radius) +
m_planes[i].z * (zCenter + radius) + m_planes[i].w >= 0.0f)
{
continue;
}
if (m_planes[i].x * (xCenter + radius) +
m_planes[i].y * (yCenter + radius) +
m_planes[i].z * (zCenter + radius) + m_planes[i].w >= 0.0f)
{
continue;
}
return false;
}
return true;
}
bool FrustumClass::CheckSphere(float xCenter, float yCenter, float zCenter, float radius)
{
int i;
// Check if the radius of the sphere is inside the view frustum.
for (i = 0; i < 6; i++)
{
if (((m_planes[i].x * xCenter) + (m_planes[i].y * yCenter) + (m_planes[i].z * zCenter) + m_planes[i].w) < -radius)
{
return false;
}
}
return true;
}
bool FrustumClass::CheckRectangle(float xCenter, float yCenter, float zCenter, float xSize, float ySize, float zSize)
{
int i;
// Check if any of the 6 planes of the rectangle are inside the view frustum.
for (i = 0; i < 6; i++)
{
if (m_planes[i].x * (xCenter - xSize) +
m_planes[i].y * (yCenter - ySize) +
m_planes[i].z * (zCenter - zSize) + m_planes[i].w >= 0.0f)
{
continue;
}
if (m_planes[i].x * (xCenter + xSize) +
m_planes[i].y * (yCenter - ySize) +
m_planes[i].z * (zCenter - zSize) + m_planes[i].w >= 0.0f)
{
continue;
}
if (m_planes[i].x * (xCenter - xSize) +
m_planes[i].y * (yCenter + ySize) +
m_planes[i].z * (zCenter - zSize) + m_planes[i].w >= 0.0f)
{
continue;
}
if (m_planes[i].x * (xCenter - xSize) +
m_planes[i].y * (yCenter - ySize) +
m_planes[i].z * (zCenter + zSize) + m_planes[i].w >= 0.0f)
{
continue;
}
if (m_planes[i].x * (xCenter + xSize) +
m_planes[i].y * (yCenter + ySize) +
m_planes[i].z * (zCenter - zSize) + m_planes[i].w >= 0.0f)
{
continue;
}
if (m_planes[i].x * (xCenter + xSize) +
m_planes[i].y * (yCenter - ySize) +
m_planes[i].z * (zCenter + zSize) + m_planes[i].w >= 0.0f)
{
continue;
}
if (m_planes[i].x * (xCenter - xSize) +
m_planes[i].y * (yCenter + ySize) +
m_planes[i].z * (zCenter + zSize) + m_planes[i].w >= 0.0f)
{
continue;
}
if (m_planes[i].x * (xCenter + xSize) +
m_planes[i].y * (yCenter + ySize) +
m_planes[i].z * (zCenter + zSize) + m_planes[i].w >= 0.0f)
{
continue;
}
return false;
}
return true;
}

View File

@ -0,0 +1,33 @@
#ifndef _FRUSTUMCLASS_H_
#define _FRUSTUMCLASS_H_
//////////////
// INCLUDES //
//////////////
#include <directxmath.h>
using namespace DirectX;
////////////////////////////////////////////////////////////////////////////////
// Class name: FrustumClass
////////////////////////////////////////////////////////////////////////////////
class FrustumClass
{
public:
FrustumClass();
FrustumClass(const FrustumClass&);
~FrustumClass();
void ConstructFrustum(XMMATRIX, XMMATRIX, float);
bool CheckPoint(float, float, float);
bool CheckCube(float, float, float, float);
bool CheckSphere(float, float, float, float);
bool CheckRectangle(float, float, float, float, float, float);
private:
XMFLOAT4 m_planes[6];
};
#endif

View File

@ -3,6 +3,9 @@
InputClass::InputClass()
{
m_directInput = 0;
m_keyboard = 0;
m_mouse = 0;
}
@ -15,9 +18,9 @@ InputClass::~InputClass()
{
}
void InputClass::Initialize()
bool InputClass::Initialize(HINSTANCE hinstance, HWND hwnd, int screenWidth, int screenHeight)
{
HRESULT result;
int i;
@ -27,10 +30,83 @@ void InputClass::Initialize()
m_keys[i] = false;
}
return;
// Store the screen size which will be used for positioning the mouse cursor.
m_screenWidth = screenWidth;
m_screenHeight = screenHeight;
// Initialize the location of the mouse on the screen.
m_mouseX = 0;
m_mouseY = 0;
// Initialize the main direct input interface.
result = DirectInput8Create(hinstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&m_directInput, NULL);
if (FAILED(result))
{
return false;
}
// Initialize the direct input interface for the keyboard.
result = m_directInput->CreateDevice(GUID_SysKeyboard, &m_keyboard, NULL);
if (FAILED(result))
{
return false;
}
// Set the data format. In this case since it is a keyboard we can use the predefined data format.
result = m_keyboard->SetDataFormat(&c_dfDIKeyboard);
if (FAILED(result))
{
return false;
}
// Set the cooperative level of the keyboard to not share with other programs.
result = m_keyboard->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
if (FAILED(result))
{
return false;
}
// Now acquire the keyboard.
result = m_keyboard->Acquire();
if (FAILED(result))
{
return false;
}
// Initialize the direct input interface for the mouse.
result = m_directInput->CreateDevice(GUID_SysMouse, &m_mouse, NULL);
if (FAILED(result))
{
return false;
}
// Set the data format for the mouse using the pre-defined mouse data format.
result = m_mouse->SetDataFormat(&c_dfDIMouse);
if (FAILED(result))
{
return false;
}
// Set the cooperative level of the mouse to share with other programs.
result = m_mouse->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
if (FAILED(result))
{
return false;
}
// Acquire the mouse.
result = m_mouse->Acquire();
if (FAILED(result))
{
return false;
}
return true;
}
void InputClass::KeyDown(unsigned int input)
{
// If a key is pressed then save that state in the key array.
@ -51,4 +127,236 @@ bool InputClass::IsKeyDown(unsigned int key)
{
// Return what state the key is in (pressed/not pressed).
return m_keys[key];
}
}
void InputClass::Shutdown()
{
// Release the mouse.
if (m_mouse)
{
m_mouse->Unacquire();
m_mouse->Release();
m_mouse = 0;
}
// Release the keyboard.
if (m_keyboard)
{
m_keyboard->Unacquire();
m_keyboard->Release();
m_keyboard = 0;
}
// Release the main interface to direct input.
if (m_directInput)
{
m_directInput->Release();
m_directInput = 0;
}
return;
}
bool InputClass::Frame()
{
bool result;
// Read the current state of the keyboard.
result = ReadKeyboard();
if (!result)
{
return false;
}
// Read the current state of the mouse.
result = ReadMouse();
if (!result)
{
return false;
}
// Process the changes in the mouse and keyboard.
ProcessInput();
return true;
}
bool InputClass::ReadKeyboard()
{
HRESULT result;
// Read the keyboard device.
result = m_keyboard->GetDeviceState(sizeof(m_keyboardState), (LPVOID)&m_keyboardState);
if (FAILED(result))
{
// If the keyboard lost focus or was not acquired then try to get control back.
if ((result == DIERR_INPUTLOST) || (result == DIERR_NOTACQUIRED))
{
m_keyboard->Acquire();
}
else
{
return false;
}
}
return true;
}
bool InputClass::ReadMouse()
{
HRESULT result;
// Read the mouse device.
result = m_mouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&m_mouseState);
if (FAILED(result))
{
// If the mouse lost focus or was not acquired then try to get control back.
if ((result == DIERR_INPUTLOST) || (result == DIERR_NOTACQUIRED))
{
m_mouse->Acquire();
}
else
{
return false;
}
}
return true;
}
void InputClass::ProcessInput()
{
// Update the location of the mouse cursor based on the change of the mouse location during the frame.
m_mouseX += m_mouseState.lX;
m_mouseY += m_mouseState.lY;
//// Ensure the mouse location doesn't exceed the screen width or height.
//if (m_mouseX < 0) { m_mouseX = 0; }
if (m_mouseY < -m_screenHeight) { m_mouseY = -m_screenHeight; }
//if (m_mouseX > m_screenWidth) { m_mouseX = m_screenWidth; }
if (m_mouseY > m_screenHeight) { m_mouseY = m_screenHeight; }
return;
}
bool InputClass::IsEscapePressed()
{
// Do a bitwise and on the keyboard state to check if the escape key is currently being pressed.
if (m_keyboardState[DIK_ESCAPE] & 0x80)
{
return true;
}
return false;
}
bool InputClass::IsLeftArrowPressed()
{
if (m_keyboardState[DIK_LEFT] & 0x80)
{
return true;
}
return false;
}
bool InputClass::IsRightArrowPressed()
{
if (m_keyboardState[DIK_RIGHT] & 0x80)
{
return true;
}
return false;
}
///////////////////////////////////////////////////
// Les touches correspondent aux claviers QWERTY //
///////////////////////////////////////////////////
bool InputClass::IsAPressed()
{
// Touche A sur QWERTY, Q sur AZERTY
if (m_keyboardState[DIK_A] & 0x80)
{
return true;
}
return false;
}
bool InputClass::IsDPressed()
{
if (m_keyboardState[DIK_D] & 0x80)
{
return true;
}
return false;
}
bool InputClass::IsWPressed()
{
// Touche W sur QWERTY, Z sur AZERTY
if (m_keyboardState[DIK_W] & 0x80)
{
return true;
}
return false;
}
bool InputClass::IsSPressed()
{
if (m_keyboardState[DIK_S] & 0x80)
{
return true;
}
return false;
}
bool InputClass::IsQPressed()
{
// Touche Q sur QWERTY, A sur AZERTY
if (m_keyboardState[DIK_Q] & 0x80)
{
return true;
}
return false;
}
bool InputClass::IsEPressed()
{
if (m_keyboardState[DIK_E] & 0x80)
{
return true;
}
return false;
}
void InputClass::GetMouseLocation(int& mouseX, int& mouseY)
{
mouseX = m_mouseX;
mouseY = m_mouseY;
return;
}
bool InputClass::IsMousePressed()
{
// Check the left mouse button state.
if (m_mouseState.rgbButtons[0] & 0x80)
{
return true;
}
return false;
}

View File

@ -1,6 +1,21 @@
#ifndef _INPUTCLASS_H_
#define _INPUTCLASS_H_
///////////////////////////////
// PRE-PROCESSING DIRECTIVES //
///////////////////////////////
#define DIRECTINPUT_VERSION 0x0800
/////////////
// LINKING //
/////////////
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")
//////////////
// INCLUDES //
//////////////
#include <dinput.h>
////////////////////////////////////////////////////////////////////////////////
// Class name: InputClass
@ -12,15 +27,42 @@ public:
InputClass(const InputClass&);
~InputClass();
void Initialize();
bool Initialize(HINSTANCE, HWND, int, int);
void Shutdown();
bool Frame();
bool IsEscapePressed();
void GetMouseLocation(int&, int&);
bool IsMousePressed();
void KeyDown(unsigned int);
void KeyUp(unsigned int);
bool IsLeftArrowPressed();
bool IsRightArrowPressed();
bool IsAPressed();
bool IsDPressed();
bool IsWPressed();
bool IsSPressed();
bool IsQPressed();
bool IsEPressed();
bool IsKeyDown(unsigned int);
private:
bool m_keys[256];
bool ReadKeyboard();
bool ReadMouse();
void ProcessInput();
private:
IDirectInput8* m_directInput;
IDirectInputDevice8* m_keyboard;
IDirectInputDevice8* m_mouse;
unsigned char m_keyboardState[256];
DIMOUSESTATE m_mouseState;
int m_screenWidth, m_screenHeight, m_mouseX, m_mouseY;
};
#endif

BIN
enginecustom/light01.tga Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

38
enginecustom/lightmap.ps Normal file
View File

@ -0,0 +1,38 @@
/////////////
// 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 LightMapPixelShader(PixelInputType input) : SV_TARGET
{
float4 color;
float4 lightColor;
float4 finalColor;
// Get the pixel color from the color texture.
color = shaderTexture1.Sample(SampleType, input.tex);
// Get the pixel color from the light map.
lightColor = shaderTexture2.Sample(SampleType, input.tex);
// Blend the two pixels together.
finalColor = color * lightColor;
return finalColor;
}

49
enginecustom/lightmap.vs Normal file
View File

@ -0,0 +1,49 @@
/////////////
// 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 LightMapVertexShader(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;
}

View File

@ -0,0 +1,377 @@
#include "lightmapshaderclass.h"
LightMapShaderClass::LightMapShaderClass()
{
m_vertexShader = 0;
m_pixelShader = 0;
m_layout = 0;
m_matrixBuffer = 0;
m_sampleState = 0;
}
LightMapShaderClass::LightMapShaderClass(const LightMapShaderClass& other)
{
}
LightMapShaderClass::~LightMapShaderClass()
{
}
bool LightMapShaderClass::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"lightmap.vs");
if (error != 0)
{
return false;
}
// Set the filename of the pixel shader.
error = wcscpy_s(psFilename, 128, L"lightmap.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 LightMapShaderClass::Shutdown()
{
// Shutdown the vertex and pixel shaders as well as the related objects.
ShutdownShader();
return;
}
bool LightMapShaderClass::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 LightMapShaderClass::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, "LightMapVertexShader", "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, "LightMapPixelShader", "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 LightMapShaderClass::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 LightMapShaderClass::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 LightMapShaderClass::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 LightMapShaderClass::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;
}

View File

@ -0,0 +1,55 @@
////////////////////////////////////////////////////////////////////////////////
#ifndef _LIGHTMAPSHADERCLASS_H_
#define _LIGHTMAPSHADERCLASS_H_
//////////////
// INCLUDES //
//////////////
#include <d3d11.h>
#include <d3dcompiler.h>
#include <directxmath.h>
#include <fstream>
using namespace DirectX;
using namespace std;
////////////////////////////////////////////////////////////////////////////////
// Class name: LightMapShaderClass
////////////////////////////////////////////////////////////////////////////////
class LightMapShaderClass
{
private:
struct MatrixBufferType
{
XMMATRIX world;
XMMATRIX view;
XMMATRIX projection;
};
public:
LightMapShaderClass();
LightMapShaderClass(const LightMapShaderClass&);
~LightMapShaderClass();
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

View File

@ -19,7 +19,7 @@ ModelClass::~ModelClass()
{
}
bool ModelClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceContext,char* modelFilename,char* textureFilename1,char* textureFilename2)
bool ModelClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceContext, char* modelFilename, char* textureFilename1, char* textureFilename2, char* textureFilename3)
{
bool result;
@ -30,6 +30,9 @@ bool ModelClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceCon
return false;
}
// Calculate the tangent and binormal vectors for the model.
CalculateModelVectors();
// Initialize the vertex and index buffers.
result = InitializeBuffers(device);
if (!result)
@ -37,7 +40,7 @@ bool ModelClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceCon
return false;
}
// Load the textures for this model.
result = LoadTextures(device, deviceContext, textureFilename1, textureFilename2);
result = LoadTextures(device, deviceContext, textureFilename1, textureFilename2, textureFilename3);
if (!result)
{
return false;
@ -103,6 +106,8 @@ bool ModelClass::InitializeBuffers(ID3D11Device* device)
vertices[i].position = XMFLOAT3(m_model[i].x, m_model[i].y, m_model[i].z);
vertices[i].texture = XMFLOAT2(m_model[i].tu, m_model[i].tv);
vertices[i].normal = XMFLOAT3(m_model[i].nx, m_model[i].ny, m_model[i].nz);
vertices[i].tangent = XMFLOAT3(m_model[i].tx, m_model[i].ty, m_model[i].tz);
vertices[i].binormal = XMFLOAT3(m_model[i].bx, m_model[i].by, m_model[i].bz);
indices[i] = i;
}
@ -200,13 +205,14 @@ void ModelClass::RenderBuffers(ID3D11DeviceContext* deviceContext)
return;
}
bool ModelClass::LoadTextures(ID3D11Device* device, ID3D11DeviceContext* deviceContext, char* filename1, char* filename2)
bool ModelClass::LoadTextures(ID3D11Device* device, ID3D11DeviceContext* deviceContext, char* filename1, char* filename2, char* filename3)
{
bool result;
// Create and initialize the texture object array.
m_Textures = new TextureClass[2];
m_Textures = new TextureClass[3];
result = m_Textures[0].Initialize(device, deviceContext, filename1);
if (!result)
@ -220,6 +226,13 @@ bool ModelClass::LoadTextures(ID3D11Device* device, ID3D11DeviceContext* deviceC
return false;
}
result = m_Textures[2].Initialize(device, deviceContext, filename3);
if (!result)
{
return false;
}
return true;
}
@ -230,6 +243,7 @@ void ModelClass::ReleaseTextures()
{
m_Textures[0].Shutdown();
m_Textures[1].Shutdown();
m_Textures[2].Shutdown();
delete[] m_Textures;
m_Textures = 0;
@ -293,6 +307,128 @@ bool ModelClass::LoadModel(char* filename)
return true;
}
void ModelClass::CalculateModelVectors()
{
int faceCount, i, index;
TempVertexType vertex1, vertex2, vertex3;
VectorType tangent, binormal;
// Calculate the number of faces in the model.
faceCount = m_vertexCount / 3;
// Initialize the index to the model data.
index = 0;
// Go through all the faces and calculate the the tangent and binormal vectors.
for (i = 0; i < faceCount; i++)
{
// Get the three vertices for this face from the model.
vertex1.x = m_model[index].x;
vertex1.y = m_model[index].y;
vertex1.z = m_model[index].z;
vertex1.tu = m_model[index].tu;
vertex1.tv = m_model[index].tv;
index++;
vertex2.x = m_model[index].x;
vertex2.y = m_model[index].y;
vertex2.z = m_model[index].z;
vertex2.tu = m_model[index].tu;
vertex2.tv = m_model[index].tv;
index++;
vertex3.x = m_model[index].x;
vertex3.y = m_model[index].y;
vertex3.z = m_model[index].z;
vertex3.tu = m_model[index].tu;
vertex3.tv = m_model[index].tv;
index++;
// Calculate the tangent and binormal of that face.
CalculateTangentBinormal(vertex1, vertex2, vertex3, tangent, binormal);
// Store the tangent and binormal for this face back in the model structure.
m_model[index - 1].tx = tangent.x;
m_model[index - 1].ty = tangent.y;
m_model[index - 1].tz = tangent.z;
m_model[index - 1].bx = binormal.x;
m_model[index - 1].by = binormal.y;
m_model[index - 1].bz = binormal.z;
m_model[index - 2].tx = tangent.x;
m_model[index - 2].ty = tangent.y;
m_model[index - 2].tz = tangent.z;
m_model[index - 2].bx = binormal.x;
m_model[index - 2].by = binormal.y;
m_model[index - 2].bz = binormal.z;
m_model[index - 3].tx = tangent.x;
m_model[index - 3].ty = tangent.y;
m_model[index - 3].tz = tangent.z;
m_model[index - 3].bx = binormal.x;
m_model[index - 3].by = binormal.y;
m_model[index - 3].bz = binormal.z;
}
return;
}
void ModelClass::CalculateTangentBinormal(TempVertexType vertex1, TempVertexType vertex2, TempVertexType vertex3, VectorType& tangent, VectorType& binormal)
{
float vector1[3], vector2[3];
float tuVector[2], tvVector[2];
float den;
float length;
// Calculate the two vectors for this face.
vector1[0] = vertex2.x - vertex1.x;
vector1[1] = vertex2.y - vertex1.y;
vector1[2] = vertex2.z - vertex1.z;
vector2[0] = vertex3.x - vertex1.x;
vector2[1] = vertex3.y - vertex1.y;
vector2[2] = vertex3.z - vertex1.z;
// Calculate the tu and tv texture space vectors.
tuVector[0] = vertex2.tu - vertex1.tu;
tvVector[0] = vertex2.tv - vertex1.tv;
tuVector[1] = vertex3.tu - vertex1.tu;
tvVector[1] = vertex3.tv - vertex1.tv;
// Calculate the denominator of the tangent/binormal equation.
den = 1.0f / (tuVector[0] * tvVector[1] - tuVector[1] * tvVector[0]);
// Calculate the cross products and multiply by the coefficient to get the tangent and binormal.
tangent.x = (tvVector[1] * vector1[0] - tvVector[0] * vector2[0]) * den;
tangent.y = (tvVector[1] * vector1[1] - tvVector[0] * vector2[1]) * den;
tangent.z = (tvVector[1] * vector1[2] - tvVector[0] * vector2[2]) * den;
binormal.x = (tuVector[0] * vector2[0] - tuVector[1] * vector1[0]) * den;
binormal.y = (tuVector[0] * vector2[1] - tuVector[1] * vector1[1]) * den;
binormal.z = (tuVector[0] * vector2[2] - tuVector[1] * vector1[2]) * den;
// Calculate the length of this normal.
length = sqrt((tangent.x * tangent.x) + (tangent.y * tangent.y) + (tangent.z * tangent.z));
// Normalize the normal and then store it
tangent.x = tangent.x / length;
tangent.y = tangent.y / length;
tangent.z = tangent.z / length;
// Calculate the length of this normal.
length = sqrt((binormal.x * binormal.x) + (binormal.y * binormal.y) + (binormal.z * binormal.z));
// Normalize the normal and then store it
binormal.x = binormal.x / length;
binormal.y = binormal.y / length;
binormal.z = binormal.z / length;
return;
}
void ModelClass::ReleaseModel()
{
if (m_model)

View File

@ -32,6 +32,8 @@ protected:
XMFLOAT3 position;
XMFLOAT2 texture;
XMFLOAT3 normal;
XMFLOAT3 tangent;
XMFLOAT3 binormal;
};
struct ModelType
@ -39,6 +41,8 @@ protected:
float x, y, z;
float tu, tv;
float nx, ny, nz;
float tx, ty, tz;
float bx, by, bz;
};
struct Vertex {
@ -53,6 +57,18 @@ protected:
float nx, ny, nz;
};
struct TempVertexType
{
float x, y, z;
float tu, tv;
float nx, ny, nz;
};
struct VectorType
{
float x, y, z;
};
struct Face {
int v1, v2, v3;
int t1, t2, t3;
@ -64,7 +80,7 @@ public:
ModelClass(const ModelClass&);
~ModelClass();
bool Initialize(ID3D11Device*, ID3D11DeviceContext*, char*, char*, char*);
bool Initialize(ID3D11Device*, ID3D11DeviceContext*, char*, char*, char*, char*);
void Shutdown();
void Render(ID3D11DeviceContext*);
@ -75,12 +91,15 @@ private:
bool InitializeBuffers(ID3D11Device*);
void ShutdownBuffers();
void RenderBuffers(ID3D11DeviceContext*);
bool LoadTextures(ID3D11Device*, ID3D11DeviceContext*, char*, char*);
bool LoadTextures(ID3D11Device*, ID3D11DeviceContext*, char*, char*, char*);
void ReleaseTextures();
bool LoadModel(char*);
void ReleaseModel();
void CalculateModelVectors();
void CalculateTangentBinormal(TempVertexType, TempVertexType, TempVertexType, VectorType&, VectorType&);
private:
ID3D11Buffer* m_vertexBuffer, * m_indexBuffer;
int m_vertexCount, m_indexCount;

BIN
enginecustom/normal01.tga Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

71
enginecustom/normalmap.ps Normal file
View File

@ -0,0 +1,71 @@
/////////////
// GLOBALS //
/////////////
Texture2D shaderTexture1 : register(t0);
Texture2D shaderTexture2 : register(t1);
SamplerState SampleType : register(s0);
cbuffer LightBuffer
{
float4 diffuseColor;
float3 lightDirection;
float padding;
};
//////////////
// TYPEDEFS //
//////////////
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
float3 normal : NORMAL;
float3 tangent : TANGENT;
float3 binormal : BINORMAL;
};
////////////////////////////////////////////////////////////////////////////////
// Pixel Shader
////////////////////////////////////////////////////////////////////////////////
float4 NormalMapPixelShader(PixelInputType input) : SV_TARGET
{
float4 textureColor;
float4 bumpMap;
float3 bumpNormal;
float3 lightDir;
float lightIntensity;
float4 color;
// 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;
return color;
}

65
enginecustom/normalmap.vs Normal file
View File

@ -0,0 +1,65 @@
/////////////
// GLOBALS //
/////////////
cbuffer MatrixBuffer
{
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
};
//////////////
// 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;
};
////////////////////////////////////////////////////////////////////////////////
// Vertex Shader
////////////////////////////////////////////////////////////////////////////////
PixelInputType NormalMapVertexShader(VertexInputType input)
{
PixelInputType output;
// Change the position vector to be 4 units for proper matrix calculations.
input.position.w = 1.0f;
// Calculate the position of the vertex against the world, view, and projection matrices.
output.position = mul(input.position, worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);
// Store the texture coordinates for the pixel shader.
output.tex = input.tex;
// Calculate the normal vector against the world matrix only 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);
return output;
}

View File

@ -0,0 +1,441 @@
#include "normalmapshaderclass.h"
NormalMapShaderClass::NormalMapShaderClass()
{
m_vertexShader = 0;
m_pixelShader = 0;
m_layout = 0;
m_matrixBuffer = 0;
m_sampleState = 0;
m_lightBuffer = 0;
}
NormalMapShaderClass::NormalMapShaderClass(const NormalMapShaderClass& other)
{
}
NormalMapShaderClass::~NormalMapShaderClass()
{
}
bool NormalMapShaderClass::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"normalmap.vs");
if (error != 0)
{
return false;
}
// Set the filename of the pixel shader.
error = wcscpy_s(psFilename, 128, L"normalmap.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 NormalMapShaderClass::Shutdown()
{
// Shutdown the vertex and pixel shaders as well as the related objects.
ShutdownShader();
return;
}
bool NormalMapShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture1, ID3D11ShaderResourceView* texture2, XMFLOAT3 lightDirection, XMFLOAT4 diffuseColor)
{
bool result;
// Set the shader parameters that it will use for rendering.
result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture1, texture2, lightDirection, diffuseColor);
if (!result)
{
return false;
}
// Now render the prepared buffers with the shader.
RenderShader(deviceContext, indexCount);
return true;
}
bool NormalMapShaderClass::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;
// 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, "NormalMapVertexShader", "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, "NormalMapPixelShader", "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;
}
return true;
}
void NormalMapShaderClass::ShutdownShader()
{
// 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 NormalMapShaderClass::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 NormalMapShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture1, ID3D11ShaderResourceView* texture2, XMFLOAT3 lightDirection, XMFLOAT4 diffuseColor)
{
HRESULT result;
D3D11_MAPPED_SUBRESOURCE mappedResource;
MatrixBufferType* dataPtr;
unsigned int bufferNumber;
LightBufferType* dataPtr2;
// 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);
// Lock the light constant buffer so it can be written to.
result = deviceContext->Map(m_lightBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
return false;
}
// Get a pointer to the data in the constant buffer.
dataPtr2 = (LightBufferType*)mappedResource.pData;
// Copy the lighting variables into the constant buffer.
dataPtr2->diffuseColor = diffuseColor;
dataPtr2->lightDirection = lightDirection;
dataPtr2->padding = 0.0f;
// Unlock the constant buffer.
deviceContext->Unmap(m_lightBuffer, 0);
// Set the position of the light constant buffer in the pixel shader.
bufferNumber = 0;
// Finally set the light constant buffer in the pixel shader with the updated values.
deviceContext->PSSetConstantBuffers(bufferNumber, 1, &m_lightBuffer);
return true;
}
void NormalMapShaderClass::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;
}

View File

@ -0,0 +1,62 @@
#ifndef _NORMALMAPSHADERCLASS_H_
#define _NORMALMAPSHADERCLASS_H_
//////////////
// INCLUDES //
//////////////
#include <d3d11.h>
#include <d3dcompiler.h>
#include <directxmath.h>
#include <fstream>
using namespace DirectX;
using namespace std;
////////////////////////////////////////////////////////////////////////////////
// Class name: NormalMapShaderClass
////////////////////////////////////////////////////////////////////////////////
class NormalMapShaderClass
{
private:
struct MatrixBufferType
{
XMMATRIX world;
XMMATRIX view;
XMMATRIX projection;
};
struct LightBufferType
{
XMFLOAT4 diffuseColor;
XMFLOAT3 lightDirection;
float padding;
};
public:
NormalMapShaderClass();
NormalMapShaderClass(const NormalMapShaderClass&);
~NormalMapShaderClass();
bool Initialize(ID3D11Device*, HWND);
void Shutdown();
bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4);
private:
bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*);
void ShutdownShader();
void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*);
bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4);
void RenderShader(ID3D11DeviceContext*, int);
private:
ID3D11VertexShader* m_vertexShader;
ID3D11PixelShader* m_pixelShader;
ID3D11InputLayout* m_layout;
ID3D11Buffer* m_matrixBuffer;
ID3D11SamplerState* m_sampleState;
ID3D11Buffer* m_lightBuffer;
};
#endif

View File

@ -0,0 +1,248 @@
#include "rendertextureclass.h"
RenderTextureClass::RenderTextureClass()
{
m_renderTargetTexture = 0;
m_renderTargetView = 0;
m_shaderResourceView = 0;
m_depthStencilBuffer = 0;
m_depthStencilView = 0;
}
RenderTextureClass::RenderTextureClass(const RenderTextureClass& other)
{
}
RenderTextureClass::~RenderTextureClass()
{
}
bool RenderTextureClass::Initialize(ID3D11Device * device, int textureWidth, int textureHeight, float screenDepth, float screenNear, int format)
{
D3D11_TEXTURE2D_DESC textureDesc;
HRESULT result;
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
D3D11_TEXTURE2D_DESC depthBufferDesc;
D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
DXGI_FORMAT textureFormat;
// Set the texture format.
switch (format)
{
case 1:
{
textureFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
break;
}
default:
{
textureFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
break;
}
}
// Store the width and height of the render texture.
m_textureWidth = textureWidth;
m_textureHeight = textureHeight;
// Initialize the render target texture description.
ZeroMemory(&textureDesc, sizeof(textureDesc));
// Setup the render target texture description.
textureDesc.Width = textureWidth;
textureDesc.Height = textureHeight;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = textureFormat;
textureDesc.SampleDesc.Count = 1;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = 0;
// Create the render target texture.
result = device->CreateTexture2D(&textureDesc, NULL, &m_renderTargetTexture);
if (FAILED(result))
{
return false;
}
// Setup the description of the render target view.
renderTargetViewDesc.Format = textureDesc.Format;
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
renderTargetViewDesc.Texture2D.MipSlice = 0;
// Create the render target view.
result = device->CreateRenderTargetView(m_renderTargetTexture, &renderTargetViewDesc, &m_renderTargetView);
if (FAILED(result))
{
return false;
}
// Setup the description of the shader resource view.
shaderResourceViewDesc.Format = textureDesc.Format;
shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
shaderResourceViewDesc.Texture2D.MipLevels = 1;
// Create the shader resource view.
result = device->CreateShaderResourceView(m_renderTargetTexture, &shaderResourceViewDesc, &m_shaderResourceView);
if (FAILED(result))
{
return false;
}
// Initialize the description of the depth buffer.
ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));
// Set up the description of the depth buffer.
depthBufferDesc.Width = textureWidth;
depthBufferDesc.Height = textureHeight;
depthBufferDesc.MipLevels = 1;
depthBufferDesc.ArraySize = 1;
depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthBufferDesc.SampleDesc.Count = 1;
depthBufferDesc.SampleDesc.Quality = 0;
depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthBufferDesc.CPUAccessFlags = 0;
depthBufferDesc.MiscFlags = 0;
// Create the texture for the depth buffer using the filled out description.
result = device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer);
if (FAILED(result))
{
return false;
}
// Initailze the depth stencil view description.
ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));
// Set up the depth stencil view description.
depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
depthStencilViewDesc.Texture2D.MipSlice = 0;
// Create the depth stencil view.
result = device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView);
if (FAILED(result))
{
return false;
}
// Setup the viewport for rendering.
m_viewport.Width = (float)textureWidth;
m_viewport.Height = (float)textureHeight;
m_viewport.MinDepth = 0.0f;
m_viewport.MaxDepth = 1.0f;
m_viewport.TopLeftX = 0;
m_viewport.TopLeftY = 0;
// Setup the projection matrix.
m_projectionMatrix = XMMatrixPerspectiveFovLH((3.141592654f / 4.0f), ((float)textureWidth / (float)textureHeight), screenNear, screenDepth);
// Create an orthographic projection matrix for 2D rendering.
m_orthoMatrix = XMMatrixOrthographicLH((float)textureWidth, (float)textureHeight, screenNear, screenDepth);
return true;
}
void RenderTextureClass::Shutdown()
{
if (m_depthStencilView)
{
m_depthStencilView->Release();
m_depthStencilView = 0;
}
if (m_depthStencilBuffer)
{
m_depthStencilBuffer->Release();
m_depthStencilBuffer = 0;
}
if (m_shaderResourceView)
{
m_shaderResourceView->Release();
m_shaderResourceView = 0;
}
if (m_renderTargetView)
{
m_renderTargetView->Release();
m_renderTargetView = 0;
}
if (m_renderTargetTexture)
{
m_renderTargetTexture->Release();
m_renderTargetTexture = 0;
}
return;
}
void RenderTextureClass::SetRenderTarget(ID3D11DeviceContext * deviceContext)
{
// Bind the render target view and depth stencil buffer to the output render pipeline.
deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);
// Set the viewport.
deviceContext->RSSetViewports(1, &m_viewport);
return;
}
void RenderTextureClass::ClearRenderTarget(ID3D11DeviceContext * deviceContext, float red, float green, float blue, float alpha)
{
float color[4];
// Setup the color to clear the buffer to.
color[0] = red;
color[1] = green;
color[2] = blue;
color[3] = alpha;
// Clear the back buffer.
deviceContext->ClearRenderTargetView(m_renderTargetView, color);
// Clear the depth buffer.
deviceContext->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
return;
}
ID3D11ShaderResourceView* RenderTextureClass::GetShaderResourceView()
{
return m_shaderResourceView;
}
void RenderTextureClass::GetProjectionMatrix(XMMATRIX & projectionMatrix)
{
projectionMatrix = m_projectionMatrix;
return;
}
void RenderTextureClass::GetOrthoMatrix(XMMATRIX & orthoMatrix)
{
orthoMatrix = m_orthoMatrix;
return;
}
int RenderTextureClass::GetTextureWidth()
{
return m_textureWidth;
}
int RenderTextureClass::GetTextureHeight()
{
return m_textureHeight;
}

View File

@ -0,0 +1,51 @@
////////////////////////////////////////////////////////////////////////////////
// Filename: rendertextureclass.h
////////////////////////////////////////////////////////////////////////////////
#ifndef _RENDERTEXTURECLASS_H_
#define _RENDERTEXTURECLASS_H_
//////////////
// INCLUDES //
//////////////
#include <d3d11.h>
#include <directxmath.h>
using namespace DirectX;
////////////////////////////////////////////////////////////////////////////////
// Class name: RenderTextureClass
////////////////////////////////////////////////////////////////////////////////
class RenderTextureClass
{
public:
RenderTextureClass();
RenderTextureClass(const RenderTextureClass&);
~RenderTextureClass();
bool Initialize(ID3D11Device*, int, int, float, float, int);
void Shutdown();
void SetRenderTarget(ID3D11DeviceContext*);
void ClearRenderTarget(ID3D11DeviceContext*, float, float, float, float);
ID3D11ShaderResourceView* GetShaderResourceView();
void GetProjectionMatrix(XMMATRIX&);
void GetOrthoMatrix(XMMATRIX&);
int GetTextureWidth();
int GetTextureHeight();
private:
int m_textureWidth, m_textureHeight;
ID3D11Texture2D* m_renderTargetTexture;
ID3D11RenderTargetView* m_renderTargetView;
ID3D11ShaderResourceView* m_shaderResourceView;
ID3D11Texture2D* m_depthStencilBuffer;
ID3D11DepthStencilView* m_depthStencilView;
D3D11_VIEWPORT m_viewport;
XMMATRIX m_projectionMatrix;
XMMATRIX m_orthoMatrix;
};
#endif

93
enginecustom/specmap.ps Normal file
View File

@ -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;
}

83
enginecustom/specmap.vs Normal file
View File

@ -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;
}

View File

@ -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;
}

View File

@ -0,0 +1,72 @@
#ifndef _SPECMAPSHADERCLASS_H_
#define _SPECMAPSHADERCLASS_H_
//////////////
// INCLUDES //
//////////////
#include <d3d11.h>
#include <d3dcompiler.h>
#include <directxmath.h>
#include <fstream>
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

10
enginecustom/square.txt Normal file
View File

@ -0,0 +1,10 @@
Vertex Count: 6
Data:
-1.0 1.0 0.0 0.0 0.0 0.0 0.0 -1.0
1.0 1.0 0.0 1.0 0.0 0.0 0.0 -1.0
-1.0 -1.0 0.0 0.0 1.0 0.0 0.0 -1.0
-1.0 -1.0 0.0 0.0 1.0 0.0 0.0 -1.0
1.0 1.0 0.0 1.0 0.0 0.0 0.0 -1.0
1.0 -1.0 0.0 1.0 1.0 0.0 0.0 -1.0

View File

@ -1,5 +1,6 @@
#ifndef _SYSTEMCLASS_H_
#define _SYSTEMCLASS_H_
#define WIN32_LEAN_AND_MEAN
#include "inputclass.h"

View File

@ -45,4 +45,4 @@ private:
XMFLOAT4 m_pixelColor;
};
#endif
#endif

View File

@ -0,0 +1,18 @@
#include "pch.h"
#include "Translate.h"
#if __has_include("Translate.g.cpp")
#include "Translate.g.cpp"
#endif
namespace winrt::enginecustom::implementation
{
int32_t Translate::MyProperty()
{
throw hresult_not_implemented();
}
void Translate::MyProperty(int32_t /*value*/)
{
throw hresult_not_implemented();
}
}

21
enginecustom/translate.h Normal file
View File

@ -0,0 +1,21 @@
#pragma once
#include "Translate.g.h"
namespace winrt::enginecustom::implementation
{
struct Translate : TranslateT<Translate>
{
Translate() = default;
int32_t MyProperty();
void MyProperty(int32_t value);
};
}
namespace winrt::enginecustom::factory_implementation
{
struct Translate : TranslateT<Translate, implementation::Translate>
{
};
}

37
enginecustom/translate.ps Normal file
View File

@ -0,0 +1,37 @@
/////////////
// GLOBALS //
/////////////
Texture2D shaderTexture : register(t0);
SamplerState SampleType : register(s0);
cbuffer TranslationBuffer
{
float textureTranslation;
};
//////////////
// TYPEDEFS //
//////////////
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
};
////////////////////////////////////////////////////////////////////////////////
// Pixel Shader
////////////////////////////////////////////////////////////////////////////////
float4 TranslatePixelShader(PixelInputType input) : SV_TARGET
{
float4 textureColor;
// Translate the position where we sample the pixel from.
input.tex.x += textureTranslation;
// Sample the pixel color from the texture using the sampler at this texture coordinate location.
textureColor = shaderTexture.Sample(SampleType, input.tex);
return textureColor;
}

48
enginecustom/translate.vs Normal file
View File

@ -0,0 +1,48 @@
/////////////
// GLOBALS //
/////////////
cbuffer MatrixBuffer
{
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
};
//////////////
// TYPEDEFS //
//////////////
struct VertexInputType
{
float4 position : POSITION;
float2 tex : TEXCOORD0;
};
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
};
////////////////////////////////////////////////////////////////////////////////
// Vertex Shader
////////////////////////////////////////////////////////////////////////////////
PixelInputType TranslateVertexShader(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;
}

View File

@ -0,0 +1,416 @@
#include "translateshaderclass.h"
TranslateShaderClass::TranslateShaderClass()
{
m_vertexShader = 0;
m_pixelShader = 0;
m_layout = 0;
m_matrixBuffer = 0;
m_sampleState = 0;
m_translateBuffer = 0;
}
TranslateShaderClass::TranslateShaderClass(const TranslateShaderClass& other)
{
}
TranslateShaderClass::~TranslateShaderClass()
{
}
bool TranslateShaderClass::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"../Engine/translate.vs");
if (error != 0)
{
return false;
}
// Set the filename of the pixel shader.
error = wcscpy_s(psFilename, 128, L"../Engine/translate.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 TranslateShaderClass::Shutdown()
{
// Shutdown the vertex and pixel shaders as well as the related objects.
ShutdownShader();
return;
}
bool TranslateShaderClass::Render(ID3D11DeviceContext * deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix,
XMMATRIX projectionMatrix, ID3D11ShaderResourceView * texture, float translation)
{
bool result;
// Set the shader parameters that it will use for rendering.
result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, translation);
if (!result)
{
return false;
}
// Now render the prepared buffers with the shader.
RenderShader(deviceContext, indexCount);
return true;
}
bool TranslateShaderClass::InitializeShader(ID3D11Device * device, HWND hwnd, WCHAR * vsFilename, WCHAR * psFilename)
{
HRESULT result;
ID3D10Blob* errorMessage;
ID3D10Blob* vertexShaderBuffer;
ID3D10Blob* pixelShaderBuffer;
D3D11_INPUT_ELEMENT_DESC polygonLayout[2];
unsigned int numElements;
D3D11_BUFFER_DESC matrixBufferDesc;
D3D11_SAMPLER_DESC samplerDesc;
D3D11_BUFFER_DESC translateBufferDesc;
// 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, "TranslateVertexShader", "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, "TranslatePixelShader", "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;
// 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 texture translation dynamic constant buffer that is in the pixel shader.
translateBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
translateBufferDesc.ByteWidth = sizeof(TranslateBufferType);
translateBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
translateBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
translateBufferDesc.MiscFlags = 0;
translateBufferDesc.StructureByteStride = 0;
// Create the constant buffer pointer so we can access the pixel shader constant buffer from within this class.
result = device->CreateBuffer(&translateBufferDesc, NULL, &m_translateBuffer);
if (FAILED(result))
{
return false;
}
return true;
}
void TranslateShaderClass::ShutdownShader()
{
// Release the texture translation constant buffer.
if (m_translateBuffer)
{
m_translateBuffer->Release();
m_translateBuffer = 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 TranslateShaderClass::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 TranslateShaderClass::SetShaderParameters(ID3D11DeviceContext * deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix,
XMMATRIX projectionMatrix, ID3D11ShaderResourceView * texture, float translation)
{
HRESULT result;
D3D11_MAPPED_SUBRESOURCE mappedResource;
MatrixBufferType* dataPtr;
unsigned int bufferNumber;
TranslateBufferType* dataPtr2;
// 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 resource in the pixel shader.
deviceContext->PSSetShaderResources(0, 1, &texture);
// Lock the texture translation constant buffer so it can be written to.
result = deviceContext->Map(m_translateBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
return false;
}
// Get a pointer to the data in the texture translation constant buffer.
dataPtr2 = (TranslateBufferType*)mappedResource.pData;
// Copy the translation value into the texture translation constant buffer.
dataPtr2->translation = translation;
// Unlock the buffer.
deviceContext->Unmap(m_translateBuffer, 0);
// Set the position of the texture translation constant buffer in the pixel shader.
bufferNumber = 0;
// Now set the texture translation constant buffer in the pixel shader with the updated values.
deviceContext->PSSetConstantBuffers(bufferNumber, 1, &m_translateBuffer);
return true;
}
void TranslateShaderClass::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 geometry.
deviceContext->DrawIndexed(indexCount, 0, 0);
return;
}

View File

@ -0,0 +1,62 @@
#ifndef _TRANSLATESHADERCLASS_H_
#define _TRANSLATESHADERCLASS_H_
//////////////
// INCLUDES //
//////////////
#include <d3d11.h>
#include <d3dcompiler.h>
#include <directxmath.h>
#include <fstream>
using namespace DirectX;
using namespace std;
////////////////////////////////////////////////////////////////////////////////
// Class name: TranslateShaderClass
////////////////////////////////////////////////////////////////////////////////
class TranslateShaderClass
{
private:
struct MatrixBufferType
{
XMMATRIX world;
XMMATRIX view;
XMMATRIX projection;
};
struct TranslateBufferType
{
float translation;
XMFLOAT3 padding;
};
public:
TranslateShaderClass();
TranslateShaderClass(const TranslateShaderClass&);
~TranslateShaderClass();
bool Initialize(ID3D11Device*, HWND);
void Shutdown();
bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, float);
private:
bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*);
void ShutdownShader();
void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*);
bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, float);
void RenderShader(ID3D11DeviceContext*, int);
private:
ID3D11VertexShader* m_vertexShader;
ID3D11PixelShader* m_pixelShader;
ID3D11InputLayout* m_layout;
ID3D11Buffer* m_matrixBuffer;
ID3D11SamplerState* m_sampleState;
ID3D11Buffer* m_translateBuffer;
};
#endif