Merge branch 'main' into ImGui-NoScripting

This commit is contained in:
CatChow0 2024-04-25 10:32:30 +02:00
commit 911b9bf8cc
29 changed files with 1966 additions and 45 deletions

72
KhaoticDemo/water.ps Normal file
View File

@ -0,0 +1,72 @@
/////////////
// GLOBALS //
/////////////
SamplerState SampleType : register(s0);
Texture2D reflectionTexture : register(t0);
Texture2D refractionTexture : register(t1);
Texture2D normalTexture : register(t2);
cbuffer WaterBuffer
{
float waterTranslation;
float reflectRefractScale;
float2 padding;
};
//////////////
// TYPEDEFS //
//////////////
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
float4 reflectionPosition : TEXCOORD1;
float4 refractionPosition : TEXCOORD2;
};
////////////////////////////////////////////////////////////////////////////////
// Pixel Shader
////////////////////////////////////////////////////////////////////////////////
float4 WaterPixelShader(PixelInputType input) : SV_TARGET
{
float2 reflectTexCoord;
float2 refractTexCoord;
float4 normalMap;
float3 normal;
float4 reflectionColor;
float4 refractionColor;
float4 color;
// Move the position the water normal is sampled from to simulate moving water.
input.tex.y += waterTranslation;
// Calculate the projected reflection texture coordinates.
reflectTexCoord.x = input.reflectionPosition.x / input.reflectionPosition.w / 2.0f + 0.5f;
reflectTexCoord.y = -input.reflectionPosition.y / input.reflectionPosition.w / 2.0f + 0.5f;
// Calculate the projected refraction texture coordinates.
refractTexCoord.x = input.refractionPosition.x / input.refractionPosition.w / 2.0f + 0.5f;
refractTexCoord.y = -input.refractionPosition.y / input.refractionPosition.w / 2.0f + 0.5f;
// Sample the normal from the normal map texture.
normalMap = normalTexture.Sample(SampleType, input.tex);
// Expand the range of the normal from (0,1) to (-1,+1).
normal = (normalMap.xyz * 2.0f) - 1.0f;
// Re-position the texture coordinate sampling position by the normal map value to simulate the rippling wave effect.
reflectTexCoord = reflectTexCoord + (normal.xy * reflectRefractScale);
refractTexCoord = refractTexCoord + (normal.xy * reflectRefractScale);
// Sample the texture pixels from the textures using the updated texture coordinates.
reflectionColor = reflectionTexture.Sample(SampleType, reflectTexCoord);
refractionColor = refractionTexture.Sample(SampleType, refractTexCoord);
// Combine the reflection and refraction results for the final color.
color = lerp(reflectionColor, refractionColor, 0.6f);
return color;
}

View File

@ -2,7 +2,7 @@
Khaotic Engine est un moteur de rendu fait en **C++** réalisé par une petite équipe dans le but d'apprendre à utiliser les API de rendu (OpenGL,DirectX 11/12 et Vulkan).
Ce moteur est basé sur **DirectX11** utilise **ImGui** avec une couche d'abstraction pour permetre son usage avec d'autres API.
Ce moteur est basé sur **DirectX11** utilise **ImGui** et **Boost** avec une couche d'abstraction pour permetre son usage avec d'autres API.
---
@ -10,15 +10,14 @@ Khaotic Engine is a rendering engine made in **C++** by a small team with the ai
This **DirectX11** based engine uses **ImGui** with an abstraction layer to enable its use with other APIs.
## Installation
**Par la solution + Debogueur :**
**Depuis la solution + Debugger**
1. Télécharger la Release Beta
2. Dezip le Zip
3. Ouvrir le fichier en .sln
4. Lancer le déboguage
1. Télécharge la Beta
2. Dézip le .zip
3. Ouvre le fichier .sln
4. Build en Release
----
@ -27,7 +26,8 @@ This **DirectX11** based engine uses **ImGui** with an abstraction layer to enab
1. Download the Beta Release
2. Unzip the Zip file
3. Open the .sln file
4. Launch the debugger
4. Set the debugger in "Release"
5. Launch the debugger
@ -45,6 +45,9 @@ This **DirectX11** based engine uses **ImGui** with an abstraction layer to enab
- **Clipping Planes**
- **Texture Translation**
- **Transparency**
- **Water**
- **Refraction**
- *Reflection (cassé / broken)*
*Plus de shaders seront disponibles dans le futur*
@ -70,7 +73,7 @@ La librairie ImGui est utilisée afin d'interragir avec les éléments du moteur
- Modifier les propriétées des lumières (Position, Couleur RVB)
----
*This part of the engine is still in developpement, other features will be added in the future*
*This part of the engine is still in development, other features will be added in the future*
ImGui is used to allow interaction between the user and the objects in the scene.
@ -89,6 +92,13 @@ ImGui is used to allow interaction between the user and the objects in the scene
[![Demo Video](https://img.youtube.com/vi/qCOCTyB_97c/0.jpg)](https://www.youtube.com/watch?v=qCOCTyB_97c)
## Bug Report :
Vous pouvez signalez les problèmes en ouvrant un ticket dans [Issues](https://github.com/GamingCampus-AdrienBourgois/khaotic-engine/issues)
----
You can report bugs with the program by creating a ticket in [Issues](https://github.com/GamingCampus-AdrienBourgois/khaotic-engine/issues)
## Engine Build by :
[](https://github.com/GamingCampus-AdrienBourgois/khaotic-engine?tab=readme-ov-file#engine-build-by-)
@ -105,3 +115,4 @@ ImGui is used to allow interaction between the user and the objects in the scene

View File

@ -75,13 +75,13 @@ void LightShaderClass::Shutdown()
}
bool LightShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[])
ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[], XMFLOAT4 ambientClor[])
{
bool result;
// Set the shader parameters that it will use for rendering.
result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, diffuseColor, lightPosition);
result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, diffuseColor, lightPosition, ambientClor);
if(!result)
{
Logger::Get().Log("Failed to set shader parameters", __FILE__, __LINE__, Logger::LogLevel::Error);
@ -418,7 +418,7 @@ void LightShaderClass::OutputShaderErrorMessage(ID3D10Blob* errorMessage, HWND h
bool LightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[])
ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[], XMFLOAT4 ambientColor[])
{
HRESULT result;
D3D11_MAPPED_SUBRESOURCE mappedResource;

View File

@ -67,14 +67,14 @@ public:
bool Initialize(ID3D11Device*, HWND);
void Shutdown();
bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4[], XMFLOAT4[]);
bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4[], XMFLOAT4[], XMFLOAT4[]);
private:
bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*);
void ShutdownShader();
void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*);
bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4[], XMFLOAT4[]);
bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4[], XMFLOAT4[], XMFLOAT4[]);
void RenderShader(ID3D11DeviceContext*, int);
private:

View File

@ -19,7 +19,11 @@ ApplicationClass::ApplicationClass() : m_ShouldQuit(false)
m_Position = 0;
m_Frustum = 0;
m_DisplayPlane = 0;
m_ReflectionShader = 0;
m_BathModel = 0;
m_WaterModel = 0;
m_Light = 0;
m_RefractionTexture = 0;
m_ReflectionTexture = 0;
}
@ -192,6 +196,7 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
m_Light->SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f);
m_Light->SetDirection(0.0f, 0.0f, -1.0f);
m_Light->SetAmbientColor(0.15f, 0.15f, 0.15f, 1.0f);
m_Light->SetSpecularColor(1.0f, 1.0f, 1.0f, 1.0f);
m_Light->SetSpecularPower(16.0f);
@ -203,6 +208,7 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
m_Lights[0] = new LightClass;
m_Lights[0]->SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f); // White
m_Lights[0]->SetDirection(0.0f, 0.0f, -1.0f);
m_Lights[0]->SetAmbientColor(0.15f, 0.15f, 0.15f, 1.0f);
m_Lights[0]->SetSpecularColor(1.0f, 1.0f, 1.0f, 1.0f);
m_Lights[0]->SetSpecularPower(16.0f);
m_Lights[0]->SetPosition(10.0f, 7.0f, -5.0f);
@ -210,6 +216,7 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
m_Lights[1] = new LightClass;
m_Lights[1]->SetDiffuseColor(1.0f, 0.0f, 0.0f, 1.0f); // Red
m_Lights[1]->SetDirection(0.0f, 0.0f, -1.0f);
m_Lights[1]->SetAmbientColor(0.15f, 0.15f, 0.15f, 1.0f);
m_Lights[1]->SetSpecularColor(1.0f, 0.0f, 0.0f, 1.0f);
m_Lights[1]->SetSpecularPower(16.0f);
m_Lights[1]->SetPosition(-10.0f, 7.0f, -5.0f);
@ -217,6 +224,7 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
m_Lights[2] = new LightClass;
m_Lights[2]->SetDiffuseColor(0.0f, 1.0f, 0.0f, 1.0f); // Green
m_Lights[2]->SetDirection(0.0f, 0.0f, -1.0f);
m_Lights[2]->SetAmbientColor(0.15f, 0.15f, 0.15f, 1.0f);
m_Lights[2]->SetSpecularColor(0.0f, 1.0f, 0.0f, 1.0f);
m_Lights[2]->SetSpecularPower(16.0f);
m_Lights[2]->SetPosition(10.0f, 7.0f, 5.0f);
@ -224,6 +232,7 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
m_Lights[3] = new LightClass;
m_Lights[3]->SetDiffuseColor(0.0f, 0.0f, 1.0f, 1.0f); // Blue
m_Lights[3]->SetDirection(0.0f, 0.0f, -1.0f);
m_Lights[3]->SetAmbientColor(0.15f, 0.15f, 0.15f, 1.0f);
m_Lights[3]->SetSpecularColor(0.0f, 0.0f, 1.0f, 1.0f);
m_Lights[3]->SetSpecularPower(16.0f);
m_Lights[3]->SetPosition(-10.0f, 7.0f, 5.0f);
@ -255,6 +264,60 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
m_ModelList = new ModelListClass;
m_ModelList->Initialize(25);
// Set the file names of the bath model.
strcpy_s(modelFilename, "bath.txt");
Filename.push_back("marble01.tga");
// Create and initialize the bath model object.
m_BathModel = new ModelClass;
result = m_BathModel->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, Filename);
if (!result)
{
MessageBox(hwnd, L"Could not initialize the bath model object.", L"Error", MB_OK);
return false;
}
// Set the file names of the water model.
strcpy_s(modelFilename, "water.txt");
Filename.push_back("water01.tga");
// Create and initialize the water model object.
m_WaterModel = new ModelClass;
result = m_WaterModel->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, Filename);
if (!result)
{
MessageBox(hwnd, L"Could not initialize the water model object.", L"Error", MB_OK);
return false;
}
// Create and initialize the refraction render to texture object.
m_RefractionTexture = new RenderTextureClass;
result = m_RefractionTexture->Initialize(m_Direct3D->GetDevice(), screenWidth, screenHeight, SCREEN_DEPTH, SCREEN_NEAR, 1);
if (!result)
{
MessageBox(hwnd, L"Could not initialize the refraction render texture object.", L"Error", MB_OK);
return false;
}
// Create and initialize the reflection render to texture object.
m_ReflectionTexture = new RenderTextureClass;
result = m_ReflectionTexture->Initialize(m_Direct3D->GetDevice(), screenWidth, screenHeight, SCREEN_DEPTH, SCREEN_NEAR, 1);
if (!result)
{
MessageBox(hwnd, L"Could not initialize the reflection render texture object.", L"Error", MB_OK);
return false;
}
// Set the height of the water.
m_waterHeight = -9.25f;
// Initialize the position of the water.
m_waterTranslation = 100.0f;
// Create and initialize the timer object.
m_Timer = new TimerClass;
@ -317,6 +380,38 @@ void ApplicationClass::Shutdown()
Logger::Get().Log("Shader manager object released", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
}
// Release the reflection render texture object.
if (m_ReflectionTexture)
{
m_ReflectionTexture->Shutdown();
delete m_ReflectionTexture;
m_ReflectionTexture = 0;
}
// Release the refraction render texture object.
if (m_RefractionTexture)
{
m_RefractionTexture->Shutdown();
delete m_RefractionTexture;
m_RefractionTexture = 0;
}
// Release the water model object.
if (m_WaterModel)
{
m_WaterModel->Shutdown();
delete m_WaterModel;
m_WaterModel = 0;
}
// Release the bath model object.
if (m_BathModel)
{
m_BathModel->Shutdown();
delete m_BathModel;
m_BathModel = 0;
}
// Release the frustum class object.
if (m_Frustum)
{
@ -593,6 +688,28 @@ bool ApplicationClass::Frame(InputClass* Input)
rotation += 360.0f;
}
// Update the position of the water to simulate motion.
m_waterTranslation += 0.001f;
if (m_waterTranslation > 1.0f)
{
m_waterTranslation -= 1.0f;
}
// Render the refraction of the scene to a texture.
result = RenderRefractionToTexture();
if (!result)
{
return false;
}
// Render the reflection of the scene to a texture.
result = RenderReflectionToTexture();
if (!result)
{
return false;
}
//// Update the x position variable each frame.
//x -= 0.0174532925f * 0.6f;
@ -641,6 +758,91 @@ bool ApplicationClass::Frame(InputClass* Input)
return true;
}
bool ApplicationClass::RenderRefractionToTexture()
{
XMMATRIX worldMatrix, viewMatrix, projectionMatrix;
XMFLOAT4 diffuseColor[4], lightPosition[4], ambientColor[4];
XMFLOAT4 clipPlane;
int i;
bool result;
// Setup a clipping plane based on the height of the water to clip everything above it.
clipPlane = XMFLOAT4(0.0f, -1.0f, 0.0f, m_waterHeight + 0.1f);
// Set the render target to be the refraction render to texture and clear it.
m_RefractionTexture->SetRenderTarget(m_Direct3D->GetDeviceContext());
m_RefractionTexture->ClearRenderTarget(m_Direct3D->GetDeviceContext(), 0.0f, 0.0f, 0.0f, 1.0f);
// Generate the view matrix based on the camera's position.
m_Camera->Render();
// Get the world, view, and projection matrices from the camera and d3d objects.
m_Direct3D->GetWorldMatrix(worldMatrix);
m_Camera->GetViewMatrix(viewMatrix);
m_Direct3D->GetProjectionMatrix(projectionMatrix);
// 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();
// Create the light position array from the four light positions.
ambientColor[i] = m_Lights[i]->GetAmbientColor();
}
// Translate to where the bath model will be rendered.
worldMatrix = XMMatrixTranslation(0.0f, -10.0f, 0.0f);
// Render the bath model using the refraction shader.
m_BathModel->Render(m_Direct3D->GetDeviceContext());
result = m_ShaderManager->RenderRefractionShader(m_Direct3D->GetDeviceContext(), m_BathModel->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix,
m_BathModel->GetTexture(0), m_Lights[0]->GetDirection(), ambientColor, diffuseColor, lightPosition, clipPlane);
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::RenderReflectionToTexture()
{
XMMATRIX worldMatrix, reflectionViewMatrix, projectionMatrix;
XMFLOAT4 diffuseColor[4], getDirection[4], ambientColor[4];
bool result;
// Set the render target to be the reflection render to texture and clear it.
m_ReflectionTexture->SetRenderTarget(m_Direct3D->GetDeviceContext());
m_ReflectionTexture->ClearRenderTarget(m_Direct3D->GetDeviceContext(), 0.0f, 0.0f, 0.0f, 1.0f);
// Use the camera to render the reflection and create a reflection view matrix.
m_Camera->RenderReflection(m_waterHeight);
// Get the camera reflection view matrix instead of the normal view matrix.
m_Camera->GetReflectionViewMatrix(reflectionViewMatrix);
// Get the world and projection matrices from the d3d object.
m_Direct3D->GetWorldMatrix(worldMatrix);
m_Direct3D->GetProjectionMatrix(projectionMatrix);
// 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::RenderSceneToTexture(float rotation)
{
XMMATRIX worldMatrix, viewMatrix, projectionMatrix;
@ -680,9 +882,9 @@ bool ApplicationClass::RenderSceneToTexture(float rotation)
bool ApplicationClass::Render(float rotation, float x, float y, float z, float textureTranslation)
{
XMMATRIX worldMatrix, viewMatrix, orthoMatrix, projectionMatrix, rotateMatrix, translateMatrix, scaleMatrix, srMatrix;
XMMATRIX worldMatrix, viewMatrix, orthoMatrix, projectionMatrix, rotateMatrix, translateMatrix, scaleMatrix, srMatrix, reflectionMatrix;
float positionX, positionY, positionZ, radius;
XMFLOAT4 diffuseColor[4], lightPosition[4];
XMFLOAT4 diffuseColor[4], lightPosition[4], getDirection[4], ambientColor[4];
int modelCount, renderCount, i;
bool result, renderModel;
float blendAmount;
@ -708,6 +910,9 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t
// Create the light position array from the four light positions.
lightPosition[i] = m_Lights[i]->GetPosition();
// Create the light position array from the four light positions.
ambientColor[i] = m_Lights[i]->GetPosition();
}
scaleMatrix = XMMatrixScaling(0.5f, 0.5f, 0.5f); // Build the scaling matrix.
@ -723,7 +928,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t
// Render the model using the light shader.
result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(0),
diffuseColor, lightPosition);
diffuseColor, lightPosition, ambientColor);
for (auto cube : m_cubes)
{
@ -753,7 +958,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t
}
result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, cube->GetTexture(0),
diffuseColor, lightPosition);
diffuseColor, lightPosition,ambientColor);
if (!result)
{
Logger::Get().Log("Could not render the cube model using the light shader", __FILE__, __LINE__, Logger::LogLevel::Error);
@ -785,7 +990,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t
}
result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(0),
diffuseColor, lightPosition);
diffuseColor, lightPosition, ambientColor);
if (!result)
{
@ -808,7 +1013,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t
chunk->Render(m_Direct3D->GetDeviceContext());
result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), chunk->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, chunk->GetTexture(5),
diffuseColor, lightPosition);
diffuseColor, lightPosition, ambientColor);
if (!result)
{
@ -890,7 +1095,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t
m_Model->Render(m_Direct3D->GetDeviceContext());
result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(0),
diffuseColor, lightPosition);
diffuseColor, lightPosition, ambientColor);
if (!result)
{
Logger::Get().Log("Could not render the model using the light shader", __FILE__, __LINE__, Logger::LogLevel::Error);
@ -998,14 +1203,41 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t
lightPosition[i] = m_Lights[i]->GetPosition();
}
// Translate to where the bath model will be rendered.
worldMatrix = XMMatrixTranslation(0.0f, -10.0f, 0.0f);
// Put the bath model vertex and index buffers on the graphics pipeline to prepare them for drawing.
m_BathModel->Render(m_Direct3D->GetDeviceContext());
// 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 bath model using the light shader.
result = m_ShaderManager->RenderTextureShader(m_Direct3D->GetDeviceContext(), m_BathModel->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix,
m_BathModel->GetTexture(0));
if (!result)
{
return false;
}
//// Render the model using the multitexture shader.
//m_Model->Render(m_Direct3D->GetDeviceContext());
// Reset the world matrix.
m_Direct3D->GetWorldMatrix(worldMatrix);
// Get the camera reflection view matrix.
m_Camera->GetReflectionViewMatrix(reflectionMatrix);
// Translate to where the water model will be rendered.
worldMatrix = XMMatrixTranslation(0.0f, m_waterHeight, 0.0f);
// Put the water model vertex and index buffers on the graphics pipeline to prepare them for drawing.
m_WaterModel->Render(m_Direct3D->GetDeviceContext());
// Render the water model using the water shader.
result = m_ShaderManager->RenderWaterShader(m_Direct3D->GetDeviceContext(), m_WaterModel->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, reflectionMatrix,
m_ReflectionTexture->GetShaderResourceView(), m_RefractionTexture->GetShaderResourceView(), m_WaterModel->GetTexture(0),
m_waterTranslation, 0.01f);
if (!result)
{
return false;
}
// Setup matrices.
rotateMatrix = XMMatrixRotationY(rotation);
@ -1129,7 +1361,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t
// Render the model using the transparent shader.
m_Model->Render(m_Direct3D->GetDeviceContext());
result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(0), diffuseColor, lightPosition);
result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(0), diffuseColor, lightPosition, ambientColor);
if (!result)
{
return false;

View File

@ -8,12 +8,10 @@
#include "d3dclass.h"
#include "cameraclass.h"
#include "object.h"
#include "lightshaderclass.h"
#include "lightclass.h"
#include <vector>
#include <filesystem>
#include "lightmapshaderclass.h"
#include "bitmapclass.h"
#include "spriteclass.h"
#include "timerclass.h"
@ -28,8 +26,6 @@
#include "frustumclass.h"
#include "rendertextureclass.h"
#include "displayplaneclass.h"
#include "reflectionshaderclass.h"
#include "systemclass.h"
/////////////
@ -90,6 +86,8 @@ private:
bool UpdateFps();
bool UpdateRenderCountString(int);
bool RenderSceneToTexture(float);
bool RenderRefractionToTexture();
bool RenderReflectionToTexture();
private :
@ -99,7 +97,7 @@ private :
D3DClass* m_Direct3D;
IDXGISwapChain* m_swapChain;
ModelClass* m_Model;
ModelClass* m_Model,* m_GroundModel, * m_WallModel, * m_BathModel, * m_WaterModel;
ModelListClass* m_ModelList;
// ------------------------------------- //
@ -107,7 +105,7 @@ private :
// ------------------------------------- //
XMMATRIX m_baseViewMatrix;
RenderTextureClass* m_RenderTexture;
RenderTextureClass* m_RenderTexture, * m_RefractionTexture, * m_ReflectionTexture;
DisplayPlaneClass* m_DisplayPlane;
int m_screenWidth, m_screenHeight;
CameraClass* m_Camera;
@ -138,11 +136,15 @@ private :
ShaderManagerClass* m_ShaderManager;
FontShaderClass* m_FontShader;
ReflectionShaderClass* m_ReflectionShader;
BitmapClass* m_Bitmap;
SpriteClass* m_Sprite;
// ----------------------------------- //
// ------------ VARIABLES ------------ //
// ----------------------------------- //
float m_waterHeight, m_waterTranslation;
// ------------------------------------------------- //
// ------------- FPS AND INFO ON SCREEN ------------ //
// ------------------------------------------------- //

82
enginecustom/bath.txt Normal file
View File

@ -0,0 +1,82 @@
Vertex Count: 78
Data:
4 -0.5 -4 0.998008 0.998008 0 1 -0
-4 -0.5 4 0.001992 0.00199199 0 1 -0
4 -0.5 4 0.998008 0.00199199 0 1 -0
4 -0.5 -4 0.998008 0.998008 0 1 -0
-4 -0.5 -4 0.001992 0.998008 0 1 -0
-4 -0.5 4 0.001992 0.00199199 0 1 -0
4 1 4 0.187127 0.998008 0 0 -1
-4 -0.5 4 0.000374 0.00199199 0 0 -1
-4 1 4 0.187127 0.00199199 0 0 -1
4 -0.5 4 0.000374 0.998008 0 0 -1
-4 -0.5 4 0.000374 0.00199199 0 0 -1
4 1 4 0.187127 0.998008 0 0 -1
4 1 -4 0.187126 0.998008 -1 0 -0
4 -0.5 4 0.000373 0.00199199 -1 0 -0
4 1 4 0.187126 0.00199199 -1 0 -0
4 -0.5 -4 0.000373 0.998008 -1 0 -0
4 -0.5 4 0.000373 0.00199199 -1 0 -0
4 1 -4 0.187126 0.998008 -1 0 -0
-4 1 -4 0.000374 0.00199199 0 0 1
4 -0.5 -4 0.187127 0.998008 0 0 1
4 1 -4 0.000374 0.998008 0 0 1
-4 1 -4 0.000374 0.00199199 0 0 1
-4 -0.5 -4 0.187127 0.00199199 0 0 1
4 -0.5 -4 0.187127 0.998008 0 0 1
-4 1 4 0.187127 0.998008 1 0 -0
-4 -0.5 -4 0.000374 0.00199199 1 0 -0
-4 1 -4 0.187127 0.00199199 1 0 -0
-4 -0.5 4 0.000374 0.998008 1 0 -0
-4 -0.5 -4 0.000374 0.00199199 1 0 -0
-4 1 4 0.187127 0.998008 1 0 -0
-5 1 5 0.199602 0.00199199 -1 0 -0
-5 -1 -5 0.000398 0.998008 -1 0 -0
-5 -1 5 0.000398 0.00199199 -1 0 -0
-5 1 -5 0.199602 0.998008 -1 0 -0
-5 -1 -5 0.000398 0.998008 -1 0 -0
-5 1 5 0.199602 0.00199199 -1 0 -0
5 1 -5 0.199602 0.00199199 1 0 -0
5 -1 5 0.000398 0.998008 1 0 -0
5 -1 -5 0.000398 0.00199199 1 0 -0
5 1 5 0.199602 0.998008 1 0 -0
5 -1 5 0.000398 0.998008 1 0 -0
5 1 -5 0.199602 0.00199199 1 0 -0
-5 -1 5 0.199602 0.00199199 0 0 1
5 1 5 0.000398 0.998008 0 0 1
-5 1 5 0.000398 0.00199199 0 0 1
5 -1 5 0.199602 0.998008 0 0 1
5 1 5 0.000398 0.998008 0 0 1
-5 -1 5 0.199602 0.00199199 0 0 1
-5 1 5 0.001992 0.00199199 0 1 -0
-4 1 -4 0.101594 0.898406 0 1 -0
-5 1 -5 0.001992 0.998008 0 1 -0
-5 1 5 0.001992 0.00199199 0 1 -0
-4 1 4 0.101594 0.101594 0 1 -0
-4 1 -4 0.101594 0.898406 0 1 -0
-4 1 -4 0.101594 0.898406 0 1 -0
5 1 -5 0.998008 0.998008 0 1 -0
-5 1 -5 0.001992 0.998008 0 1 -0
4 1 -4 0.898406 0.898406 0 1 -0
5 1 -5 0.998008 0.998008 0 1 -0
-4 1 -4 0.101594 0.898406 0 1 -0
4 1 -4 0.898406 0.898406 0 1 -0
5 1 5 0.998008 0.00199199 0 1 -0
5 1 -5 0.998008 0.998008 0 1 -0
4 1 4 0.898406 0.101594 0 1 -0
5 1 5 0.998008 0.00199199 0 1 -0
4 1 -4 0.898406 0.898406 0 1 -0
4 1 4 0.898406 0.101594 0 1 -0
-5 1 5 0.001992 0.00199199 0 1 -0
5 1 5 0.998008 0.00199199 0 1 -0
-5 1 5 0.001992 0.00199199 0 1 -0
4 1 4 0.898406 0.101594 0 1 -0
-4 1 4 0.101594 0.101594 0 1 -0
-5 1 -5 0.199602 0.00199199 0 0 -1
5 -1 -5 0.000398 0.998008 0 0 -1
-5 -1 -5 0.000398 0.00199199 0 0 -1
5 1 -5 0.199602 0.998008 0 0 -1
5 -1 -5 0.000398 0.998008 0 0 -1
-5 1 -5 0.199602 0.00199199 0 0 -1

View File

@ -48,6 +48,7 @@
<ClCompile Include="modellistclass.cpp" />
<ClCompile Include="Multitextureshaderclass.cpp" />
<ClCompile Include="normalmapshaderclass.cpp" />
<ClCompile Include="refractionshaderclass.cpp" />
<ClCompile Include="shadermanagerclass.cpp" />
<ClCompile Include="positionclass.cpp" />
<ClCompile Include="reflectionshaderclass.cpp" />
@ -61,6 +62,7 @@
<ClCompile Include="Timerclass.cpp" />
<ClCompile Include="translateshaderclass.cpp" />
<ClCompile Include="transparentshaderclass.cpp" />
<ClCompile Include="watershaderclass.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="alphamapshaderclass.h" />
@ -93,6 +95,7 @@
<ClInclude Include="modellistclass.h" />
<ClInclude Include="Multitextureshaderclass.h" />
<ClInclude Include="normalmapshaderclass.h" />
<ClInclude Include="refractionshaderclass.h" />
<ClInclude Include="shadermanagerclass.h" />
<ClInclude Include="positionclass.h" />
<ClInclude Include="reflectionshaderclass.h" />
@ -107,6 +110,7 @@
<ClInclude Include="Timerclass.h" />
<ClInclude Include="translateshaderclass.h" />
<ClInclude Include="transparentshaderclass.h" />
<ClInclude Include="watershaderclass.h" />
</ItemGroup>
<ItemGroup>
<CopyFileToFolders Include="alphamap.ps">
@ -145,6 +149,7 @@
<CopyFileToFolders Include="normalmap.vs">
<FileType>Document</FileType>
</CopyFileToFolders>
<None Include="..\KhaoticDemo\water.ps" />
<None Include="packages.config" />
<CopyFileToFolders Include="reflection.ps">
<FileType>Document</FileType>
@ -170,6 +175,9 @@
<CopyFileToFolders Include="transparent.vs">
<FileType>Document</FileType>
</CopyFileToFolders>
<None Include="refraction.ps" />
<None Include="refraction.vs" />
<None Include="water.vs" />
</ItemGroup>
<ItemGroup>
<CopyFileToFolders Include="Color.ps">
@ -203,6 +211,7 @@
<CopyFileToFolders Include="sprite04.tga" />
<CopyFileToFolders Include="stone01.tga" />
<Image Include="wall.tga" />
<Image Include="water01.tga" />
</ItemGroup>
<ItemGroup>
<CopyFileToFolders Include="cube.txt" />

View File

@ -162,6 +162,12 @@
<ClCompile Include="lightmapshaderclass.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="watershaderclass.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="refractionshaderclass.cpp">
<Filter>Fichiers sources</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="systemclass.h">
@ -299,6 +305,12 @@
<ClInclude Include="Logger.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="watershaderclass.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="refractionshaderclass.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="wall.tga">
@ -313,9 +325,16 @@
<Image Include="KhaoticIcon.ico">
<Filter>Assets</Filter>
</Image>
<Image Include="water01.tga">
<Filter>Assets</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="water.vs" />
<None Include="..\KhaoticDemo\water.ps" />
<None Include="refraction.vs" />
<None Include="refraction.ps" />
</ItemGroup>
<ItemGroup>
<Text Include="sphere.txt">

10
enginecustom/ground.txt Normal file
View File

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

BIN
enginecustom/ground01.tga Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

View File

@ -75,13 +75,13 @@ void LightShaderClass::Shutdown()
}
bool LightShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[])
ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[], XMFLOAT4 ambientClor[])
{
bool result;
// Set the shader parameters that it will use for rendering.
result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, diffuseColor, lightPosition);
result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, diffuseColor, lightPosition, ambientClor);
if(!result)
{
Logger::Get().Log("Failed to set shader parameters", __FILE__, __LINE__, Logger::LogLevel::Error);
@ -418,7 +418,7 @@ void LightShaderClass::OutputShaderErrorMessage(ID3D10Blob* errorMessage, HWND h
bool LightShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[])
ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[], XMFLOAT4 ambientColor[])
{
HRESULT result;
D3D11_MAPPED_SUBRESOURCE mappedResource;

View File

@ -67,14 +67,14 @@ public:
bool Initialize(ID3D11Device*, HWND);
void Shutdown();
bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4[], XMFLOAT4[]);
bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4[], XMFLOAT4[], XMFLOAT4[]);
private:
bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*);
void ShutdownShader();
void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*);
bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4[], XMFLOAT4[]);
bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4[], XMFLOAT4[], XMFLOAT4[]);
void RenderShader(ID3D11DeviceContext*, int);
private:

View File

@ -0,0 +1 @@
#pragma once

BIN
enginecustom/marble01.tga Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

View File

@ -0,0 +1,63 @@
/////////////
// GLOBALS //
/////////////
SamplerState SampleType : register(s0);
Texture2D shaderTexture : register(t0);
cbuffer LightBuffer
{
float4 ambientColor;
float4 diffuseColor;
float3 lightDirection;
};
//////////////
// TYPEDEFS //
//////////////
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
float3 normal : NORMAL;
float clip : SV_ClipDistance0;
};
////////////////////////////////////////////////////////////////////////////////
// Pixel Shader
////////////////////////////////////////////////////////////////////////////////
float4 RefractionPixelShader(PixelInputType input) : SV_TARGET
{
float4 textureColor;
float3 lightDir;
float lightIntensity;
float4 color;
// Sample the texture pixel at this location.
textureColor = shaderTexture.Sample(SampleType, input.tex);
// Set the default output color to the ambient light value for all pixels.
color = ambientColor;
// Invert the light direction for calculations.
lightDir = -lightDirection;
// Calculate the amount of light on this pixel.
lightIntensity = saturate(dot(input.normal, lightDir));
if(lightIntensity > 0.0f)
{
// Determine the final diffuse color based on the diffuse color and the amount of light intensity.
color += (diffuseColor * lightIntensity);
}
// Saturate the final light color.
color = saturate(color);
// Multiply the texture pixel and the input color to get the final result.
color = color * textureColor;
return color;
}

View File

@ -0,0 +1,65 @@
/////////////
// GLOBALS //
/////////////
cbuffer MatrixBuffer
{
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
};
cbuffer ClipPlaneBuffer
{
float4 clipPlane;
};
//////////////
// TYPEDEFS //
//////////////
struct VertexInputType
{
float4 position : POSITION;
float2 tex : TEXCOORD0;
float3 normal : NORMAL;
};
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
float3 normal : NORMAL;
float clip : SV_ClipDistance0;
};
////////////////////////////////////////////////////////////////////////////////
// Vertex Shader
////////////////////////////////////////////////////////////////////////////////
PixelInputType RefractionVertexShader(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.
output.normal = mul(input.normal, (float3x3)worldMatrix);
// Normalize the normal vector.
output.normal = normalize(output.normal);
// Set the clipping plane.
output.clip = dot(mul(input.position, worldMatrix), clipPlane);
return output;
}

View File

@ -0,0 +1,473 @@
#include "refractionshaderclass.h"
RefractionShaderClass::RefractionShaderClass()
{
m_vertexShader = 0;
m_pixelShader = 0;
m_layout = 0;
m_matrixBuffer = 0;
m_sampleState = 0;
m_lightBuffer = 0;
m_clipPlaneBuffer = 0;
}
RefractionShaderClass::RefractionShaderClass(const RefractionShaderClass& other)
{
}
RefractionShaderClass::~RefractionShaderClass()
{
}
bool RefractionShaderClass::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"refraction.vs");
if (error != 0)
{
return false;
}
// Set the filename of the pixel shader.
error = wcscpy_s(psFilename, 128, L"refraction.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 RefractionShaderClass::Shutdown()
{
// Shutdown the vertex and pixel shaders as well as the related objects.
ShutdownShader();
return;
}
bool RefractionShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 ambientColor[], XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[], XMFLOAT4 clipPlane)
{
bool result;
// Set the shader parameters that it will use for rendering.
result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, lightDirection, ambientColor, diffuseColor, lightPosition, clipPlane);
if (!result)
{
return false;
}
// Now render the prepared buffers with the shader.
RenderShader(deviceContext, indexCount);
return true;
}
bool RefractionShaderClass::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;
D3D11_BUFFER_DESC lightBufferDesc;
D3D11_BUFFER_DESC clipPlaneBufferDesc;
// 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, "RefractionVertexShader", "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, "RefractionPixelShader", "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_CLAMP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
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.
// Note that ByteWidth always needs to be a multiple of 16 if using D3D11_BIND_CONSTANT_BUFFER or CreateBuffer will fail.
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 clip plane dynamic constant buffer that is in the vertex shader.
clipPlaneBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
clipPlaneBufferDesc.ByteWidth = sizeof(ClipPlaneBufferType);
clipPlaneBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
clipPlaneBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
clipPlaneBufferDesc.MiscFlags = 0;
clipPlaneBufferDesc.StructureByteStride = 0;
// Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class.
result = device->CreateBuffer(&clipPlaneBufferDesc, NULL, &m_clipPlaneBuffer);
if (FAILED(result))
{
return false;
}
return true;
}
void RefractionShaderClass::ShutdownShader()
{
// Release the clip plane constant buffer.
if (m_clipPlaneBuffer)
{
m_clipPlaneBuffer->Release();
m_clipPlaneBuffer = 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 RefractionShaderClass::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 RefractionShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 ambientColor[], XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[], XMFLOAT4 clipPlane)
{
HRESULT result;
D3D11_MAPPED_SUBRESOURCE mappedResource;
MatrixBufferType* dataPtr;
unsigned int bufferNumber;
ClipPlaneBufferType* dataPtr2;
LightBufferType* 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);
// Lock the clip plane constant buffer so it can be written to.
result = deviceContext->Map(m_clipPlaneBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if(FAILED(result))
{
return false;
}
// Get a pointer to the data in the clip plane constant buffer.
dataPtr2 = (ClipPlaneBufferType*)mappedResource.pData;
// Copy the clip plane into the clip plane constant buffer.
dataPtr2->clipPlane = clipPlane;
// Unlock the buffer.
deviceContext->Unmap(m_clipPlaneBuffer, 0);
// Set the position of the clip plane constant buffer in the vertex shader.
bufferNumber = 1;
// Now set the clip plane constant buffer in the vertex shader with the updated values.
deviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_clipPlaneBuffer);
// Set shader texture resource in the pixel shader.
deviceContext->PSSetShaderResources(0, 1, &texture);
// 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.
dataPtr3 = (LightBufferType*)mappedResource.pData;
// Copy the lighting variables into the constant buffer.
dataPtr3->ambientColor = ambientColor[0];
dataPtr3->diffuseColor = diffuseColor[0];
dataPtr3->lightPosition = lightPosition[0];
dataPtr3->lightDirection = lightDirection;
// 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 RefractionShaderClass::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 the geometry.
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,72 @@
#ifndef _REFRACTIONSHADERCLASS_H_
#define _REFRACTIONSHADERCLASS_H_
//////////////
// INCLUDES //
//////////////
#include <d3d11.h>
#include <d3dcompiler.h>
#include <directxmath.h>
#include <fstream>
using namespace DirectX;
using namespace std;
////////////////////////////////////////////////////////////////////////////////
// Class name: RefractionShaderClass
////////////////////////////////////////////////////////////////////////////////
class RefractionShaderClass
{
private:
struct MatrixBufferType
{
XMMATRIX world;
XMMATRIX view;
XMMATRIX projection;
};
struct LightBufferType
{
XMFLOAT4 ambientColor;
XMFLOAT4 diffuseColor;
XMFLOAT4 lightPosition;
XMFLOAT3 lightDirection;
float padding;
};
struct ClipPlaneBufferType
{
XMFLOAT4 clipPlane;
};
public:
RefractionShaderClass();
RefractionShaderClass(const RefractionShaderClass&);
~RefractionShaderClass();
bool Initialize(ID3D11Device*, HWND);
void Shutdown();
bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*,
XMFLOAT3, XMFLOAT4[], XMFLOAT4[], XMFLOAT4[], XMFLOAT4);
private:
bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*);
void ShutdownShader();
void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*);
bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*,
XMFLOAT3, XMFLOAT4[], XMFLOAT4[], XMFLOAT4[], XMFLOAT4);
void RenderShader(ID3D11DeviceContext*, int);
private:
ID3D11VertexShader* m_vertexShader;
ID3D11PixelShader* m_pixelShader;
ID3D11InputLayout* m_layout;
ID3D11SamplerState* m_sampleState;
ID3D11Buffer* m_matrixBuffer;
ID3D11Buffer* m_lightBuffer;
ID3D11Buffer* m_clipPlaneBuffer;
};
#endif

