Added color gradient for the terrain blend maps

Added terrainBuffer struct
Added shared methods to genereate random UV's and intensities
Added water to the terrain
Added random UV's to the shader
Removed the vector3d class since DX can deal with that stuff...
This commit is contained in:
iDunnoDev
2022-05-04 14:09:59 +01:00
committed by iDunnoDev
parent 7a57c73ac3
commit bc906064e5
15 changed files with 597 additions and 254 deletions

View File

@ -0,0 +1,56 @@
#include "ColorGradient.h"
ColorGradient::ColorGradient(float min, float max, vector<RGBA> colorSteps)
{
_minValue = min;
_maxValue = max;
_colorSteps = colorSteps;
}
ColorGradient::~ColorGradient()
{
_colorSteps.clear();
}
// Get the RGBA value at the give point
RGBA ColorGradient::GetRGBAValue(float inputValue)
{
if (inputValue <= _minValue)
{
return _colorSteps.front();
}
else if (inputValue >= _maxValue)
{
return _colorSteps.back();
}
float range = _maxValue - _minValue;
float value = inputValue - _minValue;
float steps = range / (float)(_colorSteps.size() - 1);
int colorStepInside = (int)(value / steps);
float normalisedValue = (value - (colorStepInside * steps)) / steps;
return Interpolate(_colorSteps[colorStepInside], _colorSteps[colorStepInside + 1], normalisedValue);
}
// Method for interpolating the color between each step
RGBA ColorGradient::Interpolate(RGBA a, RGBA b, float pointValue)
{
if (pointValue <= 0.0f)
{
return a;
}
else if (pointValue >= 1.0f)
{
return b;
}
unsigned int currentRed = (unsigned int)((1.0f - pointValue) * a.red + pointValue * b.red);
unsigned int currentGreen = (unsigned int)((1.0f - pointValue) * a.green + pointValue * b.green);
unsigned int currentBlue = (unsigned int)((1.0f - pointValue) * a.blue + pointValue * b.blue);
unsigned int currentAlpha = (unsigned int)((1.0f - pointValue) * a.alpha + pointValue * b.alpha);
return RGBA{ currentRed, currentGreen, currentBlue, currentAlpha };
}

34
Graphics2/ColorGradient.h Normal file
View File

@ -0,0 +1,34 @@
#pragma once
#include <vector>
using namespace std;
// Struct to hold the color data in
typedef struct RGBA {
unsigned int red;
unsigned int green;
unsigned int blue;
unsigned int alpha;
} RGBA;
// Class for dealing with color gradients, mainly for the terrain and blend mapping
class ColorGradient
{
public:
ColorGradient(float min, float max, vector<RGBA> colorSteps);
~ColorGradient();
// Get the RGBA value at the give point
RGBA GetRGBAValue(float inputValue);
private:
float _minValue;
float _maxValue;
// Method for interpolating the color between each step
RGBA Interpolate(RGBA a, RGBA b, float pointValue);
// Vector to hold the color steps in for the gradient
vector<RGBA> _colorSteps;
};

View File

@ -9,7 +9,7 @@ void Graphics2::CreateSceneGraph()
_turnSpeed = 1;
_invertPitch = -1;
GetCamera()->SetCameraPosition(0.0f, 320.0f, -80.0f);
GetCamera()->SetCameraPosition(0.0f, 550.0f, -80.0f);
SceneGraphPointer sceneGraph = GetSceneGraph();
@ -18,15 +18,20 @@ void Graphics2::CreateSceneGraph()
//cube->SetWorldTransform(XMMatrixScaling(5.0f, 8.0f, 2.5f) * XMMatrixTranslation(0, 23.0f, 0));
//sceneGraph->Add(cube);
shared_ptr<TerrainNode> terrainNode = make_shared<TerrainNode>(L"MainTerrain", L"Textures\\Example_HeightMap.raw", 1023, 1023, 10, 10);
shared_ptr<TerrainNode> terrainNode = make_shared<TerrainNode>(L"MainTerrain", L"Textures\\Example_HeightMap.raw", L"lovelycat");
terrainNode->SetAmbientLight(XMFLOAT4(0.7f, 0.7f, 0.7f, 1.0f));
terrainNode->SetDirectionalLight(XMVectorSet(0.5f, -1.0f, -1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f));
terrainNode->SetWaterColor(XMFLOAT4(SharedMethods::RGBValueToIntensity(0xA4), SharedMethods::RGBValueToIntensity(0xC1), SharedMethods::RGBValueToIntensity(0xF9), 1.0f));
//terrainNode->SetWaterColor(XMFLOAT4(1.0f, 0.0f, 0.8f, 1.0f));
//terrainNode->SetWaterColor(XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f));
sceneGraph->Add(terrainNode);
shared_ptr<SplitMeshNode> node = make_shared<SplitMeshNode>(L"Plane1", L"Models\\Plane\\Bonanza.3DS");
//shared_ptr<MeshNode> node = make_shared<MeshNode>(L"Plane1", L"Models\\Plane\\Bonanza.3DS");
node->SetWorldTransform(XMMatrixScaling(0.5f, 0.5f, 0.5f) * XMMatrixTranslation(-30.0f, 320.0f, 0));
node->SetWorldTransform(XMMatrixTranslation(-30.0f, 520.0f, 0));
sceneGraph->Add(node);
//SetBackgroundColour(XMFLOAT4(0.29f, 0.38f, 0.72f, 1.0f));
SetBackgroundColour(XMFLOAT4(0.29f, 0.38f, 0.72f, 1.0f));
//SetBackgroundColour(XMFLOAT4(SharedMethods::RGBValueToIntensity(0x89), 0, 1, 1));
_currentRotation = 0;

View File

