Skip to content

Commit

Permalink
Merge pull request #25 from LeeVangraefschepe/terrain-component
Browse files Browse the repository at this point in the history
Added terrain component
  • Loading branch information
AtlantiaKing authored Oct 29, 2023
2 parents ba6e6f8 + ca2aa9b commit 74e675f
Show file tree
Hide file tree
Showing 32 changed files with 806 additions and 113 deletions.
154 changes: 154 additions & 0 deletions Data/Heightmap.fx
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
float4x4 gWorld : WORLD;
float4x4 gWorldViewProj : WORLDVIEWPROJECTION;
float4x4 gLightViewProj : LIGHTVIEWPROJECTION;
float3 gLightDirection = float3(-0.577f, -0.577f, 0.577f);
float4 gColor = float4(1.0f, 1.0f, 1.0f, 1.0f);

Texture2D gShadowMap;
Texture2D gHeightMap;

float gMaxHeight = 100;

struct VS_INPUT {
float3 pos : POSITION;
float2 uv : TEXCOORD0;
};
struct VS_OUTPUT {
float4 pos : SV_POSITION;
float3 normal : NORMAL;
float4 lPos : TEXCOORD1;
};

SamplerState samLinear
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap; // or Mirror or Clamp or Border
AddressV = Wrap; // or Mirror or Clamp or Border
};

DepthStencilState EnableDepth
{
DepthEnable = TRUE;
DepthWriteMask = ALL;
};

RasterizerState BackCulling
{
CullMode = BACK;
};

float gShadowMapBias = 0.0005f;

float2 texOffset(int u, int v)
{
return float2(u / 1280.0f, v / 720.0f);
}

SamplerComparisonState cmpSampler
{
// sampler state
Filter = COMPARISON_MIN_MAG_MIP_LINEAR;
AddressU = MIRROR;
AddressV = MIRROR;

// sampler comparison state
ComparisonFunc = LESS_EQUAL;
};

float EvaluateShadowMap(float4 lpos)
{
// Re-homogenize position after interpolation
lpos.xyz /= lpos.w;

// If position is not visible to the light - dont illuminate it
// Results in hard light frustum
if (lpos.x < -1.0f || lpos.x > 1.0f ||
lpos.y < -1.0f || lpos.y > 1.0f ||
lpos.z < 0.0f || lpos.z > 1.0f)
return 1.0f;

// Transform clip space coords to texture space coords (-1:1 to 0:1)
lpos.x = lpos.x / 2.0f + 0.5f;
lpos.y = lpos.y / -2.0f + 0.5f;

// Apply shadow map bias
lpos.z -= gShadowMapBias;

// PCF sampling for shadow map
float sum = 0;

// Perform PCF filtering on a 4 x 4 texel neighborhood
for (float y = -1.5; y <= 1.5; y += 1.0)
{
for (float x = -1.5; x <= 1.5; x += 1.0)
{
sum += gShadowMap.SampleCmpLevelZero(cmpSampler, lpos.xy + texOffset(x, y), lpos.z);
}
}

float shadowMapDepth = sum / 16.0;

return shadowMapDepth * 0.5f + 0.5f;
}

//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
VS_OUTPUT VS(VS_INPUT input)
{
VS_OUTPUT output;
float2 heightMapPos = input.uv;
// Step 1: convert position into float4 and multiply with matWorldViewProj
float height = gHeightMap[heightMapPos];

float L = gHeightMap[heightMapPos + float2(-1.0f, 0.0f)] * gMaxHeight;
float R = gHeightMap[heightMapPos + float2(1.0f, 0.0f)] * gMaxHeight;
float T = gHeightMap[heightMapPos + float2(0.0f, 1.0f)] * gMaxHeight;
float B = gHeightMap[heightMapPos + float2(0.0f, -1.0f)] * gMaxHeight;

output.pos = mul(float4(input.pos + float3(0, height * gMaxHeight, 0), 1.0f), gWorldViewProj);
// Step 2: rotate the normal: NO TRANSLATION
// this is achieved by clipping the 4x4 to a 3x3 matrix,
// thus removing the postion row of the matrix
float3 normal = normalize(float3(-R + L, 4, -T + B));
output.normal = /*normalize(mul(normal, (float3x3) gWorld))*/normal;
output.lPos = mul(float4(input.pos, 1.0f), mul(gWorld, gLightViewProj));

return output;
}

//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS(VS_OUTPUT input) : SV_TARGET
{
float shadowValue = EvaluateShadowMap(input.lPos);

float3 color_rgb = gColor.rgb;
float color_a = gColor.a;

//HalfLambert Diffuse :)
float diffuseStrength = dot(input.normal, -gLightDirection);
diffuseStrength = diffuseStrength * 0.5 + 0.5;
diffuseStrength = saturate(diffuseStrength);
color_rgb = color_rgb * diffuseStrength;

return float4(color_rgb * shadowValue, color_a);
}