View File

@ -11,6 +11,8 @@ ShaderManagerClass::ShaderManagerClass()
m_TransparentShader = 0;
m_LightShader = 0;
m_LightMapShader = 0;
m_RefractionShader = 0;
m_WaterShader = 0;
}
@ -120,6 +122,24 @@ bool ShaderManagerClass::Initialize(ID3D11Device* device, HWND hwnd)
return false;
}
// Create and initialize the refraction shader object.
m_RefractionShader = new RefractionShaderClass;
result = m_RefractionShader->Initialize(device, hwnd);
if (!result)
{
return false;
}
// Create and initialize the water shader object.
m_WaterShader = new WaterShaderClass;
result = m_WaterShader->Initialize(device, hwnd);
if (!result)
{
return false;
}
Logger::Get().Log("ShaderManagerClass initialized", __FILE__, __LINE__, Logger::LogLevel::Initialize);
return true;
@ -201,6 +221,22 @@ void ShaderManagerClass::Shutdown()
m_LightMapShader = 0;
}
// Release the refraction shader object.
if (m_RefractionShader)
{
m_RefractionShader->Shutdown();
delete m_RefractionShader;
m_RefractionShader = 0;
}
// Release the water shader object.
if (m_WaterShader)
{
m_WaterShader->Shutdown();
delete m_WaterShader;
m_WaterShader = 0;
}
Logger::Get().Log("ShaderManagerClass shut down", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
return;
@ -322,12 +358,12 @@ bool ShaderManagerClass::RenderTransparentShader(ID3D11DeviceContext* deviceCont
}
bool ShaderManagerClass::RenderlightShader(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[])
ID3D11ShaderResourceView* texture, XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[], XMFLOAT4 ambientColor[])
{
bool result;
result = m_LightShader->Render(deviceContext, indexCount, worldMatrix, viewMatrix, projectionMatrix, texture, diffuseColor, lightPosition);
result = m_LightShader->Render(deviceContext, indexCount, worldMatrix, viewMatrix, projectionMatrix, texture, diffuseColor, lightPosition, ambientColor);
if (!result)
{
return false;
@ -348,5 +384,37 @@ bool ShaderManagerClass::RenderlightMapShader(ID3D11DeviceContext* deviceContext
return false;
}
return true;
}
bool ShaderManagerClass::RenderRefractionShader(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
ID3D11ShaderResourceView* texture, XMFLOAT3 lightDirection, XMFLOAT4 ambientColor[], XMFLOAT4 diffuseColor[], XMFLOAT4 lightPosition[], XMFLOAT4 clipPlane)
{
bool result;
result = m_RefractionShader->Render(deviceContext, indexCount, worldMatrix, viewMatrix, projectionMatrix, texture, lightDirection, ambientColor, diffuseColor, lightPosition, clipPlane);
if (!result)
{
return false;
}
return true;
}
bool ShaderManagerClass::RenderWaterShader(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
XMMATRIX reflectionMatrix, ID3D11ShaderResourceView* reflectionTexture, ID3D11ShaderResourceView* refractionTexture,
ID3D11ShaderResourceView* normalTexture, float waterTranslation, float reflectRefractScale)
{
bool result;
result = m_WaterShader->Render(deviceContext, indexCount, worldMatrix, viewMatrix, projectionMatrix, reflectionMatrix, reflectionTexture,
refractionTexture, normalTexture, waterTranslation, reflectRefractScale);
if (!result)
{
return false;
}
return true;
}

View File

@ -13,6 +13,10 @@
#include "transparentshaderclass.h"
#include "lightshaderclass.h"
#include "lightmapshaderclass.h"
#include "refractionshaderclass.h"
#include "watershaderclass.h"
////////////////////////////////////////////////////////////////////////////////
// Class name: ShaderManagerClass
////////////////////////////////////////////////////////////////////////////////
@ -33,9 +37,12 @@ public:
bool RenderSpecMapShader(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*,
XMFLOAT3, XMFLOAT4, XMFLOAT3, XMFLOAT4, float);
bool RenderTransparentShader(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, float);
bool RenderlightShader(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4[], XMFLOAT4[]);
bool RenderlightShader(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT4[], XMFLOAT4[], XMFLOAT4[]);
bool RenderlightMapShader(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*);
bool RenderRefractionShader(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*,
XMFLOAT3, XMFLOAT4[], XMFLOAT4[], XMFLOAT4[], XMFLOAT4);
bool RenderWaterShader(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*,
ID3D11ShaderResourceView*, ID3D11ShaderResourceView*, float, float);
private:
TextureShaderClass* m_TextureShader;
NormalMapShaderClass* m_NormalMapShader;
@ -47,6 +54,8 @@ private:
LightShaderClass* m_LightShader;
LightMapShaderClass* m_LightMapShader;
RefractionShaderClass* m_RefractionShader;
WaterShaderClass* m_WaterShader;
};
#endif

40
enginecustom/wall.txt Normal file
View File

@ -0,0 +1,40 @@
Vertex Count: 36
Data:
-5 5 -0.5 0.001992 0.00199199 0 0 -1
5 -5 -0.5 0.998008 0.998008 0 0 -1
-5 -5 -0.5 0.001992 0.998008 0 0 -1
5 5 -0.5 0.998008 0.00199199 0 0 -1
5 -5 -0.5 0.998008 0.998008 0 0 -1
-5 5 -0.5 0.001992 0.00199199 0 0 -1
-5 5 0.5 0.099801 0.00199199 0 1 -0
5 5 -0.5 0.000199 0.998008 0 1 -0
-5 5 -0.5 0.000199 0.00199199 0 1 -0
5 5 0.5 0.099801 0.998008 0 1 -0
5 5 -0.5 0.000199 0.998008 0 1 -0
-5 5 0.5 0.099801 0.00199199 0 1 -0
-5 -5 0.5 0.001992 0.00199199 0 0 1
5 5 0.5 0.998008 0.998008 0 0 1
-5 5 0.5 0.001992 0.998008 0 0 1
5 -5 0.5 0.998008 0.00199199 0 0 1
5 5 0.5 0.998008 0.998008 0 0 1
-5 -5 0.5 0.001992 0.00199199 0 0 1
-5 -5 -0.5 0.099801 0.00199199 0 -1 -0
5 -5 0.5 0.000199 0.998008 0 -1 -0
-5 -5 0.5 0.000199 0.00199199 0 -1 -0
5 -5 -0.5 0.099801 0.998008 0 -1 -0
5 -5 0.5 0.000199 0.998008 0 -1 -0
-5 -5 -0.5 0.099801 0.00199199 0 -1 -0
5 5 -0.5 0.000199 0.00199199 1 0 -0
5 -5 0.5 0.099801 0.998008 1 0 -0
5 -5 -0.5 0.000199 0.998008 1 0 -0
5 5 0.5 0.099801 0.00199199 1 0 -0
5 -5 0.5 0.099801 0.998008 1 0 -0
5 5 -0.5 0.000199 0.00199199 1 0 -0
-5 5 0.5 0.000199 0.00199199 -1 0 -0
-5 -5 -0.5 0.099801 0.998008 -1 0 -0
-5 -5 0.5 0.000199 0.998008 -1 0 -0
-5 5 -0.5 0.099801 0.00199199 -1 0 -0
-5 -5 -0.5 0.099801 0.998008 -1 0 -0
-5 5 0.5 0.000199 0.00199199 -1 0 -0

