DirectX11之简单三角形之美

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;
}

结果为:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嘿克不黑

你的鼓励是我的最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值