//Code for sampler creation
D3D11_SAMPLER_DESC SamDesc;
ZeroMemory(&SamDesc, sizeof(D3D11_SAMPLER_DESC));
SamDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
SamDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
SamDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
SamDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
SamDesc.MipLODBias = 0.0f;
SamDesc.MaxAnisotropy = 1;
SamDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
SamDesc.BorderColor[0] = SamDesc.BorderColor[1] = SamDesc.BorderColor[2] = SamDesc.BorderColor[3] = 0;
SamDesc.MinLOD = 0;
SamDesc.MaxLOD = D3D11_FLOAT32_MAX;
//Code for texture loading
D3DX11_IMAGE_LOAD_INFO imageInfo;
imageInfo.Width = D3DX11_DEFAULT;
imageInfo.Height = D3DX11_DEFAULT;
imageInfo.Depth = D3DX11_DEFAULT;
imageInfo.FirstMipLevel = D3DX11_DEFAULT;
imageInfo.MipLevels = D3DX11_DEFAULT;
imageInfo.Usage = D3D11_USAGE_DEFAULT;
imageInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE;
imageInfo.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
imageInfo.MipFilter = D3DX11_FILTER_LINEAR;
imageInfo.Filter = D3DX11_FILTER_LINEAR;
D3DX11CreateShaderResourceViewFromFile(..)
//Code window creation
RECT rc = { 0, 0, 1600, 960 };
AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
hWnd = CreateWindow(L"myclass", L"myapp", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL);
if (!hWnd)
return FALSE;
g_WindowHWND = hWnd;
ShowWindow(g_WindowHWND, nCmdShow);
//Code buffer creation after window is created
m_hWndMainRenderTarget = hwnd;
// Create a Direct2D render target
RECT rcRenderTarget;
GetClientRect( hwnd, &rcRenderTarget);
m_uiRenderTargetWidth = rcRenderTarget.right-rcRenderTarget.left;
m_uiRenderTargetHeight = rcRenderTarget.bottom-rcRenderTarget.top;
// Create swapchain settings
DXGI_SWAP_CHAIN_DESC sSwapChainDesc;
ZeroMemory( &sSwapChainDesc, sizeof( sSwapChainDesc ) );
sSwapChainDesc.BufferCount = 1;
sSwapChainDesc.BufferDesc.Width = m_uiRenderTargetWidth;
sSwapChainDesc.BufferDesc.Height = m_uiRenderTargetHeight;
sSwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sSwapChainDesc.OutputWindow = m_hWndMainRenderTarget;
sSwapChainDesc.SampleDesc.Count = 1;
sSwapChainDesc.SampleDesc.Quality = 0;
sSwapChainDesc.Windowed = m_bWindowed;
sSwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
// Retrive device, adapter and factory that was created with the device
IDXGIDevice * pDXGIDevice;
hr = m_pDevice->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice);
IDXGIAdapter * pDXGIAdapter;
hr = pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter);
IDXGIFactory * pIDXGIFactory;
pDXGIAdapter->GetParent(__uuidof(IDXGIFactory), (void **)&pIDXGIFactory);
// Create swap chain seperate
if(FAILED( hr = pIDXGIFactory->CreateSwapChain( pDXGIDevice, &sSwapChainDesc, &m_pSwapChain ) ))
{
return hr;
}
// Get a pointer to the back buffer
if(FAILED( hr = m_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&m_pBackBuffer )))
{
return hr;
}
// Create a render-target view
if(FAILED( hr = m_pDevice->CreateRenderTargetView( m_pBackBuffer, NULL, &m_pRenderTargetView )))
{
return hr;
}
D3D11_TEXTURE2D_DESC sDepthStencilTextureDesc;
// Create depth stencil texture etc..
sDepthStencilTextureDesc.Width = m_uiRenderTargetWidth;
sDepthStencilTextureDesc.Height = m_uiRenderTargetHeight;
sDepthStencilTextureDesc.MipLevels = 1;
sDepthStencilTextureDesc.ArraySize = 1;
sDepthStencilTextureDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
sDepthStencilTextureDesc.SampleDesc.Count = 1;
sDepthStencilTextureDesc.SampleDesc.Quality = 0;
sDepthStencilTextureDesc.Usage = D3D11_USAGE_DEFAULT;
sDepthStencilTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
sDepthStencilTextureDesc.CPUAccessFlags = 0;
sDepthStencilTextureDesc.MiscFlags = 0;
if(FAILED( hr = m_pDevice->CreateTexture2D( &sDepthStencilTextureDesc, NULL, &m_pDepthStencilTexture )))
{
return hr;
}
D3D11_DEPTH_STENCIL_VIEW_DESC sDepthStencilViewDesc;
// Depth stencil view desc...
ZeroMemory( &sDepthStencilViewDesc, sizeof( sDepthStencilViewDesc ) );
sDepthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
sDepthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
sDepthStencilViewDesc.Texture2D.MipSlice = 0;
sDepthStencilViewDesc.Flags = 0;
if(FAILED( hr = m_pDevice->CreateDepthStencilView( m_pDepthStencilTexture, &sDepthStencilViewDesc,&m_pDepthStencilView )))
{
return hr;
}
// Bind the view
m_pDeviceContext->OMSetRenderTargets( 1, &m_pRenderTargetView, m_pDepthStencilView );
D3D11_VIEWPORT sViewPort;
// Setup the viewport
sViewPort.Width = (FLOAT)m_uiRenderTargetWidth;
sViewPort.Height = (FLOAT)m_uiRenderTargetHeight;
sViewPort.MinDepth = 0.0f;
sViewPort.MaxDepth = 1.0f;
sViewPort.TopLeftX = 0;
sViewPort.TopLeftY = 0;
m_pDeviceContext->RSSetViewports( 1, &sViewPort );
//Code projection matrx creation. zNear = 1.0f and zFar = 12000.0f
int width = g_CDevice.GetRenderTargetWidth();
int height = g_CDevice.GetRenderTargetHeight();
float fov = 0.785398163f;
float aspectRatio = width / (float)height;
D3DXMatrixPerspectiveFovLH(&g_mProjection, fov, aspectRatio, g_fZNear, g_fZFar);
//Code pixelshader
Texture2D txColorMap_1 : register( t0 ); // grass
Texture2D txColorMap_2 : register( t1 ); // dirt
Texture2D txColorMap_3 : register( t2 ); // rock
Texture2D txColorMap_4 : register( t3 ); // rgba random blend map
Texture2D txColorMap_5 : register( t4 ); // noisy normal map
// Texture sampler - D3D11_FILTER_MIN_MAG_MIP_LINEAR / ADRESS: D3D11_TEXTURE_ADDRESS_WRAP
SamplerState samLinear2D_1 : register( s0 );
struct PixelInputType
{
float4 position : SV_POSITION;
float3 normal : TEXCOORD0;
float2 tex_1 : TEXCOORD1; // uv for detail
float2 tex_2 : TEXCOORD2; // uv for noise map
};
float4 PSMain(PixelInputType input) : SV_Target
{
const float uvDetail = 32.0f; // detail uv in the range of 0.125f - 0.25f
const float4 vLightDir = float4(-0.5f, 1.0f, 1.0f, 1.0f); // Directional light for testing
const float4 vLightColor = float4(0.8f, 0.8f, 0.8f, 1.0f);
const float4 vAmbientColor = float4(0.2f, 0.2f, 0.2f, 1.0f);
float4 finalColor;
float blendAmount;
float4 t_1 = txColorMap_4.Sample( samLinear2D_1, input.tex_2 * 0.125f);// random map blend values
float4 col;
// Read detail texture
float4 c1 = txColorMap_1.Sample( samLinear2D_1, input.tex_1 * uvDetail);
float4 c2 = txColorMap_2.Sample( samLinear2D_1, input.tex_1 * uvDetail);
float4 c3 = txColorMap_3.Sample( samLinear2D_1, input.tex_1 * uvDetail);
// Read detail texture with lower uv values for mixing
float4 c4 = txColorMap_1.Sample( samLinear2D_1, input.tex_1 * uvDetail * 0.25f);
float4 c5 = txColorMap_2.Sample( samLinear2D_1, input.tex_1 * uvDetail * 0.125f);
float4 c6 = txColorMap_3.Sample( samLinear2D_1, input.tex_1 * uvDetail * 0.125f);
// lerp the values with the blend values of the
c1 = lerp(c1*c4, c2, t_1.r);
c2 = lerp(c2*c5, c3, t_1.g);
c3 = lerp(c3,c6, t_1.b);
// Slope calculation based on rastertek tutorial
float slope = 1.0f - input.normal.y;
if(slope < 0.2)
{
blendAmount = slope / 0.2f;
col = lerp(c1, c2, blendAmount);
}
if((slope < 0.7) && (slope >= 0.2f))
{
blendAmount = (slope - 0.2f) * (1.0f / (0.7f - 0.2f));
col = lerp(c2, c3, blendAmount);
}
if(slope >= 0.7)
{
col = c3;
}
// add normal map noise values for some cheap bump effect
float3 n1 = txColorMap_5.Sample(samLinear2D_1, input.tex_1 * uvDetail);
float3 n2 = txColorMap_5.Sample(samLinear2D_1, input.tex_1 * uvDetail * 0.25f);
n1 = lerp(n1, n2, t_1.r);
float d = dot((float3)vLightDir,n1);
col *= d;
// calculate directional lighting
finalColor = saturate( dot( (float3)vLightDir,input.normal) * vLightColor) * col;
finalColor += col * vAmbientColor;
return finalColor;
}