BIN
enginecustom/wall01.tga Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

72
enginecustom/water.ps Normal file
View File

@ -0,0 +1,72 @@
/////////////
// GLOBALS //
/////////////
SamplerState SampleType : register(s0);
Texture2D reflectionTexture : register(t0);
Texture2D refractionTexture : register(t1);
Texture2D normalTexture : register(t2);
cbuffer WaterBuffer
{
float waterTranslation;
float reflectRefractScale;
float2 padding;
};
//////////////
// TYPEDEFS //
//////////////
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
float4 reflectionPosition : TEXCOORD1;
float4 refractionPosition : TEXCOORD2;
};
////////////////////////////////////////////////////////////////////////////////
// Pixel Shader
////////////////////////////////////////////////////////////////////////////////
float4 WaterPixelShader(PixelInputType input) : SV_TARGET
{
float2 reflectTexCoord;
float2 refractTexCoord;
float4 normalMap;
float3 normal;
float4 reflectionColor;
float4 refractionColor;
float4 color;
// Move the position the water normal is sampled from to simulate moving water.
input.tex.y += waterTranslation;
// Calculate the projected reflection texture coordinates.
reflectTexCoord.x = input.reflectionPosition.x / input.reflectionPosition.w / 2.0f + 0.5f;
reflectTexCoord.y = -input.reflectionPosition.y / input.reflectionPosition.w / 2.0f + 0.5f;
// Calculate the projected refraction texture coordinates.
refractTexCoord.x = input.refractionPosition.x / input.refractionPosition.w / 2.0f + 0.5f;
refractTexCoord.y = -input.refractionPosition.y / input.refractionPosition.w / 2.0f + 0.5f;
// Sample the normal from the normal map texture.
normalMap = normalTexture.Sample(SampleType, input.tex);
// Expand the range of the normal from (0,1) to (-1,+1).
normal = (normalMap.xyz * 2.0f) - 1.0f;
// Re-position the texture coordinate sampling position by the normal map value to simulate the rippling wave effect.
reflectTexCoord = reflectTexCoord + (normal.xy * reflectRefractScale);
refractTexCoord = refractTexCoord + (normal.xy * reflectRefractScale);
// Sample the texture pixels from the textures using the updated texture coordinates.
reflectionColor = reflectionTexture.Sample(SampleType, reflectTexCoord);
refractionColor = refractionTexture.Sample(SampleType, refractTexCoord);
// Combine the reflection and refraction results for the final color.
color = lerp(reflectionColor, refractionColor, 0.6f);
return color;
}

10
enginecustom/water.txt Normal file
View File

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

71
enginecustom/water.vs Normal file
View File

@ -0,0 +1,71 @@
/////////////
// GLOBALS //
/////////////
cbuffer MatrixBuffer
{
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
};
cbuffer ReflectionBuffer
{
matrix reflectionMatrix;
};
//////////////
// TYPEDEFS //
//////////////
struct VertexInputType
{
float4 position : POSITION;
float2 tex : TEXCOORD0;
};
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
float4 reflectionPosition : TEXCOORD1;
float4 refractionPosition : TEXCOORD2;
};
////////////////////////////////////////////////////////////////////////////////
// Vertex Shader
////////////////////////////////////////////////////////////////////////////////
PixelInputType WaterVertexShader(VertexInputType input)
{
PixelInputType output;
matrix reflectProjectWorld;
matrix viewProjectWorld;
// 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;
// Create the reflection projection world matrix.
reflectProjectWorld = mul(reflectionMatrix, projectionMatrix);
reflectProjectWorld = mul(worldMatrix, reflectProjectWorld);
// Calculate the input position against the reflectProjectWorld matrix.
output.reflectionPosition = mul(input.position, reflectProjectWorld);
// Create the view projection world matrix for refraction.
viewProjectWorld = mul(viewMatrix, projectionMatrix);
viewProjectWorld = mul(worldMatrix, viewProjectWorld);
// Calculate the input position against the viewProjectWorld matrix.
output.refractionPosition = mul(input.position, viewProjectWorld);
return output;
}

BIN
enginecustom/water01.tga Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

