建立了三个ConstantBuffer,一个是每一帧都需要从cpu传过来的用来旋转的world矩阵,一个是摄影机操作后传过来的view矩阵,还有一个是只传过来一次的projection矩阵和两个方向光的向量
1.lighting.fx
// Constant Buffer Variables
cbuffer CBChangesEveryFrame : register( b0 )
{
matrix World;
};
cbuffer CBChangesWhenMoving : register( b1 )
{
matrix View;
}
cbuffer CBNeverChange : register( b2 )
{
matrix Projection;
float4 vLightDir[2];
};
struct VS_INPUT
{
float4 Pos : POSITION;
float3 Norm : NORMAL;
};
struct PS_INPUT
{
float4 Pos : SV_POSITION;
float3 Norm : TEXCOORD0;
};
// 以上都是声明
// Vertex Shader
PS_INPUT VS( VS_INPUT input )
{
PS_INPUT output = (PS_INPUT)0;
output.Pos = mul( input.Pos, World );
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Norm = mul( float4(input.Norm, 1), World ).xyz;// .xyz指取前三位向量,等式左边的PS_INPUT中的Norm是float3型,而右边是float4型
// 也可写成output.Norm = mul( input.Norm, (float3x3)World );
return output;
}
// Pixel Shader
float4 PS( PS_INPUT input) : SV_Target
{
static float4 vLightColor = {1.0f, 1.0f, 1.0f, 1.0f};
float4 finalColor = 0;
float k = 0.85f;// 反射率
for(int i = 0; i < 2; i++)
{
finalColor += k * saturate(dot((float3)vLightDir[i], -input.Norm) * vLightColor);// 反射率 * saturate(dot(两光线向量·顶点法线向量)·颜色值),saturate表示饱和处理——大于1变为1,小于0变成0
}
finalColor.a = 1;// 同finalColor.w = 1; rgba对应xyzw
return finalColor;
}
2.winmain.cpp
#include <windows.h>
#include <d3d11_1.h>
#include <d3dcompiler.h>
#include <directxmath.h>
#include <directxcolors.h>
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
// 找到项目的属性->链接器->输入->附加依赖项,在%(AdditionalDependencies)前追加上以下项:
// d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;
// 或者像下面这样添加代码:
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dcompiler.lib")
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "comctl32.lib")
using namespace DirectX;
struct VertexNormal
{
XMFLOAT3 Pos;
XMFLOAT3 Normal;
};
struct CBChangesEveryFrame
{
XMMATRIX mWorld;
};
struct CBChangesWhenMoving
{
XMMATRIX mView;
};
struct CBNeverChanges
{
XMMATRIX mProjection;
XMFLOAT4 vLightDir[2];
};
struct Camera
{
Camera()
: vAxisX(XMVectorSet(1.0f, 0.0f, 0.0f, 1.0f))
, vAxisAim(XMVectorSet(1.0f, 0.0f, 0.0f, 1.0f))
, vAxisY(XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f))
, vAxisZ(XMVectorSet(0.0f, 0.0f, 1.0f, 1.0f))
, vPosition(XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f))
{}
Camera(const XMVECTOR & xAxis, const XMVECTOR & yAxis, const XMVECTOR & zAxis, const XMVECTOR & pos)
: vAxisX(XMVector3Normalize(xAxis))
, vAxisAim(XMVector3Normalize(xAxis))
, vAxisY(XMVector3Normalize(yAxis))
, vAxisZ(XMVector3Normalize(zAxis))
, vPosition(pos)
{}
// 前后平移
void XMove(float dx)
{
XMMATRIX move = XMMatrixTranslationFromVector(dx * vAxisX);
vPosition = XMVector3TransformCoord(vPosition, move);
}
// 左右平移
void YMove(float dy)
{
XMMATRIX move = XMMatrixTranslationFromVector(dy * vAxisY);
vPosition = XMVector3TransformCoord(vPosition, move);
}
// 上下平移
void ZMove(float dz)
{
XMMATRIX move = XMMatrixTranslationFromVector(dz * vAxisZ);
vPosition = XMVector3TransformCoord(vPosition, move);
}
void ZSpin(float angle)
{
XMMATRIX mspin = XMMatrixRotationAxis(vAxisZ, angle);
vAxisX = XMVector3Transform(vAxisX, mspin);
vAxisAim = XMVector3Transform(vAxisAim, mspin);
vAxisY = XMVector3Transform(vAxisY, mspin);
}
void YSpin(float angle)
{
XMMATRIX mspin = XMMatrixRotationAxis(vAxisY, angle);
vAxisAim = XMVector3Transform(vAxisAim, mspin);
}
void ZoomIn(float in)
{
XMMATRIX move = XMMatrixTranslationFromVector(in * vAxisAim);
vPosition = XMVector4Transform(vPosition, move);
}
XMVECTOR vEye() const {return vPosition;}
XMVECTOR vUp() const {return XMVector4Transform(vAxisAim, XMMatrixRotationAxis(vAxisY, -XM_PIDIV2));}
XMVECTOR vFocus() const {return vPosition + vAxisAim;}
XMVECTOR vPosition;// 摄像机位矢
XMVECTOR vAxisAim;// 瞄准轴(可以在摄像机vAxisX-vAxisZ平面内上下转动)
XMVECTOR vAxisX;// 摄像机前后移动轴单位向量
XMVECTOR vAxisY;// 摄像机左右移动轴单位向量
XMVECTOR vAxisZ;// 摄像机上下移动轴单位向量
};
HINSTANCE g_hInst = nullptr;
HWND g_hWnd = nullptr;
D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL;
D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;
ID3D11Device* g_pd3dDevice = nullptr;
ID3D11Device1* g_pd3dDevice1 = nullptr;
ID3D11DeviceContext* g_pImmediateContext = nullptr;
ID3D11DeviceContext1* g_pImmediateContext1 = nullptr;
IDXGISwapChain* g_pSwapChain = nullptr;
IDXGISwapChain1* g_pSwapChain1 = nullptr;
ID3D11RenderTargetView* g_pRenderTargetView = nullptr;
ID3D11Texture2D* g_pDepthStencil = nullptr;
ID3D11DepthStencilView* g_pDepthStencilView = nullptr;
ID3D11VertexShader* g_pVertexShader = nullptr;
ID3D11PixelShader* g_pPixelShader =