//--------------------------------------------------------------------------------------
// Technique
//--------------------------------------------------------------------------------------
technique11 DefaultTechnique
{
pass P0
{
SetRasterizerState(BackCulling);
SetDepthStencilState(EnableDepth, 0);

SetVertexShader(CompileShader(vs_4_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_4_0, PS()));
}
}

Binary file added Data/Heightmap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions Graphics/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ add_library(GraphicsEngine STATIC
"DirectX/DirectXSpriteRenderer.cpp"
"Shaders/Sprites.cpp"
"DirectX/DirectXDefaults.cpp"
"Shaders/Heightmap.cpp"
)

set(GraphicsEngineIncludeDir "${CMAKE_CURRENT_SOURCE_DIR}" PARENT_SCOPE)
Expand Down
12 changes: 12 additions & 0 deletions Graphics/Camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ void leap::graphics::Camera::SetTransform(const glm::mat4x3& transform)
m_IsDirty = true;
}

void leap::graphics::Camera::SetFarPlane(float farPlane)
{
m_FarC = farPlane;
CalculateProjectionMatrix();
}

void leap::graphics::Camera::SetNearPlane(float nearPlane)
{
m_NearC = nearPlane;
CalculateProjectionMatrix();
}

const glm::mat4x4& leap::graphics::Camera::GetViewMatrix()
{
if (m_IsDirty) CalculateViewMatrix();
Expand Down
4 changes: 4 additions & 0 deletions Graphics/Camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@ namespace leap::graphics
void SetAspectRatio(const glm::ivec2& size);
void SetColor(const glm::vec4& color) { m_Color = color; }
void SetTransform(const glm::mat4x3& transform);
void SetFarPlane(float farPlane);
void SetNearPlane(float nearPlane);

const glm::vec4& GetColor() const { return m_Color; }
const glm::mat4x4& GetInverseViewMatrix();
const glm::mat4x4& GetViewMatrix();
const glm::mat4x4& GetProjectionMatrix() const;
float GetFarPlane() const { return m_FarC; }
float GetNearPlane() const { return m_NearC; }

private:
glm::vec4 m_Color{ 0.39f, 0.59f, 0.93f, 1.f };
Expand Down
39 changes: 35 additions & 4 deletions Graphics/Data/CustomMesh.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,45 @@
#pragma once

#include "Vertex.h"
#include <Debug.h>

#include <vector>

namespace leap::graphics
{
struct CustomMesh final
class CustomMesh final
{
std::vector<Vertex> vertices{};
std::vector<unsigned int> indices{};
public:
template<typename T>
void AddVertex(const T& vertex)
{
constexpr unsigned int vertexSize{ sizeof(T) };

if (m_PrevSize != 0 && vertexSize != m_PrevSize) Debug::LogError("LeapEngine Graphics Error : Custom Mesh received two different kinds of vertex types");

const size_t vertexStart{ m_Vertices.size() };

m_Vertices.resize(m_Vertices.size() + vertexSize);
memcpy_s(&m_Vertices[vertexStart], vertexSize, &vertex, vertexSize);

m_PrevSize = vertexSize;
}
void AddIndex(unsigned int index)
{
m_Indices.emplace_back(index);
}
void SetIndices(std::vector<unsigned int>&& indices)
{
m_Indices = indices;
}

const std::vector<unsigned char>& GetVertexBuffer() const { return m_Vertices; }
unsigned int GetVertexSize() const { return m_PrevSize; }
const std::vector<unsigned int>& GetIndexBuffer() const { return m_Indices; }

private:
unsigned int m_PrevSize{};

std::vector<unsigned char> m_Vertices{};
std::vector<unsigned int> m_Indices{};
};
}
8 changes: 6 additions & 2 deletions Graphics/Data/Vertex.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ namespace leap::graphics
glm::vec3 normal{};
glm::vec2 uv{};
glm::vec3 tangent{};
glm::vec4 color{ 1.0f, 1.0f, 1.0f, 1.0f };
glm::vec3 viewDirection{};
};

struct VertexPosUV
{
glm::vec3 position{};
glm::vec2 uv{};
};
}
3 changes: 2 additions & 1 deletion Graphics/DirectX/DirectXDefaults.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ leap::graphics::DirectXMaterial* leap::graphics::DirectXDefaults::GetMaterialErr
return m_pNoMeshMaterial.get();
}