@ -145,6 +145,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="Camera.h" />
<ClInclude Include="ColorGradient.h" />
<ClInclude Include="Core.h" />
<ClInclude Include="DDSTextureLoader.h" />
<ClInclude Include="DirectXCore.h" />
@ -152,10 +153,12 @@
<ClInclude Include="DirectXFramework.h" />
<ClInclude Include="GamePadController.h" />
<ClInclude Include="Graphics2.h" />
<ClInclude Include="HeightMapTerrainNode.h" />
<ClInclude Include="HelperFunctions.h" />
<ClInclude Include="Mesh.h" />
<ClInclude Include="MeshNode.h" />
<ClInclude Include="MeshRenderer.h" />
<ClInclude Include="PerlinTerrainNode.h" />
<ClInclude Include="Renderer.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="ResourceManager.h" />
@ -168,7 +171,6 @@
<ClInclude Include="targetver.h" />
<ClInclude Include="TerrainNode.h" />
<ClInclude Include="TexturedCubeNode.h" />
<ClInclude Include="Vector3D.h" />
<ClInclude Include="WICTextureLoader.h" />
</ItemGroup>
<ItemGroup>
@ -185,14 +187,17 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="Camera.cpp" />
<ClCompile Include="ColorGradient.cpp" />
<ClCompile Include="DDSTextureLoader.cpp" />
<ClCompile Include="Framework.cpp" />
<ClCompile Include="DirectXFramework.cpp" />
<ClCompile Include="GamePadController.cpp" />
<ClCompile Include="Graphics2.cpp" />
<ClCompile Include="HeightMapTerrainNode.cpp" />
<ClCompile Include="Mesh.cpp" />
<ClCompile Include="MeshNode.cpp" />
<ClCompile Include="MeshRenderer.cpp" />
<ClCompile Include="PerlinTerrainNode.cpp" />
<ClCompile Include="ResourceManager.cpp" />
<ClCompile Include="SceneGraph.cpp" />
<ClCompile Include="SharedMethods.cpp" />
@ -201,7 +206,6 @@
<ClCompile Include="SubMeshRenderer.cpp" />
<ClCompile Include="TerrainNode.cpp" />
<ClCompile Include="TexturedCubeNode.cpp" />
<ClCompile Include="Vector3D.cpp" />
<ClCompile Include="WICTextureLoader.cpp" />
</ItemGroup>
<ItemGroup>

View File

@ -93,7 +93,13 @@
<ClInclude Include="DDSTextureLoader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Vector3D.h">
<ClInclude Include="ColorGradient.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PerlinTerrainNode.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="HeightMapTerrainNode.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
@ -180,7 +186,13 @@
<ClCompile Include="DDSTextureLoader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Vector3D.cpp">
<ClCompile Include="ColorGradient.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PerlinTerrainNode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="HeightMapTerrainNode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>

View File

@ -12,12 +12,38 @@ float SharedMethods::RGBValueToIntensity(int value)
return (float)value / 255.0f;
}
float SharedMethods::lerp(int a, int b, int p)
float SharedMethods::Lerp(int a, int b, int p)
{
return lerp((float)a, (float)b, (float)p);
return Lerp((float)a, (float)b, (float)p);
}
float SharedMethods::lerp(float a, float b, float p)
float SharedMethods::Lerp(float a, float b, float p)
{
return a + p * (b - a);
}
float SharedMethods::GenerateRandomIntensity(float min, float max)
{
float randNo = (float)rand() / (float)RAND_MAX;
float rangeDiff = max - min;
float actualNo = randNo * rangeDiff;
int roundedNo = (int)(actualNo * 100 + 0.5f);
return (float)roundedNo * 0.01f;
}
float SharedMethods::GenerateRandomUV(int min, int max)
{
int randNo = rand() % ((max - min) + 1) + min;
float finalNo;
if (randNo < max)
{
int randMan = rand() % 90;
finalNo = (float)(randNo * 0.1f) + (randMan * 0.01f);
}
else
{
finalNo = (float)randNo * 0.1f;
}
return finalNo;
}

View File

@ -16,13 +16,33 @@ struct CBUFFER
float padding[2];
};
struct TCBUFFER
{
XMMATRIX completeTransformation;
XMMATRIX worldTransformation;
XMFLOAT4 cameraPosition;
XMVECTOR lightVector;
XMFLOAT4 lightColor;
XMFLOAT4 ambientColor;
XMFLOAT4 diffuseCoefficient;
XMFLOAT4 specularCoefficient;
float shininess;
float opacity;
float waterHeight;
float waterShininess;
XMFLOAT4 waterColor;
float padding[4];
};
namespace SharedMethods
{
XMMATRIX RotateFromPoint(float x, float y, float z, XMMATRIX rotationMatrix);
float RGBValueToIntensity(int value);
float lerp(int a, int b, int p);
float lerp(float a, float b, float p);
float Lerp(int a, int b, int p);
float Lerp(float a, float b, float p);
float GenerateRandomIntensity(float min, float max);
float GenerateRandomUV(int min, int max);
};

View File