View File

@ -0,0 +1,470 @@
#include "watershaderclass.h"
WaterShaderClass::WaterShaderClass()
{
m_vertexShader = 0;
m_pixelShader = 0;
m_layout = 0;
m_sampleState = 0;
m_matrixBuffer = 0;
m_reflectionBuffer = 0;
m_waterBuffer = 0;
}
WaterShaderClass::WaterShaderClass(const WaterShaderClass& other)
{
}
WaterShaderClass::~WaterShaderClass()
{
}
bool WaterShaderClass::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"water.vs");
if (error != 0)
{
return false;
}
// Set the filename of the pixel shader.
error = wcscpy_s(psFilename, 128, L"water.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 WaterShaderClass::Shutdown()
{
// Shutdown the vertex and pixel shaders as well as the related objects.
ShutdownShader();
return;
}
bool WaterShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix,
XMMATRIX reflectionMatrix, ID3D11ShaderResourceView* reflectionTexture, ID3D11ShaderResourceView* refractionTexture,
ID3D11ShaderResourceView* normalTexture, float waterTranslation, float reflectRefractScale)
{
bool result;
// Set the shader parameters that it will use for rendering.
result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, reflectionMatrix, reflectionTexture,
refractionTexture, normalTexture, waterTranslation, reflectRefractScale);
if (!result)
{
return false;
}
// Now render the prepared buffers with the shader.
RenderShader(deviceContext, indexCount);
return true;
}
bool WaterShaderClass::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 reflectionBufferDesc;
D3D11_BUFFER_DESC waterBufferDesc;
// 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, "WaterVertexShader", "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, "WaterPixelShader", "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 reflection dynamic constant buffer that is in the vertex shader.
reflectionBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
reflectionBufferDesc.ByteWidth = sizeof(ReflectionBufferType);
reflectionBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
reflectionBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
reflectionBufferDesc.MiscFlags = 0;
reflectionBufferDesc.StructureByteStride = 0;
// Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class.
result = device->CreateBuffer(&reflectionBufferDesc, NULL, &m_reflectionBuffer);
if (FAILED(result))
{
return false;
}
// Setup the description of the water dynamic constant buffer that is in the pixel shader.
waterBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
waterBufferDesc.ByteWidth = sizeof(WaterBufferType);
waterBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
waterBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
waterBufferDesc.MiscFlags = 0;
waterBufferDesc.StructureByteStride = 0;
// Create the constant buffer pointer so we can access the pixel shader constant buffer from within this class.
result = device->CreateBuffer(&waterBufferDesc, NULL, &m_waterBuffer);
if (FAILED(result))
{
return false;
}
return true;
}
void WaterShaderClass::ShutdownShader()
{
// Release the water constant buffer.
if (m_waterBuffer)
{
m_waterBuffer->Release();
m_waterBuffer = 0;
}
// Release the reflection constant buffer.
if (m_reflectionBuffer)
{
m_reflectionBuffer->Release();
m_reflectionBuffer = 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 WaterShaderClass::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 WaterShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, XMMATRIX projectionMatrix, XMMATRIX reflectionMatrix,
ID3D11ShaderResourceView* reflectionTexture, ID3D11ShaderResourceView* refractionTexture, ID3D11ShaderResourceView* normalTexture,
float waterTranslation, float reflectRefractScale)
{
HRESULT result;
D3D11_MAPPED_SUBRESOURCE mappedResource;
MatrixBufferType* dataPtr;
unsigned int bufferNumber;
ReflectionBufferType* dataPtr2;
WaterBufferType* dataPtr3;
// Transpose the matrices to prepare them for the shader.
worldMatrix = XMMatrixTranspose(worldMatrix);
viewMatrix = XMMatrixTranspose(viewMatrix);
projectionMatrix = XMMatrixTranspose(projectionMatrix);
reflectionMatrix = XMMatrixTranspose(reflectionMatrix);
// 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;
// Finanly set the constant buffer in the vertex shader with the updated values.
deviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_matrixBuffer);
// Lock the reflection constant buffer so it can be written to.
result = deviceContext->Map(m_reflectionBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
return false;
}
// Get a pointer to the data in the constant buffer.
dataPtr2 = (ReflectionBufferType*)mappedResource.pData;
// Copy the reflection matrix into the constant buffer.
dataPtr2->reflection = reflectionMatrix;
// Unlock the constant buffer.
deviceContext->Unmap(m_reflectionBuffer, 0);
// Set the position of the reflection constant buffer in the vertex shader.
bufferNumber = 1;
// Finally set the reflection constant buffer in the vertex shader with the updated values.
deviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_reflectionBuffer);
// Set the reflection texture resource in the pixel shader.
deviceContext->PSSetShaderResources(0, 1, &reflectionTexture);
// Set the refraction texture resource in the pixel shader.
deviceContext->PSSetShaderResources(1, 1, &refractionTexture);
// Set the normal map texture resource in the pixel shader.
deviceContext->PSSetShaderResources(2, 1, &normalTexture);
// Lock the water constant buffer so it can be written to.
result = deviceContext->Map(m_waterBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
return false;
}
// Get a pointer to the data in the constant buffer.
dataPtr3 = (WaterBufferType*)mappedResource.pData;
// Copy the water data into the constant buffer.
dataPtr3->waterTranslation = waterTranslation;
dataPtr3->reflectRefractScale = reflectRefractScale;
dataPtr3->padding = XMFLOAT2(0.0f, 0.0f);
// Unlock the constant buffer.
deviceContext->Unmap(m_waterBuffer, 0);
// Set the position of the water constant buffer in the pixel shader.
bufferNumber = 0;
// Finally set the water constant buffer in the pixel shader with the updated values.
deviceContext->PSSetConstantBuffers(bufferNumber, 1, &m_waterBuffer);
return true;
}
void WaterShaderClass::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,70 @@
#ifndef _WATERSHADERCLASS_H_
#define _WATERSHADERCLASS_H_
//////////////
// INCLUDES //
//////////////
#include <d3d11.h>
#include <d3dcompiler.h>
#include <directxmath.h>
#include <fstream>
using namespace DirectX;
using namespace std;
////////////////////////////////////////////////////////////////////////////////
// Class name: WaterShaderClass
////////////////////////////////////////////////////////////////////////////////
class WaterShaderClass
{
private:
struct MatrixBufferType
{
XMMATRIX world;
XMMATRIX view;
XMMATRIX projection;
};
struct ReflectionBufferType
{
XMMATRIX reflection;
};
struct WaterBufferType
{
float waterTranslation;
float reflectRefractScale;
XMFLOAT2 padding;
};
public:
WaterShaderClass();
WaterShaderClass(const WaterShaderClass&);
~WaterShaderClass();
bool Initialize(ID3D11Device*, HWND);
void Shutdown();
bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*,
ID3D11ShaderResourceView*, ID3D11ShaderResourceView*, float, float);
private:
bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*);
void ShutdownShader();
void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*);
bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*,
ID3D11ShaderResourceView*, ID3D11ShaderResourceView*, float, float);
void RenderShader(ID3D11DeviceContext*, int);
private:
ID3D11VertexShader* m_vertexShader;
ID3D11PixelShader* m_pixelShader;
ID3D11InputLayout* m_layout;
ID3D11Buffer* m_matrixBuffer;
ID3D11SamplerState* m_sampleState;
ID3D11Buffer* m_reflectionBuffer;
ID3D11Buffer* m_waterBuffer;
};
#endif