void leap::graphics::DirectXDefaults::GetMeshError(ID3D11Device* pDevice, ID3D11Buffer*& pVertexBuffer, ID3D11Buffer*& pIndexBuffer, unsigned int& nrIndices)
void leap::graphics::DirectXDefaults::GetMeshError(ID3D11Device* pDevice, unsigned int& vertexSize, ID3D11Buffer*& pVertexBuffer, ID3D11Buffer*& pIndexBuffer, unsigned int& nrIndices)
{
const DirectXMeshLoader::DirectXMeshDefinition& mesh{ DirectXMeshLoader::GetInstance().LoadMesh("Data/Engine/Models/error.obj", pDevice)};
vertexSize = mesh.vertexSize;
pVertexBuffer = mesh.vertexBuffer;
pIndexBuffer = mesh.indexBuffer;
nrIndices = mesh.nrIndices;
Expand Down
2 changes: 1 addition & 1 deletion Graphics/DirectX/DirectXDefaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace leap::graphics

DirectXMaterial* GetMaterialNotFound(ID3D11Device* pDevice);
DirectXMaterial* GetMaterialError(ID3D11Device* pDevice);
static void GetMeshError(ID3D11Device* pDevice, ID3D11Buffer*& pVertexBuffer, ID3D11Buffer*& pIndexBuffer, unsigned int& nrIndices);
static void GetMeshError(ID3D11Device* pDevice, unsigned int& vertexSize, ID3D11Buffer*& pVertexBuffer, ID3D11Buffer*& pIndexBuffer, unsigned int& nrIndices);

void Reload(ID3D11Device* pDevice) const;
private:
Expand Down
24 changes: 22 additions & 2 deletions Graphics/DirectX/DirectXEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,23 @@ leap::graphics::ITexture* leap::graphics::DirectXEngine::CreateTexture(const std
return it->second.get();
}

auto pTexture{ std::make_unique<DirectXTexture>(m_pDevice, path) };
auto pTexture{ std::make_unique<DirectXTexture>(m_pDevice, m_pDeviceContext, path) };
auto pTextureRaw{ pTexture.get() };

m_pTextures[path] = std::move(pTexture);
return pTextureRaw;
}

leap::graphics::ITexture* leap::graphics::DirectXEngine::CreateTexture(int width, int height)
{
auto pTexture{ std::make_unique<DirectXTexture>(m_pDevice, m_pDeviceContext, width, height) };
auto pTextureRaw{ pTexture.get() };

m_pUniqueTextures.emplace_back(std::move(pTexture));

return pTextureRaw;
}

void leap::graphics::DirectXEngine::SetDirectionLight(const glm::mat3x3& transform)
{
if (!m_pCamera) return;
Expand Down Expand Up @@ -183,6 +193,12 @@ void leap::graphics::DirectXEngine::Release()

void leap::graphics::DirectXEngine::ReloadDirectXEngine()
{
// Store all the previous texture information to reapply it later to reloaded textures
for (const auto& pTexture : m_pUniqueTextures)
{
pTexture->StoreData(m_pDevice);
}

// Release the previous version of the graphics engine
Release();

Expand Down Expand Up @@ -285,7 +301,11 @@ void leap::graphics::DirectXEngine::ReloadDirectXEngine()
// Reload existing textures, materials & meshes using new video settings
for (const auto& texturePair : m_pTextures)
{
texturePair.second->Reload(m_pDevice, texturePair.first);
texturePair.second->Reload(m_pDevice, m_pDeviceContext, texturePair.first);
}
for (const auto& pTexture : m_pUniqueTextures)
{
pTexture->Reload(m_pDevice, m_pDeviceContext);
}

for (const auto& materialPair : m_pMaterials)
Expand Down
9 changes: 6 additions & 3 deletions Graphics/DirectX/DirectXEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct ID3D11RenderTargetView;
#include "../DirectionalLight.h"

#include "DirectXRenderTarget.h"
#include "DirectXTexture.h"
#include "DirectXMeshRenderer.h"
#include "DirectXMaterial.h"

Expand All @@ -30,7 +31,6 @@ namespace leap::graphics
class Camera;
class IMeshRenderer;
class IMaterial;
class DirectXTexture;

class DirectXEngine final : public IRenderer
{
Expand Down Expand Up @@ -58,8 +58,8 @@ namespace leap::graphics
virtual void SetDirectionLight(const glm::mat3x3& transform) override;

// Meshes
virtual IMeshRenderer* CreateMeshRenderer();
virtual void RemoveMeshRenderer(IMeshRenderer* pMeshRenderer);
virtual IMeshRenderer* CreateMeshRenderer() override;
virtual void RemoveMeshRenderer(IMeshRenderer* pMeshRenderer) override;

// Sprites
virtual void AddSprite(Sprite* pSprite) override;
Expand All @@ -69,6 +69,8 @@ namespace leap::graphics
virtual IMaterial* CreateMaterial(std::unique_ptr<Shader, ShaderDelete> pShader, const std::string& name) override;
virtual IMaterial* CloneMaterial(const std::string& original, const std::string& clone) override;
virtual ITexture* CreateTexture(const std::string& path) override;
virtual ITexture* CreateTexture(int width, int height) override;

private:
void Release();
void ReloadDirectXEngine();
Expand All @@ -88,6 +90,7 @@ namespace leap::graphics
std::vector<std::unique_ptr<DirectXMeshRenderer>> m_pRenderers{};
std::unordered_map<std::string, std::unique_ptr<DirectXMaterial>> m_pMaterials{};
std::unordered_map<std::string, std::unique_ptr<DirectXTexture>> m_pTextures{};
std::vector<std::unique_ptr<DirectXTexture>> m_pUniqueTextures{};

bool m_IsInitialized{};
Camera* m_pCamera{};
Expand Down
Loading

0 comments on commit 74e675f

Please sign in to comment.