@ -1,10 +1,14 @@
#include "TerrainNode.h"
#define WORLD_HEIGHT 512
#define WORLD_HEIGHT 1024
TerrainNode::TerrainNode(wstring name, wstring heightMap, int widthX, int widthZ, int cellSizeX, int cellSizeZ) : SceneNode(name)
TerrainNode::TerrainNode(wstring name, wstring heightMap, wstring seed, float waterHeight, wstring waterNormalMap, int widthX, int widthZ, int cellSizeX, int cellSizeZ) : SceneNode(name)
{
_heightMap = heightMap;
_seedString = seed;
_seedHash = std::hash<wstring>{}(_seedString);
srand(_seedHash);
_widthX = widthX;
_widthZ = widthZ;
@ -15,16 +19,45 @@ TerrainNode::TerrainNode(wstring name, wstring heightMap, int widthX, int widthZ
_cellSizeX = cellSizeX;
_cellSizeZ = cellSizeZ;
_waterHeight = waterHeight;
_waterNormalMapName = waterNormalMap;
_polygonsCount = (_gridCols * _gridRows) * 2;
_vertexCount = _polygonsCount * 2;
_indiciesCount = _polygonsCount * 3;
}
void TerrainNode::SetAmbientLight(XMFLOAT4 ambientLight)
{
_ambientLight = ambientLight;
}
void TerrainNode::SetWaterColor(XMFLOAT4 waterColor)
{
_waterColor = waterColor;
}
void TerrainNode::SetDirectionalLight(FXMVECTOR lightVector, XMFLOAT4 lightColor)
{
_directionalLightColor = lightColor;
XMStoreFloat4(&_directionalLightVector, lightVector);
}
void TerrainNode::SetCameraPosition(XMFLOAT4 cameraPosition)
{
_cameraPosition = cameraPosition;
}
bool TerrainNode::Initialise()
{
_device = DirectXFramework::GetDXFramework()->GetDevice();
_deviceContext = DirectXFramework::GetDXFramework()->GetDeviceContext();
if (_device.Get() == nullptr || _deviceContext.Get() == nullptr)
{
return false;
}
if (_heightMap.length() > 0)
{
if (LoadHeightMap(_heightMap))
@ -42,12 +75,15 @@ bool TerrainNode::Initialise()
}
GenerateTerrainData();
LoadTerrainTextures();
GenerateBlendMap();
BuildExtraMaps();
GenerateBuffers();
BuildShaders();
BuildVertexLayout();
BuildConstantBuffer();
BuildBlendState();
BuildRendererStates();
return true;
}
@ -60,6 +96,14 @@ void TerrainNode::GenerateTerrainData()
float centerWidth = totalWidth * -0.5f;
float centerDepth = totalDepth * 0.5f;
_terrainStartX = centerWidth;
_terrainStartZ = centerDepth;
_terrainEndX = centerWidth + totalWidth - 1;
_terrainEndZ = centerDepth - totalDepth + 1;
float bu = 1.0f / (float)(_gridCols - 1u);
float bv = 1.0f / (float)(_gridRows - 1u);
int currentVertexCount = 0;
for (int z = 0; z < _gridRows; z++)
{
@ -77,35 +121,56 @@ void TerrainNode::GenerateTerrainData()
offsetIndexZ = 0;
}
Vector3D polygonNormal = Vector3D(0.0f, 0.0f, 0.0f);
float rUA = 0.0f;
float rVA = rUA; // 0.0f;
float rUB = 1.0f;
float rVB = rUB;
VERTEX vertex;
/*int tumbleAmount = rand() % 10;
float prevUV = 0.0f;
bool firstTumble = true;
for (int ti = 0; ti < tumbleAmount; ti++)
{
prevUV = rVB;
rVB = rUB;
rUB = rVA;
rVA = rUA;
rUA = prevUV;
}*/
// TL
TerrainVertex vertex{};
vertex.Position = XMFLOAT3(x * _cellSizeX + centerWidth, GetHeightMapValueAt(currentIndex), (-z + 1) * _cellSizeZ + centerDepth);
vertex.Normal = XMFLOAT3(0.0f, 0.0f, 0.0f);
vertex.TexCoord = XMFLOAT2(0.0f, 1.0f);
vertex.TexCoord = XMFLOAT2(rUA, rVA);
vertex.BlendMapTexCoord = XMFLOAT2((bu * x), (bv * z));
_terrainVerts.push_back(vertex);
_terrainNormals.push_back(polygonNormal);
vertex = VERTEX();
// TR
vertex = TerrainVertex();
vertex.Position = XMFLOAT3((x + 1) * _cellSizeX + centerWidth, GetHeightMapValueAt(currentIndex + offsetIndexX), (-z + 1) * _cellSizeZ + centerDepth);
vertex.Normal = XMFLOAT3(0.0f, 0.0f, 0.0f);
vertex.TexCoord = XMFLOAT2(1.0f, 1.0f);
vertex.TexCoord = XMFLOAT2(rUB, rVA);
vertex.BlendMapTexCoord = XMFLOAT2((bu * (x + 1)), (bv * z));
_terrainVerts.push_back(vertex);
_terrainNormals.push_back(polygonNormal);
vertex = VERTEX();
// BL
vertex = TerrainVertex();
vertex.Position = XMFLOAT3(x * _cellSizeX + centerWidth, GetHeightMapValueAt(currentIndex + offsetIndexZ), -z * _cellSizeZ + centerDepth);
vertex.Normal = XMFLOAT3(0.0f, 0.0f, 0.0f);
vertex.TexCoord = XMFLOAT2(0.0f, 0.0f);
vertex.TexCoord = XMFLOAT2(rUA, rVB);
vertex.BlendMapTexCoord = XMFLOAT2((bu * x), (bv * (z + 1)));
_terrainVerts.push_back(vertex);
_terrainNormals.push_back(polygonNormal);
vertex = VERTEX();
// BR
vertex = TerrainVertex();
vertex.Position = XMFLOAT3((x + 1) * _cellSizeX + centerWidth, GetHeightMapValueAt(currentIndex + offsetIndexZ + offsetIndexX), -z * _cellSizeZ + centerDepth);
vertex.Normal = XMFLOAT3(0.0f, 0.0f, 0.0f);
vertex.TexCoord = XMFLOAT2(1.0f, 0.0f);
vertex.TexCoord = XMFLOAT2(rUB, rVB);
vertex.BlendMapTexCoord = XMFLOAT2((bu * (x + 1)), (bv * (z + 1)));
_terrainVerts.push_back(vertex);
_terrainNormals.push_back(polygonNormal);
_indices.push_back(currentVertexCount);
_indices.push_back(currentVertexCount + 1);
@ -123,19 +188,27 @@ void TerrainNode::GenerateTerrainData()
{
for (int x = 0; x < _gridCols; x++)
{
Vector3D vectorA = Vector3D(_terrainVerts[currentNormalIndex + 1].Position, _terrainVerts[currentNormalIndex].Position);
Vector3D vectorB = Vector3D(_terrainVerts[currentNormalIndex + 2].Position, _terrainVerts[currentNormalIndex].Position);
Vector3D polygonNormal = Vector3D::CrossProduct(vectorA, vectorB);
XMVECTOR v1 = XMVectorSet(_terrainVerts[currentNormalIndex + 1].Position.x - _terrainVerts[currentNormalIndex].Position.x,
_terrainVerts[currentNormalIndex + 1].Position.y - _terrainVerts[currentNormalIndex].Position.y,
_terrainVerts[currentNormalIndex + 1].Position.z - _terrainVerts[currentNormalIndex].Position.z,
0.0f);
XMVECTOR v2 = XMVectorSet(_terrainVerts[currentNormalIndex + 2].Position.x - _terrainVerts[currentNormalIndex].Position.x,
_terrainVerts[currentNormalIndex + 2].Position.y - _terrainVerts[currentNormalIndex].Position.y,
_terrainVerts[currentNormalIndex + 2].Position.z - _terrainVerts[currentNormalIndex].Position.z,
0.0f);
_terrainNormals[currentNormalIndex] += polygonNormal;
_terrainNormals[currentNormalIndex + 1] += polygonNormal;
_terrainNormals[currentNormalIndex + 2] += polygonNormal;
_terrainNormals[currentNormalIndex + 3] += polygonNormal;
XMVECTOR polygonNormal = XMVector3Cross(v1, v2);
XMStoreFloat3(&_terrainVerts[currentNormalIndex].Normal, XMVectorAdd(XMLoadFloat3(&_terrainVerts[currentNormalIndex].Normal), polygonNormal));
XMStoreFloat3(&_terrainVerts[currentNormalIndex + 1].Normal, XMVectorAdd(XMLoadFloat3(&_terrainVerts[currentNormalIndex + 1].Normal), polygonNormal));
XMStoreFloat3(&_terrainVerts[currentNormalIndex + 2].Normal, XMVectorAdd(XMLoadFloat3(&_terrainVerts[currentNormalIndex + 2].Normal), polygonNormal));
XMStoreFloat3(&_terrainVerts[currentNormalIndex + 3].Normal, XMVectorAdd(XMLoadFloat3(&_terrainVerts[currentNormalIndex + 3].Normal), polygonNormal));
AddNormalToVertex(z - 1, x - 1, 3, polygonNormal);
AddNormalToVertex(z - 1, x, 2, polygonNormal);
AddNormalToVertex(z - 1, x, 3, polygonNormal);
AddNormalToVertex(z - 1, x + 1, 2, polygonNormal);
AddNormalToVertex(z, x - 1, 1, polygonNormal);
AddNormalToVertex(z, x - 1, 3, polygonNormal);
AddNormalToVertex(z, x + 1, 0, polygonNormal);
@ -149,29 +222,24 @@ void TerrainNode::GenerateTerrainData()
}
}
for (int i = 0; i < _terrainNormals.size(); i++)
for (int i = 0; i < _terrainVerts.size(); i++)
{
_terrainNormals[i].Normalize();
_terrainVerts[i].Normal = _terrainNormals[i].Get();
XMVECTOR currentNormal = XMLoadFloat3(&_terrainVerts[i].Normal);
//XMVECTOR normalised = XMVector3Normalize(currentNormal);
XMStoreFloat3(&_terrainVerts[i].Normal, XMVector3Normalize(currentNormal));
}
_terrainNormals.clear();
}
void TerrainNode::AddNormalToVertex(int row, int col, int vertexIndex, Vector3D normal)
void TerrainNode::AddNormalToVertex(int row, int col, int vertexIndex, XMVECTOR normal)
{
int rowIndexOffset = row * _gridCols;
int colIndexOffset = col;
int finalIndex = vertexIndex + ((rowIndexOffset + colIndexOffset) * 4);
if (row >= 0 && row < _gridRows && col >= 0 && col < _gridCols)
if (row >= 0 && row < (int)_gridRows && col >= 0 && col < (int)_gridCols)
{
_terrainNormals[finalIndex] += normal;
}
if (row == _gridRows)
{
int test = 1;
XMStoreFloat3(&_terrainVerts[finalIndex].Normal, XMVectorAdd(XMLoadFloat3(&_terrainVerts[finalIndex].Normal), normal));
}
}
@ -181,7 +249,7 @@ void TerrainNode::GenerateBuffers()
// buffer should be
D3D11_BUFFER_DESC vertexBufferDescriptor;
vertexBufferDescriptor.Usage = D3D11_USAGE_IMMUTABLE;
vertexBufferDescriptor.ByteWidth = sizeof(VERTEX) * _vertexCount;
vertexBufferDescriptor.ByteWidth = sizeof(TerrainVertex) * _vertexCount;
vertexBufferDescriptor.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDescriptor.CPUAccessFlags = 0;
vertexBufferDescriptor.MiscFlags = 0;
@ -219,51 +287,50 @@ void TerrainNode::Render()
XMMATRIX projectionTransformation = DirectXFramework::GetDXFramework()->GetProjectionTransformation();
XMMATRIX viewTransformation = DirectXFramework::GetDXFramework()->GetCamera()->GetViewMatrix();
XMMATRIX completeTransformation = XMLoadFloat4x4(&_worldTransformation) * viewTransformation * projectionTransformation;
XMMATRIX completeTransformation = XMLoadFloat4x4(&_combinedWorldTransformation) * viewTransformation * projectionTransformation;
// Draw the first cube
CBUFFER cBuffer;
TCBUFFER cBuffer;
cBuffer.completeTransformation = completeTransformation;
cBuffer.worldTransformation = XMLoadFloat4x4(&_worldTransformation);
cBuffer.ambientColor = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
cBuffer.ambientColor = _ambientLight; // XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
//cBuffer.AmbientColor = XMFLOAT4(SharedMethods::RGBValueToIntensity(0xfd), 0.0f, 1.0f, 1.0f); //XMFLOAT4(1, 1, 1, 1); //_ambientLight;
cBuffer.lightVector = XMVector4Normalize(XMLoadFloat4(&_directionalLightVector));
cBuffer.lightColor = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
//cBuffer.LightColor = XMFLOAT4(SharedMethods::RGBValueToIntensity(0x89), 0.0f, 5.0f, 5.0f);
//cBuffer.LightColor = _directionalLightColor;
cBuffer.cameraPosition = DirectXFramework::GetDXFramework()->GetCamera()->GetRawCameraPosition();
//cBuffer.lightColor = XMFLOAT4(0.5f, 0.5f, 0.5f, 0.5f);
//cBuffer.LightColor = XMFLOAT4(SharedMethods::RGBValueToIntensity(0x89), 0.0f, 5.0f, 5.0f);
cBuffer.lightColor = _directionalLightColor;
XMStoreFloat4(&cBuffer.cameraPosition, DirectXFramework::GetDXFramework()->GetCamera()->GetCameraPosition());
cBuffer.waterHeight = _waterHeight;
cBuffer.waterShininess = 15.0f;
cBuffer.waterColor = _waterColor;
_deviceContext->PSSetShaderResources(0, 1, _blendMapResourceView.GetAddressOf());
_deviceContext->PSSetShaderResources(1, 1, _texturesResourceView.GetAddressOf());
_deviceContext->PSSetShaderResources(2, 1, _waterNormalMap.GetAddressOf());
_deviceContext->PSSetShaderResources(3, 1, _rngNoiseMap.GetAddressOf());
_deviceContext->VSSetShader(_vertexShader.Get(), 0, 0);
_deviceContext->PSSetShader(_pixelShader.Get(), 0, 0);
_deviceContext->IASetInputLayout(_layout.Get());
// Update the constant buffer
_deviceContext->VSSetConstantBuffers(0, 1, _constantBuffer.GetAddressOf());
_deviceContext->UpdateSubresource(_constantBuffer.Get(), 0, 0, &cBuffer, 0, 0);
// Set the texture to be used by the pixel shader
_deviceContext->PSSetShaderResources(0, 1, _texture.GetAddressOf());
UINT stride = sizeof(VERTEX);
UINT stride = sizeof(TerrainVertex);
UINT offset = 0;
_deviceContext->IASetVertexBuffers(0, 1, _vertexBuffer.GetAddressOf(), &stride, &offset);
_deviceContext->IASetIndexBuffer(_indexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);
cBuffer.diffuseCoefficient = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
cBuffer.diffuseCoefficient = XMFLOAT4(0.8f, 0.8f, 0.8f, 1.0f);
cBuffer.specularCoefficient = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
cBuffer.shininess = 1.0f;
cBuffer.opacity = 1.0f;
cBuffer.shininess = 10.0f;
cBuffer.opacity = 1.0f;
// Update the constant buffer
_deviceContext->VSSetConstantBuffers(0, 1, _constantBuffer.GetAddressOf());
_deviceContext->UpdateSubresource(_constantBuffer.Get(), 0, 0, &cBuffer, 0, 0);
_deviceContext->PSSetShaderResources(0, 1, _texture.GetAddressOf());
_deviceContext->PSSetConstantBuffers(0, 1, _constantBuffer.GetAddressOf());
_deviceContext->UpdateSubresource(_constantBuffer.Get(), 0, 0, &cBuffer, 0, 0);
_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
//_deviceContext->RSSetState(_wireframeRasteriserState.Get());
_deviceContext->DrawIndexed(_indiciesCount, 0, 0);
// Turn back face culling back on in case another renderer
// relies on it
_deviceContext->RSSetState(_defaultRasteriserState.Get());
}
void TerrainNode::Shutdown(void)
@ -280,7 +347,7 @@ void TerrainNode::BuildShaders()
ComPtr<ID3DBlob> compilationMessages = nullptr;
//Compile vertex shader
HRESULT hr = D3DCompileFromFile(L"TerrainShadersNoBlend.hlsl",
HRESULT hr = D3DCompileFromFile(L"TerrainShaders.hlsl",
nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE,
"VShader", "vs_5_0",
shaderCompileFlags, 0,
@ -297,7 +364,7 @@ void TerrainNode::BuildShaders()
ThrowIfFailed(_device->CreateVertexShader(_vertexShaderByteCode->GetBufferPointer(), _vertexShaderByteCode->GetBufferSize(), NULL, _vertexShader.GetAddressOf()));
// Compile pixel shader
hr = D3DCompileFromFile(L"TerrainShadersNoBlend.hlsl",
hr = D3DCompileFromFile(L"TerrainShaders.hlsl",
nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE,
"PShader", "ps_5_0",
shaderCompileFlags, 0,
@ -334,27 +401,11 @@ void TerrainNode::BuildConstantBuffer()
D3D11_BUFFER_DESC bufferDesc;
ZeroMemory(&bufferDesc, sizeof(bufferDesc));
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.ByteWidth = sizeof(CBUFFER);
bufferDesc.ByteWidth = sizeof(TCBUFFER);
bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
ThrowIfFailed(_device->CreateBuffer(&bufferDesc, NULL, _constantBuffer.GetAddressOf()));
}
void TerrainNode::BuildBlendState()
{
D3D11_BLEND_DESC transparentDesc = { 0 };
transparentDesc.AlphaToCoverageEnable = false;
transparentDesc.IndependentBlendEnable = false;
transparentDesc.RenderTarget[0].BlendEnable = true;
transparentDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
transparentDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
transparentDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
transparentDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO;
transparentDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
transparentDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
transparentDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
ThrowIfFailed(_device->CreateBlendState(&transparentDesc, _transparentBlendState.GetAddressOf()));
}
void TerrainNode::BuildRendererStates()
{
// Set default and wireframe rasteriser states
@ -403,8 +454,198 @@ float TerrainNode::GetHeightMapValueAt(int index)
float result = 0;
if (_usedHeightMap)
{
result = _heightValues[index] * WORLD_HEIGHT; // +(rand() % 10);
result = _heightValues[index] * WORLD_HEIGHT; // +(rand() % 10);
}
return result;
}
void TerrainNode::LoadTerrainTextures()
{
// Change the paths below as appropriate for your use
wstring terrainTextureNames[5] = { L"Textures\\grass.dds", L"Textures\\darkdirt.dds", L"Textures\\stone.dds", L"Textures\\lightdirt.dds", L"Textures\\snow.dds" };
// Load the textures from the files
ComPtr<ID3D11Resource> terrainTextures[5];
for (int i = 0; i < 5; i++)
{
ThrowIfFailed(CreateDDSTextureFromFileEx(_device.Get(),
_deviceContext.Get(),
terrainTextureNames[i].c_str(),
0,
D3D11_USAGE_IMMUTABLE,
D3D11_BIND_SHADER_RESOURCE,
0,
0,
false,
terrainTextures[i].GetAddressOf(),
nullptr
));
}
// Now create the Texture2D arrary. We assume all textures in the
// array have the same format and dimensions
D3D11_TEXTURE2D_DESC textureDescription;
ComPtr<ID3D11Texture2D> textureInterface;
terrainTextures[0].As<ID3D11Texture2D>(&textureInterface);
textureInterface->GetDesc(&textureDescription);
D3D11_TEXTURE2D_DESC textureArrayDescription;
textureArrayDescription.Width = textureDescription.Width;
textureArrayDescription.Height = textureDescription.Height;
textureArrayDescription.MipLevels = textureDescription.MipLevels;
textureArrayDescription.ArraySize = 5;
textureArrayDescription.Format = textureDescription.Format;
textureArrayDescription.SampleDesc.Count = 1;
textureArrayDescription.SampleDesc.Quality = 0;
textureArrayDescription.Usage = D3D11_USAGE_DEFAULT;
textureArrayDescription.BindFlags = D3D11_BIND_SHADER_RESOURCE;
textureArrayDescription.CPUAccessFlags = 0;
textureArrayDescription.MiscFlags = 0;
ComPtr<ID3D11Texture2D> textureArray = 0;
ThrowIfFailed(_device->CreateTexture2D(&textureArrayDescription, 0, textureArray.GetAddressOf()));
// Copy individual texture elements into texture array.
for (UINT i = 0; i < 5; i++)
{
// For each mipmap level...
for (UINT mipLevel = 0; mipLevel < textureDescription.MipLevels; mipLevel++)
{
_deviceContext->CopySubresourceRegion(textureArray.Get(),
D3D11CalcSubresource(mipLevel, i, textureDescription.MipLevels),
NULL,
NULL,
NULL,
terrainTextures[i].Get(),
mipLevel,
nullptr
);
}
}
// Create a resource view to the texture array.
D3D11_SHADER_RESOURCE_VIEW_DESC viewDescription;
viewDescription.Format = textureArrayDescription.Format;
viewDescription.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
viewDescription.Texture2DArray.MostDetailedMip = 0;
viewDescription.Texture2DArray.MipLevels = textureArrayDescription.MipLevels;
viewDescription.Texture2DArray.FirstArraySlice = 0;
viewDescription.Texture2DArray.ArraySize = 5;
ThrowIfFailed(_device->CreateShaderResourceView(textureArray.Get(), &viewDescription, _texturesResourceView.GetAddressOf()));
}
void TerrainNode::GenerateBlendMap()
{
RGBA snowTops = RGBA{ 0u, 0u, 0u, 255u };
RGBA grassLand = RGBA{ 0u, 0u, 50u, 0u };
RGBA lightDirt = RGBA{ 50u, 0u, 255u, 0u };
RGBA darkDirt = RGBA{ 255u, 0u, 0u, 0u };
vector<RGBA> colorSteps = {darkDirt, lightDirt, grassLand, grassLand, grassLand, snowTops};
ColorGradient terrainBlendGradient = ColorGradient(30.0f, 650.0f, colorSteps);
// Note that _numberOfRows and _numberOfColumns need to be setup
// to the number of rows and columns in your grid in order for this
// to work.
DWORD* blendMap = new DWORD[_gridCols * _gridRows];
DWORD* blendMapPtr = blendMap;
BYTE r;
BYTE g;
BYTE b;
BYTE a;
DWORD index = 0;
for (DWORD i = 0; i < _gridRows; i++)
{
for (DWORD j = 0; j < _gridCols; j++)
{
// Calculate the appropriate blend colour for the
// current location in the blend map. This has been
// left as an exercise for you. You need to calculate
// appropriate values for the r, g, b and a values (each
// between 0 and 255). The code below combines these
// into a DWORD (32-bit value) and stores it in the blend map.
int currentIndex = ((i * _gridCols) + j) * 4;
float totalHeights = 0.0f;
float biggestSlope = 0.0f;
for (int si = 0; si < 4; si++)
{
totalHeights += _terrainVerts[currentIndex + si].Position.y;
if (_terrainVerts[currentIndex + si].Normal.y > biggestSlope)
{
biggestSlope = _terrainVerts[currentIndex + si].Normal.y;
}
}
float avgHeight = totalHeights / 4.0f;
RGBA currentBlend = terrainBlendGradient.GetRGBAValue(avgHeight);
r = currentBlend.red;
g = currentBlend.green;
b = currentBlend.blue;
a = currentBlend.alpha;
DWORD mapValue = (a << 24) + (b << 16) + (g << 8) + r;
*blendMapPtr++ = mapValue;
}
}
D3D11_TEXTURE2D_DESC blendMapDescription;
blendMapDescription.Width = _gridCols;
blendMapDescription.Height = _gridRows;
blendMapDescription.MipLevels = 1;
blendMapDescription.ArraySize = 1;
blendMapDescription.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
blendMapDescription.SampleDesc.Count = 1;
blendMapDescription.SampleDesc.Quality = 0;
blendMapDescription.Usage = D3D11_USAGE_DEFAULT;
blendMapDescription.BindFlags = D3D11_BIND_SHADER_RESOURCE;
blendMapDescription.CPUAccessFlags = 0;
blendMapDescription.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA blendMapInitialisationData;
blendMapInitialisationData.pSysMem = blendMap;
blendMapInitialisationData.SysMemPitch = 4 * _gridCols;
ComPtr<ID3D11Texture2D> blendMapTexture;
ThrowIfFailed(_device->CreateTexture2D(&blendMapDescription, &blendMapInitialisationData, blendMapTexture.GetAddressOf()));
// Create a resource view to the texture array.
D3D11_SHADER_RESOURCE_VIEW_DESC viewDescription;
viewDescription.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
viewDescription.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
viewDescription.Texture2D.MostDetailedMip = 0;
viewDescription.Texture2D.MipLevels = 1;
ThrowIfFailed(_device->CreateShaderResourceView(blendMapTexture.Get(), &viewDescription, _blendMapResourceView.GetAddressOf()));
delete[] blendMap;
}
void TerrainNode::BuildExtraMaps()
{
// Note that in order to use CreateWICTextureFromFile, we
// need to ensure we make a call to CoInitializeEx in our
// Initialise method (and make the corresponding call to
// CoUninitialize in the Shutdown method). Otherwise,
// the following call will throw an exception
ThrowIfFailed(CreateWICTextureFromFile(_device.Get(),
_deviceContext.Get(),
_waterNormalMapName.c_str(),
nullptr,
_waterNormalMap.GetAddressOf()
));
ThrowIfFailed(CreateWICTextureFromFile(_device.Get(),
_deviceContext.Get(),
L"Textures\\noiseMap.png",
nullptr,
_rngNoiseMap.GetAddressOf()
));
}

View File

@ -1,15 +1,31 @@
#pragma once
#include "DirectXFramework.h"
#include <fstream>
#include <vector>
#include "ColorGradient.h"
#include "DDSTextureLoader.h"
#include "WICTextureLoader.h"
#include "SharedMethods.h"
#include "SceneNode.h"
#include "Vector3D.h"
typedef struct TerrainVertex
{
XMFLOAT3 Position;
XMFLOAT3 Normal;
XMFLOAT2 TexCoord;
XMFLOAT2 BlendMapTexCoord;
} TerrainVertex;
class TerrainNode : public SceneNode
{
public:
TerrainNode(wstring name, wstring heightMap, int widthX = 1023, int widthZ = 1023, int rows = 10, int cols = 10);
TerrainNode(wstring name, wstring heightMap, wstring seed, float waterHeight = 150.0f, wstring waterNormalMap = L"Textures\\waterNormals.bmp", int widthX = 1023, int widthZ = 1023, int cellSizeX = 10, int cellSizeZ = 10);
void SetAmbientLight(XMFLOAT4 ambientLight);
void SetWaterColor(XMFLOAT4 waterColor);
void SetDirectionalLight(FXMVECTOR lightVector, XMFLOAT4 lightColor);
void SetCameraPosition(XMFLOAT4 cameraPosition);
bool Initialise(void);
void Render(void);
@ -19,14 +35,16 @@ private:
int _widthX;
int _widthZ;
UINT _gridRows;
UINT _gridCols;
unsigned int _gridRows;
unsigned int _gridCols;
int _cellSizeX;
int _cellSizeZ;
bool _usedHeightMap;
float _waterHeight;
UINT _polygonsCount;
UINT _indiciesCount;
UINT _vertexCount;
@ -37,12 +55,12 @@ private:
float _terrainEndZ;
wstring _heightMap;
wstring _textureName;
wstring _seedString;
unsigned int _seedHash;
vector<VERTEX> _terrainVerts;
vector<TerrainVertex> _terrainVerts;
vector<int> _indices;
vector<float> _heightValues;
vector<Vector3D> _terrainNormals;
XMFLOAT4 _ambientLight;
XMFLOAT4 _directionalLightVector;
@ -62,24 +80,31 @@ private:
ComPtr<ID3D11InputLayout> _layout;
ComPtr<ID3D11Buffer> _constantBuffer;
ComPtr<ID3D11ShaderResourceView> _texture;
ComPtr<ID3D11BlendState> _transparentBlendState;
ComPtr<ID3D11ShaderResourceView> _texturesResourceView;
ComPtr<ID3D11ShaderResourceView> _blendMapResourceView;
ComPtr<ID3D11RasterizerState> _defaultRasteriserState;
ComPtr<ID3D11RasterizerState> _wireframeRasteriserState;
ComPtr<ID3D11ShaderResourceView> _rngNoiseMap;
ComPtr<ID3D11ShaderResourceView> _waterNormalMap;
wstring _waterNormalMapName;
XMFLOAT4 _waterColor;
void GenerateTerrainData();
void GenerateBuffers();
void BuildShaders();
void BuildVertexLayout();
void BuildConstantBuffer();
void BuildBlendState();
void BuildRendererStates();
void BuildTexture();
void LoadTerrainTextures();
void GenerateBlendMap();
bool LoadHeightMap(wstring heightMapFilename);
float GetHeightMapValueAt(int index);
void AddNormalToVertex(int row, int col, int vertexIndex, Vector3D normal);
void AddNormalToVertex(int row, int col, int vertexIndex, XMVECTOR normal);
void BuildExtraMaps();
};

View File

@ -10,11 +10,17 @@ cbuffer ConstantBuffer
float4 specularCoefficient; // The specular reflection cooefficient
float shininess; // The shininess factor
float opacity; // The opacity (transparency) of the material. 0 = fully transparent, 1 = fully opaque
float2 padding;
float waterHeight;
float waterShininess;
float4 waterColor;
float padding[4];
}
Texture2D BlendMap : register(t0);
Texture2DArray TexturesArray : register(t1);
Texture2D WaterNormalMap : register(t2);
Texture2D rngNoiseMap : register(t3);
SamplerState ss
{
@ -41,10 +47,26 @@ struct PixelShaderInput
float2 BlendMapTexCoord : TEXCOORD1;
};
float2 UVRotate(float2 uvCoord, float2 pivotPoint, float rotation)
{
float2x2 rotateMatrix = float2x2(float2(sin(rotation), -cos(rotation)), float2(cos(rotation), sin(rotation)));
uvCoord -= pivotPoint;
uvCoord = mul(uvCoord, rotateMatrix);
uvCoord += pivotPoint;
return uvCoord;
}
PixelShaderInput VShader(VertexShaderInput vin)
{
PixelShaderInput output;
PixelShaderInput output;
float3 position = vin.Position;
if (position.y < waterHeight)
{
position.y = waterHeight - 0.01f;
}
output.Position = mul(completeTransformation, float4(position, 1.0f));
output.PositionWS = mul(worldTransformation, float4(position, 1.0f));
output.NormalWS = float4(mul((float3x3)worldTransformation, vin.Normal), 1.0f);
@ -53,12 +75,25 @@ PixelShaderInput VShader(VertexShaderInput vin)
return output;
}
float4 hash4(float2 v)
{
float4 p = mul(float4x2(127.1, 311.7, 269.5, 183.3, 113.5, 271.9, 246.1, 124.6), v);
return frac(sin(p) * 43758.5453123);
}
float4 PShader(PixelShaderInput input) : SV_TARGET
{
float4 directionToCamera = normalize(input.PositionWS - cameraPosition);
float4 directionToLight = normalize(-lightVector);
float surfaceShininess = shininess;
float4 adjustedNormal = normalize(input.NormalWS);
if (input.PositionWS.y < waterHeight)
{
float3 n0 = (float3)WaterNormalMap.Sample(ss, input.TexCoord);
float4 n2 = float4(mul((float3x3)worldTransformation, n0), 1.0f);
adjustedNormal = n2;
surfaceShininess = waterShininess;
}
// Calculate diffuse lighting
float NdotL = max(0, dot(adjustedNormal, directionToLight));
@ -74,16 +109,34 @@ float4 PShader(PixelShaderInput input) : SV_TARGET
// Calculate ambient lighting
float4 ambientLight = ambientColor * diffuseCoefficient;
float4 color;
float4 randSamp = rngNoiseMap.Sample(ss, input.BlendMapTexCoord);
// Sample layers in texture array.
float4 c0 = TexturesArray.Sample(ss, float3(input.TexCoord, 0.0f));
float4 c1 = TexturesArray.Sample(ss, float3(input.TexCoord, 1.0f));
float4 c2 = TexturesArray.Sample(ss, float3(input.TexCoord, 2.0f));
float4 c3 = TexturesArray.Sample(ss, float3(input.TexCoord, 3.0f));
float4 c4 = TexturesArray.Sample(ss, float3(input.TexCoord, 4.0f));
float2 scaleCenter = float2(0.5f, 0.5f);
float currentScale = randSamp.r;
float2 scaledUV = frac(UVRotate(input.TexCoord, scaleCenter, currentScale)); // (input.TexCoord - scaleCenter) * currentScale + scaleCenter;
float2 xChange = ddx(scaledUV);
float2 yChange = ddy(scaledUV);
/*if (xChange.x < 0)
{
xChange = float2(0, 0);
}
if (yChange.y < 0)
{
yChange = float2(0, 0);
}*/
// Sample layers in texture array.
float4 c0 = TexturesArray.SampleGrad(ss, float3(scaledUV, 0.0f), xChange, yChange);
float4 c1 = TexturesArray.SampleGrad(ss, float3(scaledUV, 1.0f), xChange, yChange);
float4 c2 = TexturesArray.SampleGrad(ss, float3(scaledUV, 2.0f), xChange, yChange);
float4 c3 = TexturesArray.SampleGrad(ss, float3(scaledUV, 3.0f), xChange, yChange);
float4 c4 = TexturesArray.SampleGrad(ss, float3(scaledUV, 4.0f), xChange, yChange);
// Sample the blend map.
float4 t = BlendMap.Sample(ss, input.BlendMapTexCoord);
float4 t = BlendMap.Sample(ss, input.BlendMapTexCoord);
// Blend the layers on top of each other.
color = c0;
@ -93,7 +146,11 @@ float4 PShader(PixelShaderInput input) : SV_TARGET
color = lerp(color, c4, t.a);
// Combine all components
if (input.PositionWS.y < waterHeight)
{
color = color * waterColor;
}
color = (ambientLight + diffuse) * color;
color = saturate(color + specular);
color = saturate(color + specular);
return color;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

View File

@ -1,104 +0,0 @@
#include "Vector3D.h"
Vector3D::Vector3D(float x, float y, float z)
{
_vector.x = x;
_vector.y = y;
_vector.z = z;
}
Vector3D::Vector3D(XMFLOAT3 vertexA, XMFLOAT3 vertexB)
{
_vector.x = vertexB.x - vertexA.x;
_vector.y = vertexB.y - vertexA.y;
_vector.z = vertexB.z - vertexA.z;
}
Vector3D::Vector3D(const Vector3D& other)
{
Copy(other);
}
Vector3D::~Vector3D()
{
}
XMFLOAT3 Vector3D::Get() const
{
return _vector;
}
const void Vector3D::Normalize()
{
float length = (float) sqrt((_vector.x * _vector.x) + (_vector.y + _vector.y) + (_vector.z * _vector.z));
if (length != 0)
{
_vector.x /= length;
_vector.y /= length;
_vector.z /= length;
}
}
float Vector3D::DotProduct(const Vector3D v1, const Vector3D v2)
{
return v1.Get().x * v2.Get().x + v1.Get().y * v2.Get().y + v1.Get().z * v2.Get().z;
}
float Vector3D::Length(const Vector3D v1, const Vector3D v2)
{
return (float)sqrt(pow((v1.Get().x - v2.Get().x), 2) + pow((v1.Get().y - v2.Get().y), 2) + pow((v1.Get().z - v2.Get().z), 2));
}
Vector3D Vector3D::CrossProduct(Vector3D v1, Vector3D v2)
{
// v1.GetY() * v2.GetZ() - v1.GetZ() * v2.GetY()
float crossedX = v1.Get().y * v2.Get().z - v1.Get().z * v2.Get().y;
// v1.GetZ() * v2.GetX() - v1.GetX() * v2.GetZ()
float crossedY = v1.Get().z * v2.Get().x - v1.Get().x * v2.Get().z;
// v1.GetX() * v2.GetY() - v1.GetY() * v2.GetX()
float crossedZ = v1.Get().x * v2.Get().y - v1.Get().y * v2.Get().x;
return Vector3D(crossedX, crossedY, crossedZ);
}
Vector3D& Vector3D::operator= (const Vector3D& rhs)
{
if (this != &rhs)
{
Copy(rhs);
}
return *this;
}
const Vector3D Vector3D::operator+ (const Vector3D& rhs) const
{
return Vector3D(_vector.x + rhs.Get().x, _vector.y + rhs.Get().y, _vector.z + rhs.Get().z);
}
Vector3D& Vector3D::operator+= (const Vector3D& rhs)
{
_vector.x += rhs.Get().x;
_vector.y += rhs.Get().y;
_vector.z += rhs.Get().z;
return *this;
}
const Vector3D Vector3D::operator/ (const float rhs) const
{
return Vector3D(_vector.x / rhs, _vector.y / rhs, _vector.z / rhs);
}
const Vector3D Vector3D::operator/ (const int rhs) const
{
return Vector3D(_vector.x / rhs, _vector.y / rhs, _vector.z / rhs);
}
void Vector3D::Copy(const Vector3D& other)
{
_vector.x = other.Get().x;
_vector.y = other.Get().y;
_vector.z = other.Get().z;
}

View File

@ -1,33 +0,0 @@
#pragma once
#include "DirectXFramework.h"
#include "SharedMethods.h"
class Vector3D
{
public:
Vector3D(float x, float y, float z);
Vector3D(XMFLOAT3 vertexA, XMFLOAT3 vertexB);
Vector3D(const Vector3D& other);
~Vector3D();
XMFLOAT3 Get() const;
const void Normalize();
static float DotProduct(const Vector3D v1, const Vector3D v2);
static float Length(const Vector3D v1, const Vector3D v2);
static Vector3D CrossProduct(const Vector3D v1, const Vector3D v2);
Vector3D& operator= (const Vector3D& rhs);
const Vector3D operator+ (const Vector3D& rhs) const;
Vector3D& operator+= (const Vector3D& rhs);
const Vector3D operator/ (const float rhs) const;
const Vector3D operator/ (const int rhs) const;
private:
XMFLOAT3 _vector;
void Copy(const Vector3D& other);
};