DX11——第一个程序:Box

程序流程:

  1. 创建主窗口。注册窗口类WNDCLASS,创建窗口CreateWindow,显示窗口ShowWindow,绘制窗口客户区UpdateWindow
    bool initWndApp(HINSTANCE hInstance, int show)
    {
    	WNDCLASSEX wc;
    	wc.cbSize = sizeof(WNDCLASSEX);
    	wc.hInstance = hInstance;
    	wc.lpfnWndProc = WndProc;
    	wc.style = CS_HREDRAW | CS_VREDRAW;
    	wc.cbClsExtra = 0;
    	wc.cbWndExtra = 0;
    	wc.hIcon = LoadIcon(0,IDI_APPLICATION); 
    	wc.hCursor = LoadCursor(0, IDC_CROSS);
    	wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    	wc.lpszMenuName = 0;
    	wc.lpszClassName = L"BasicWndClass";
    	wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    	if ( !RegisterClassEx(&wc)) {
    		MessageBox(0, L"RegisterClass Failed", 0, 0);
    		return false;
    	}
    	//如果没有WS_VISIBLE标志,则需要手动调用ShowWindow来显示窗口
    	
    	mainWnd = CreateWindowEx(NULL, L"BasicWndClass",
    		L"我的窗口1", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
    		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
    		NULL, NULL, hInstance, NULL);
    	if (mainWnd == 0) {
    		MessageBox(0, L"CreateWindow1 FAILED", 0, 0);
    		return false;
    	}
    	ShowWindow(mainWnd, show);
    	//该函数将发送一个WM_PAINT消息
    	UpdateWindow(mainWnd);
    	return true;
    }

  2. 创建设备和设备环境。D3D11CreateDevice,测试多重采样质量等级ID3D11Device::CheckMultisampleQualityLevels
  3. 创建后台缓冲交换链。IDXGIFactory::CreateSwapChain
    void mCreateDevice()
    {
    	D3D_FEATURE_LEVEL featureLevel;
    	HRESULT hr = D3D11CreateDevice(0,
    		D3D_DRIVER_TYPE_HARDWARE,
    		0, createDeviceFlg,
    		0, 0,
    		D3D11_SDK_VERSION,
    		&g_pD3DDevice,
    		&featureLevel,
    		&g_pD3DImmediateContext);
    	
    	if (FAILED(hr))
    	{
    		MessageBox(0, L"D3D11CreateDevice Failed.", 0, 0);
    		return;
    	}
    	if (featureLevel != D3D_FEATURE_LEVEL_11_0)
    	{
    		MessageBox(0, L"DX 11 unsupported.", 0, 0);
    		return;
    	}
    	DXGI_SWAP_CHAIN_DESC sd;
    	//back buffer数
    	sd.BufferCount = 1;
    	//显示器一般不支持大于24位的颜色
    	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    	sd.BufferDesc.Width = g_WndWidth;
    	sd.BufferDesc.Height = g_WndHeight;
    	//刷新频率60/1
    	sd.BufferDesc.RefreshRate.Numerator = 60;
    	sd.BufferDesc.RefreshRate.Denominator = 1;
    	sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
    	sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
    	//不使用多重采样
    	sd.SampleDesc.Count = 1;
    	sd.SampleDesc.Quality = 0;
    	sd.OutputWindow = mainWnd;	
    	sd.Windowed = true;
    	sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    	sd.Flags = 0;
    	//create swap chain
    	IDXGIDevice *dxgiDevice = 0;
    	HR(g_pD3DDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice));
    	IDXGIAdapter *dxgiAdapter = 0;
    	HR(dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter));
    	IDXGIFactory *dxgiFactory = 0;
    	HR(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory));
    	HR(dxgiFactory->CreateSwapChain(g_pD3DDevice, &sd, &g_pSwapChain));
    	dxgiDevice->Release();
    	dxgiAdapter->Release();
    	dxgiFactory->Release();
    }

  4. 创建渲染对象视图。ID3D11Device::CreateRenderTargetView
  5. 创建深度模板缓冲及其视图。ID3D11Device::CreateDepthStencilView
  6. 将4、5中的视图绑定到管线。ID3D11DeviceContext::OMSetRenderTargets
  7. 设置视口。ID3D11DeviceContext::RSSetViewports
    void mCreateView()
    {
    	assert(g_pD3DDevice);
    	assert(g_pD3DImmediateContext);
    	assert(g_pSwapChain);
    
    	ReleaseCOM(g_pRenderTView);
    	ReleaseCOM(g_pDSView);
    	ReleaseCOM(g_pDepthStencilBuffer);
    
    	HR(g_pSwapChain->ResizeBuffers(1, g_WndWidth, g_WndHeight, DXGI_FORMAT_R8G8B8A8_UNORM, 0));
    
    	ID3D11Texture2D *backBuffer;
    	HR(g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBuffer)));
    	g_pD3DDevice->CreateRenderTargetView(backBuffer, 0, &g_pRenderTView);
    	ReleaseCOM(backBuffer);
    
    	D3D11_TEXTURE2D_DESC depthStencilDesc;
    	depthStencilDesc.Width = g_WndWidth;
    	depthStencilDesc.Height = g_WndHeight;
    	depthStencilDesc.ArraySize = 1;
    	depthStencilDesc.MipLevels = 1;
    	depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    	depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    	depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
    	depthStencilDesc.SampleDesc.Count = 1;
    	depthStencilDesc.SampleDesc.Quality = 0;
    	depthStencilDesc.CPUAccessFlags = 0;		
    	depthStencilDesc.MiscFlags = 0;	
    	
    	HR(g_pD3DDevice->CreateTexture2D(&depthStencilDesc, 0, &g_pDepthStencilBuffer));
    	HR(g_pD3DDevice->CreateDepthStencilView(g_pDepthStencilBuffer, 0, &g_pDSView));
    
    	g_pD3DImmediateContext->OMSetRenderTargets(
    		1, &g_pRenderTView, g_pDSView);
    	//set view port
    	g_pVp.TopLeftX = 0.0f;
    	g_pVp.TopLeftY = 0.0f;
    	g_pVp.Width = static_cast<float>(g_WndWidth);
    	g_pVp.Height = static_cast<float>(g_WndHeight);
    	g_pVp.MinDepth = 0.0f;
    	g_pVp.MaxDepth = 1.0f;
    	g_pD3DImmediateContext->RSSetViewports(1, &g_pVp);
    }
  8. 创建顶点缓冲区。创建顶点结构,定义顶点数组,定义缓冲区描述D3D11_BUFFER_DESC,定义子资D3D11_SUBRESOURCE_DATAID3D11Device::CreateBuffer
  9. 创建索引缓冲区。定义索引数据,定义缓冲区描述D3D11_BUFFER_DESC,定义子资源D3D11_SUBRESOURCE_DATAID3D11Device::CreateBuffer
    void mCreateBuffer()
    {
    	
    //顺时针方向为正面
    
    	D3D11_BUFFER_DESC vBufferDesc;
    	vBufferDesc.ByteWidth = sizeof(myVertex) * 8;
    	vBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    	vBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
    	vBufferDesc.CPUAccessFlags = 0;
    	vBufferDesc.MiscFlags = 0;
    	vBufferDesc.StructureByteStride = 0; 
    
    	D3D11_SUBRESOURCE_DATA vertexData;
    	vertexData.pSysMem = mvBox;	
    	HR(g_pD3DDevice->CreateBuffer(&vBufferDesc, &vertexData, &g_pVectorBuffer));
    
    	
    	D3D11_BUFFER_DESC iBufferDesc;
    	iBufferDesc.ByteWidth = sizeof(UINT) * 36;
    	iBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
    	iBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
    	iBufferDesc.CPUAccessFlags = 0;
    	iBufferDesc.MiscFlags = 0;
    	iBufferDesc.StructureByteStride = 0;
    	
    	D3D11_SUBRESOURCE_DATA indexData;
    	indexData.pSysMem = idxBox;
    	//indexData.SysMemPitch = 0;
    	//indexData.SysMemSlicePitch = 0;
    	HR(g_pD3DDevice->CreateBuffer(&iBufferDesc, &indexData, &g_pIndexBuffer));
    }


  10. 创建并编写着色器。在.FX文件(Effect文件)中编写Vertex Shader,Pixel Shader等。
  11. 编译Effect文件。D3DX11CompileFromFile
    void mCreateFX()
    {
    	DWORD shaderFlg = 0;
    #if defined(DEBUG) || defined(_DEBUG)
    	shaderFlg |= D3D10_SHADER_DEBUG;
    	shaderFlg |= D3D10_SHADER_SKIP_OPTIMIZATION;
    #endif
    	ID3D10Blob *compiledShader = 0;
    	ID3D10Blob *compiledMsg = 0;
    	HRESULT hr = D3DX11CompileFromFile(L"color.fx",
    		0, 0, 0,
    		"fx_5_0",
    		shaderFlg,
    		0, 0,
    		&compiledShader,
    		&compiledMsg,
    		0);
    	if (compiledMsg != 0) {
    		MessageBoxA(0, (char*)compiledMsg->GetBufferPointer(), 0, 0);
    		compiledMsg->Release();
    	}
    	if (FAILED(hr)) {
    		DXTrace(__FILE__, (DWORD)__LINE__, hr,
    			L"D3DX11CompileFromFile", TRUE);
    	}
    	HR(D3DX11CreateEffectFromMemory(
    		compiledShader->GetBufferPointer(),
    		compiledShader->GetBufferSize(),
    		0, g_pD3DDevice, &g_pEffect));
    	ReleaseCOM(compiledShader); // attention
    
    	g_pTech = g_pEffect->GetTechniqueByName("ColorTech");
    	mWVP = g_pEffect->GetVariableByName("gWorldViewProj")->AsMatrix();	//buuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuug__gWorldViewProjection
    }

  12. 创建输入布局。定义输入元素描述D3D11_INPUT_ELEMENT_DESCID3D11Device::CreateInputLayout
    void mCreateInputLayout()
    {	
    	D3D11_INPUT_ELEMENT_DESC vertexDesc[] = 
    	{
    		{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, 
    		D3D11_INPUT_PER_VERTEX_DATA, 0},
    		{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12,
    		D3D11_INPUT_PER_VERTEX_DATA, 0}
    	};
    	D3DX11_PASS_DESC passDesc;
    	g_pTech->GetPassByIndex(0)->GetDesc(&passDesc);
    	HR(g_pD3DDevice->CreateInputLayout(vertexDesc, 2,
    		passDesc.pIAInputSignature,
    		passDesc.IAInputSignatureSize,
    		&g_pLayout));
    
    }

  13. 进入窗口消息循环。收到消息时转14,否则转15。
    void run()
    {
    	MSG msg;
    
    	while (true) {
    		if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
    			if (msg.message == WM_QUIT) break;
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}
    		//do animation/game stuff
    		drawBox();
    	}
    	release();
    }

  14. 处理窗口消息。
    LRESULT CALLBACK
    	WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	PAINTSTRUCT ps;
    	HDC hdc;
    	static UINT wcount = 0;
    
    	switch(msg){
    	case WM_CREATE:
    //		MessageBox(0, L"窗口创建成功!", L"Create", 0);
    		++wcount;		
    		return 0;
    		//WM_PAINT在窗口需要重绘时发送
    	case WM_PAINT:
    		hdc = BeginPaint(hWnd, &ps);
    		drawBox();
    		EndPaint(hWnd, &ps);
    		return 0;
    	case WM_KEYDOWN:
    		if (wParam == VK_ESCAPE){
    			DestroyWindow(hWnd);
    		}
    		return 0;
    	case WM_DESTROY:
    		if (!--wcount){
    			PostQuitMessage(0);
    		}
    		return 0;
    	}
    
    	return DefWindowProc(hWnd, msg, wParam, lParam);
    }

  15. 设置变换矩阵。World MatrixView MatrixPerspective Projection Matrix
  16. 将资源绑定到管线。IASetInputLayoutIASetPrimitiveTopologyIASetVertexBuffersIASetIndexBuffer
  17. 绘制图形。
  18. 提交到缓冲区。
    void mSetRenderState()
    {
    	// clear render target and depth/stencil
    	g_pD3DImmediateContext->ClearRenderTargetView(
    		g_pRenderTView, reinterpret_cast<const float*>(&LightSteelBlue));
    	g_pD3DImmediateContext->ClearDepthStencilView(
    		g_pDSView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
    
    	g_pD3DImmediateContext->IASetInputLayout(g_pLayout);
    	g_pD3DImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    
    	UINT stride = sizeof(myVertex);
    	UINT offset = 0;
    
    	g_pD3DImmediateContext->IASetVertexBuffers(0, 1, &g_pVectorBuffer,
    		&stride, &offset);
    	g_pD3DImmediateContext->IASetIndexBuffer(g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
    	// world matrix
    	XMMATRIX world;
    	world = XMMatrixIdentity();
    	// view matrix
    	XMMATRIX view;
    	float x = 3.0f;
    	float y = 2.0f;
    	float z = 2.0f;
    	XMVECTOR pos = XMVectorSet(x, y, z, 1.0f);
    	XMVECTOR target = XMVectorZero();
    	XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
    	view = XMMatrixLookAtLH(pos, target, up);
    	// projection matrix
    	XMMATRIX proj;
    	proj = XMMatrixPerspectiveFovLH(
    		0.25*PI, static_cast<float>(g_WndWidth)/g_WndHeight, 1.0f, 1000.0f);
    	XMMATRIX wvp = world*view*proj;
    	mWVP->SetMatrix(reinterpret_cast<const float*>(&wvp));
    
    	D3DX11_TECHNIQUE_DESC techDesc;
    	g_pTech->GetDesc(&techDesc);
    	for (UINT p=0; p<techDesc.Passes; ++p)
    	{
    		g_pTech->GetPassByIndex(p)->Apply(0, g_pD3DImmediateContext);
    		g_pD3DImmediateContext->DrawIndexed(36, 0, 0);
    	}	
    
    	HR(g_pSwapChain->Present(0, 0));
    }

  19. 释放资源。
    void release()
    {
    	ReleaseCOM(g_pD3DDevice);
    	ReleaseCOM(g_pD3DImmediateContext);
    	ReleaseCOM(g_pSwapChain);
    	ReleaseCOM(g_pEffect);
    	ReleaseCOM(g_pLayout);
    	ReleaseCOM(g_pVectorBuffer);
    	ReleaseCOM(g_pDepthStencilBuffer);
    	ReleaseCOM(g_pDSView);
    }

创建的资源在使用完后,最好都释放一下。不然小心内存用完哦!大笑

ID3DX11Effect->GetVariableByName();里面的变量名写错了,编译器检查不到,运行时box出不来。痛苦的找了几天的bug,在仔细检查了N遍后发现。血与泪的教训啊!铭记!快哭了



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

superbin

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值