1、创建一个Win32项目(现在叫Windows桌面向导),命名为“D3DTriangle”。
2、创建一个h文件,命名为“d3dUtility.h”。在创建两个cpp文件,分别命名为“d3dTriangle.cpp”和“d3dUtility.cpp”。
3、创建hlsl文件
右键项目新建筛选器,在筛选器里面新建“HLSL”文件,如果没有看见这个选项随便选择一个文件类型创建,只要在后面加上.hlsl后缀。然后把hlsl文件设置为不参与生成。
4、复制第一个案例的d3dUtility.cpp和d3dUtility.h到本项目。
5、编写创建的Triangle.hlsl文件
float4 VSMain(float4 Pos:POSITION) : SV_POSITION
{
return Pos;
}
float4 PSMain(float4 Pos:POSITION):SV_TARGET
{
return float4(0.0f,1.0f,0.0f,1.0f);
}
6、编写d3dTriangle.cpp源文件
#include"d3dUtility.h"
ID3D11Device* device=NULL;
IDXGISwapChain* swapChain=NULL;
ID3D11DeviceContext* immediateContext=NULL;
ID3D11RenderTargetView* renderTargetView=NULL;
ID3D11VertexShader* vertexShader;
ID3D11PixelShader* pixelShader;
struct Vertex
{
XMFLOAT3 Pos;
};
bool Setup()
{
DWORD dwShaderFlag=D3DCOMPILE_ENABLE_STRICTNESS;
ID3DBlob* pVSBlob=NULL;
if(FAILED(D3DX11CompileFromFile(
L"Triangle.hlsl",
NULL,
NULL,
"VSMain",
"vs_5_0",
dwShaderFlag,
0,
NULL,
&pVSBlob,
NULL,
NULL)))
{
MessageBox(NULL,L"Fail to compile vertex shader",L"ERROR",MB_OK);
return S_FALSE;
}
device->CreateVertexShader(
pVSBlob->GetBufferPointer(),
pVSBlob->GetBufferSize(),
NULL,
&vertexShader);
ID3DBlob* pPSBlob=NULL;
if(FAILED(D3DX11CompileFromFile(
L"Triangle.hlsl",
NULL,
NULL,
"PSMain",
"ps_5_0",
dwShaderFlag,
0,
NULL,
&pPSBlob,
NULL,
NULL)))
{
MessageBox(NULL,L"Fail to compile pixel shader",L"ERROR",MB_OK);
return S_FALSE;
}
device->CreatePixelShader(
pPSBlob->GetBufferPointer(),
pPSBlob->GetBufferSize(),
NULL,
&pixelShader);
D3D11_INPUT_ELEMENT_DESC layout[]=
{
{"POSITION",
0,
DXGI_FORMAT_R32G32B32_FLOAT,
0,
0,
D3D11_INPUT_PER_VERTEX_DATA,
0}
};
UINT numElements=ARRAYSIZE(layout);
ID3D11InputLayout* pVertexLayout;
device->CreateInputLayout(
layout,
numElements,
pVSBlob->GetBufferPointer(),
pVSBlob->GetBufferSize(),
&pVertexLayout);
immediateContext->IASetInputLayout(pVertexLayout);
Vertex vertices[]=
{
//XMFLOAT3(0.0f,0.5f,0.0f),
//XMFLOAT3(0.5f,0.0f,0.0f),
//XMFLOAT3(-0.5f,0.0f,0.0f),
XMFLOAT3(0.5f,0.0f,0.0f),
XMFLOAT3(0.0f,-0.5f,0.0f),
XMFLOAT3(-0.5f,0.0f,0.0f),
};
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd,sizeof(bd));
bd.ByteWidth=sizeof(Vertex)*3;//顶点个数
bd.BindFlags=D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags=0;
bd.MiscFlags=0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory(&InitData,sizeof(InitData));
InitData.pSysMem=vertices;
ID3D11Buffer* vertexBuffer;
device->CreateBuffer(&bd,&InitData,&vertexBuffer);
UINT stride=sizeof(Vertex);
UINT offset=0;
immediateContext->IASetVertexBuffers(
0,
1,
&vertexBuffer,
&stride,
&offset);
immediateContext->IASetPrimitiveTopology(
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
}
void Cleanup()
{
if(renderTargetView) renderTargetView->Release();
if(immediateContext) immediateContext->Release();
if(swapChain) swapChain->Release();
if(device) device->Release();
if(vertexShader)vertexShader->Release();
if(pixelShader)pixelShader->Release();
}
bool Display(float timeDelta)
{
if(device)
{
float ClearColor[4]={0.0f,0.125f,0.3f,1.0f};
immediateContext->ClearRenderTargetView(renderTargetView,ClearColor);
immediateContext->VSSetShader(vertexShader,NULL,0);
immediateContext->PSSetShader(pixelShader,NULL,0);
immediateContext->Draw(3,0);//改变绘制的顶点个数
swapChain->Present(0,0);
}
return true;
}
LRESULT CALLBACK d3d::WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
::PostQuitMessage(0);
break;
case WM_KEYDOWN:
if(wParam==VK_ESCAPE)
::DestroyWindow(hwnd);
break;
}
return ::DefWindowProc(hwnd,msg,wParam,lParam);
}
int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE prevInstance,
PSTR cmdLine,
int showCmd)
{
if(!d3d::InitD3D(hinstance,
800,600,
&renderTargetView,
&immediateContext,
&swapChain,
&device))
{
::MessageBox(0,L"InitD3D()-FAILED",0,0);
return 0;
}
if(!Setup())
{
::MessageBox(0,L"Setup()-FAILED",0,0);
return 0;
}
d3d::EnterMsgLoop(Display);
Cleanup();
return 0;
}
7、编译运行程序,结果如下:
如果要更改颜色可以更改如下图代码:
如果要更改三角形为正三角形可以更改如下位置:
注释部分为正三角形
如下图效果:
注意:在绘制三角形的时候,D3D会默认顶点绕序为顺时针的三角形为正面,而顶点绕序为逆时针的三角形为背面。而默认情况下背面是不能显示的。修改代码还可以实现一个可以移动和缩放的菱形,代码如下
#include"d3dUtility.h"
ID3D11Device* device=NULL;
IDXGISwapChain* swapChain=NULL;
ID3D11DeviceContext* immediateContext=NULL;
ID3D11RenderTargetView* renderTargetView=NULL;
ID3D11VertexShader* vertexShader;
ID3D11PixelShader* pixelShader;
float x = 0;
float y = 0;
float x2 = 0;
float y2 = 0;
float x3 = 0;
float y3 = 0;
float x4 = 0;
float y4 = 0;
float x5 = 0;
float y5 = 0;
float x6 = 0;
float y6 = 0;
struct Vertex
{
XMFLOAT3 Pos;
};
bool Setup()
{
DWORD dwShaderFlag=D3DCOMPILE_ENABLE_STRICTNESS;
ID3DBlob* pVSBlob=NULL;
if(FAILED(D3DX11CompileFromFile(
L"Triangle.hlsl",
NULL,
NULL,
"VSMain",
"vs_5_0",
dwShaderFlag,
0,
NULL,
&pVSBlob,
NULL,
NULL)))
{
MessageBox(NULL,L"Fail to compile vertex shader",L"ERROR",MB_OK);
return S_FALSE;
}
device->CreateVertexShader(
pVSBlob->GetBufferPointer(),
pVSBlob->GetBufferSize(),
NULL,
&vertexShader);
ID3DBlob* pPSBlob=NULL;
if(FAILED(D3DX11CompileFromFile(
L"Triangle.hlsl",
NULL,
NULL,
"PSMain",
"ps_5_0",
dwShaderFlag,
0,
NULL,
&pPSBlob,
NULL,
NULL)))
{
MessageBox(NULL,L"Fail to compile pixel shader",L"ERROR",MB_OK);
return S_FALSE;
}
device->CreatePixelShader(
pPSBlob->GetBufferPointer(),
pPSBlob->GetBufferSize(),
NULL,
&pixelShader);
D3D11_INPUT_ELEMENT_DESC layout[]=
{
{"POSITION",
0,
DXGI_FORMAT_R32G32B32_FLOAT,
0,
0,
D3D11_INPUT_PER_VERTEX_DATA,
0}
};
UINT numElements=ARRAYSIZE(layout);
ID3D11InputLayout* pVertexLayout;
device->CreateInputLayout(
layout,
numElements,
pVSBlob->GetBufferPointer(),
pVSBlob->GetBufferSize(),
&pVertexLayout);
immediateContext->IASetInputLayout(pVertexLayout);
Vertex vertices[]=
{
XMFLOAT3(0.0f + x,0.5f + y,0.0f),
XMFLOAT3(0.5f + x2,0.0f + y2,0.0f),
XMFLOAT3(-0.5f + x3,0.0f + y3,0.0f),
XMFLOAT3(0.5f + x4,0.0f + y4,0.0f),
XMFLOAT3(0.0f + x5,-0.5f + y5,0.0f),
XMFLOAT3(-0.5f + x6,0.0f + y6,0.0f),
};
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd,sizeof(bd));
bd.ByteWidth=sizeof(Vertex)*6;//顶点个数
bd.BindFlags=D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags=0;
bd.MiscFlags=0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory(&InitData,sizeof(InitData));
InitData.pSysMem=vertices;
ID3D11Buffer* vertexBuffer;
device->CreateBuffer(&bd,&InitData,&vertexBuffer);
UINT stride=sizeof(Vertex);
UINT offset=0;
immediateContext->IASetVertexBuffers(
0,
1,
&vertexBuffer,
&stride,
&offset);
immediateContext->IASetPrimitiveTopology(
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
}
void Cleanup()
{
if(renderTargetView) renderTargetView->Release();
if(immediateContext) immediateContext->Release();
if(swapChain) swapChain->Release();
if(device) device->Release();
if(vertexShader)vertexShader->Release();
if(pixelShader)pixelShader->Release();
}
bool Display(float timeDelta)
{
if(device)
{
float ClearColor[4]={0.0f,0.125f,0.3f,1.0f};
immediateContext->ClearRenderTargetView(renderTargetView,ClearColor);
immediateContext->VSSetShader(vertexShader,NULL,0);
immediateContext->PSSetShader(pixelShader,NULL,0);
immediateContext->Draw(6,0);//改变绘制的顶点个数
swapChain->Present(0,0);
}
return true;
}
LRESULT CALLBACK d3d::WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
::PostQuitMessage(0);
break;
case WM_KEYDOWN:
if(wParam==VK_ESCAPE)
::DestroyWindow(hwnd);
//移动
if (::GetAsyncKeyState('W') & 0x8000f)
{
x += 0.1;
x2 += 0.1;
x3 += 0.1;
x4 += 0.1;
x5 += 0.1;
x6 += 0.1;
Setup();
}
if (::GetAsyncKeyState('S') & 0x8000f)
{
x -= 0.1;
x2 -= 0.1;
x3 -= 0.1;
x4 -= 0.1;
x5 -= 0.1;
x6 -= 0.1;
Setup();
}
if (::GetAsyncKeyState('D') & 0x8000f)
{
y += 0.1;
y2 += 0.1;
y3 += 0.1;
y4 += 0.1;
y5 += 0.1;
y6 += 0.1;
Setup();
}
if (::GetAsyncKeyState('A') & 0x8000f)
{
y -= 0.1;
y2 -= 0.1;
y3 -= 0.1;
y4 -= 0.1;
y5 -= 0.1;
y6 -= 0.1;
Setup();
}
//缩放
//放大
if (::GetAsyncKeyState('Q') & 0x8000f)
{
y += 0.1;
x2 += 0.1;
x3 -= 0.1;
x4 += 0.1;
y5 -= 0.1;
x6 -= 0.1;
Setup();
}
//缩小
if (::GetAsyncKeyState('R') & 0x8000f)
{
y -= 0.1;
x2 -= 0.1;
x3 += 0.1;
x4 -= 0.1;
y5 += 0.1;
x6 += 0.1;
Setup();
}
//
break;
}
return ::DefWindowProc(hwnd,msg,wParam,lParam);
}
int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE prevInstance,
PSTR cmdLine,
int showCmd)
{
if(!d3d::InitD3D(hinstance,
800,600,
&renderTargetView,
&immediateContext,
&swapChain,
&device))
{
::MessageBox(0,L"InitD3D()-FAILED",0,0);
return 0;
}
if(!Setup())
{
::MessageBox(0,L"Setup()-FAILED",0,0);
return 0;
}
d3d::EnterMsgLoop(Display);
Cleanup();
return 0;
}
结果为: