zoukankan      html  css  js  c++  java
  • D3D实战-在窗口中画一个三角形

    简介

    本文使用D3D绘制一个三角形,通过这个程序可以了解一下D3D的基本开发过程。

    运行效果

    开发环境

    系统:Windows 10
    IDE:Visual Studio 2019

    注意

    本示例需要两个帮助文件点击下载

    开发步骤

    创建窗口

    1、新建一个空白C++项目,文件->新建->项目,语言选择C++,平台选择Windows,选择空项目,点击下一步,真写项目名称和位置,点击创建。
    2、新建一个C++文件:stdafx.cpp和一个头文件:stdafx.h。
    3、解决方案资源管理器中右击项目,选择属性。
    常规里边,输出目录改为:bin$(Configuration),中间目录改为:obj$(Configuration)。
    调试里边,工作目录改为:$(OutDir)
    点击确定

    4、右击项目,选择属性。
    C/C++->预处理器,预处理器定义,编辑,填入如下内容:
    _DEBUG
    _WINDOWS
    NOMINMAX
    C/C++->预编译头,改为使用(/Yu)。
    链接器->输入,附加依赖项改为:
    d3d12.lib
    D3D11.lib
    dxgi.lib
    d3dcompiler.lib
    d2d1.lib
    dwrite.lib
    dxguid.lib
    xaudio2.lib
    mfcore.lib
    mfplat.lib
    mfreadwrite.lib
    mfuuid.lib
    链接器->系统,子系统改为:窗口 (/SUBSYSTEM:WINDOWS)
    点击确定。
    5、右击项目,管理NuGet程序包,浏览里边搜索DirectXTK12,在搜索结果中选择directxtk12_desktop_2017,安装。
    6、右击stdafx.cpp文件,选择属性,预编译头,改为创建 (/Yc)
    6、打开stdafx.h,输入以下内容

    #pragma once
    
    #include <SDKDDKVer.h>
    #define WIN32_LEAN_AND_MEAN 
    #include <windows.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <memory.h>
    #include <tchar.h>
    #include <time.h> 
    #include <string>
    
    #include <d3d12.h>
    #include <d3d11_3.h>
    #include <d3d11on12.h>
    #include <dxgi1_4.h>
    #include <D3Dcompiler.h>
    #include <DirectXMath.h>
    
    #include <d2d1_3.h>
    #include <dwrite_3.h>
    #include <wincodec.h>
    
    #include <CommonStates.h>
    #include <DDSTextureLoader.h>
    #include <ResourceUploadBatch.h>
    #include <DirectXHelpers.h>
    #include <Effects.h>
    #include <GamePad.h>
    #include <GeometricPrimitive.h>
    #include <GraphicsMemory.h>
    #include <Keyboard.h>
    #include <Model.h>
    #include <Mouse.h>
    #include <PostProcess.h>
    #include <PrimitiveBatch.h>
    #include <ScreenGrab.h>
    #include <SimpleMath.h>
    #include <SpriteBatch.h>
    #include <SpriteFont.h>
    #include <VertexTypes.h>
    #include <WICTextureLoader.h>
    
    #include <Audio.h>
    
    #include <string>
    #include <wrl.h>
    #include <shellapi.h>
    
    

    7、创建一个C++源文件TriangleMain.cpp,输入以下内容:

    #include "stdafx.h"
    
    // 全局变量:
    HINSTANCE hInst;                                // 当前实例
    WCHAR szWindowClass[] = L"TriangleWindow";
    
    // 此代码模块中包含的函数的前向声明:
    ATOM                MyRegisterClass(HINSTANCE hInstance);
    BOOL                InitInstance(HINSTANCE, int);
    LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
    INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
    int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
    	_In_opt_ HINSTANCE hPrevInstance,
    	_In_ LPWSTR    lpCmdLine,
    	_In_ int       nCmdShow)
    {
    	UNREFERENCED_PARAMETER(hPrevInstance);
    	UNREFERENCED_PARAMETER(lpCmdLine);
    
    	// TODO: 在此处放置代码。
    
    	// 初始化全局字符串
    	MyRegisterClass(hInstance);
    
    	// 执行应用程序初始化:
    	if (!InitInstance(hInstance, nCmdShow))
    	{
    		return FALSE;
    	}
    
    	MSG msg = {};
    
    	// 主消息循环:
    	while (msg.message != WM_QUIT)
    	{
    		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}
    	}
    
    	return (int)msg.wParam;
    }
    
    
    
    //
    //  函数: MyRegisterClass()
    //
    //  目标: 注册窗口类。
    //
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
    	WNDCLASSEXW wcex = { 0 };
    
    	wcex.cbSize = sizeof(WNDCLASSEX);
    
    	wcex.style = CS_HREDRAW | CS_VREDRAW;
    	wcex.lpfnWndProc = WndProc;
    	wcex.cbClsExtra = 0;
    	wcex.cbWndExtra = 0;
    	wcex.hInstance = hInstance;
    	wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    	wcex.lpszClassName = szWindowClass;
    
    	return RegisterClassExW(&wcex);
    }
    
    //
    //   函数: InitInstance(HINSTANCE, int)
    //
    //   目标: 保存实例句柄并创建主窗口
    //
    //   注释:
    //
    //        在此函数中,我们在全局变量中保存实例句柄并
    //        创建和显示主程序窗口。
    //
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
    	hInst = hInstance; // 将实例句柄存储在全局变量中
    
    	HWND hWnd = CreateWindowW(szWindowClass, L"Triangle", WS_OVERLAPPEDWINDOW,
    		CW_USEDEFAULT, 0, 800, 600, nullptr, nullptr, hInstance, nullptr);
    
    	if (!hWnd)
    	{
    		return FALSE;
    	}
    
    	ShowWindow(hWnd, nCmdShow);
    	UpdateWindow(hWnd);
    
    	return TRUE;
    }
    
    //
    //  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
    //
    //  目标: 处理主窗口的消息。
    //
    //  WM_COMMAND  - 处理应用程序菜单
    //  WM_PAINT    - 绘制主窗口
    //  WM_DESTROY  - 发送退出消息并返回
    //
    //
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	switch (message)
    	{
    	case WM_KEYDOWN:
    		break;
    	case WM_PAINT:
    		break;
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		break;
    	default:
    		return DefWindowProc(hWnd, message, wParam, lParam);
    	}
    	return 0;
    }
    

    编译后按F5运行,正常情况下会出现一个空白窗口。这个窗口用作绘图区域。

    准备3D环境

    首先,我们要在程序里枚举出支持DirectX的设备,并创建一个交换链用于呈现后台缓存中的图像内容。我们将这部分代码封装到一个Device的类中,绘图操作放到Scene类中。

    Device类实现

    这个类中需要创建两个东西,一个设备接口实例,一个交换链实例,还有一个是CPU与GPU数据同步的围栏,以及提供创建各类资源、呈现图像、缓存管理的方法。别外,创建交互链需要提供窗口的句柄和尺寸。

    //Device.h
    #pragma once
    
    using namespace DirectX;
    using namespace Microsoft::WRL;
    
    class Device
    {
    private:
    	HWND m_hwnd; //窗口句柄
    	int m_width; //窗口宽度
    	int m_height; //窗口高度
    	bool m_useWarpDevice; //是否使用模拟设备
    	UINT m_frameCount; //缓冲数量
    	int m_rtvDescriptorSize; //RTV缓存大小
    
    	ComPtr<IDXGISwapChain3> m_swapChain;
    	ComPtr<ID3D12Device> m_device;
    	ComPtr<ID3D12CommandQueue> m_commandQueue;
    
    	ComPtr<ID3D12DescriptorHeap> m_rtvHeap;
    	std::vector<ComPtr<ID3D12Resource>> m_renderTargets;
    	ComPtr<ID3D12Resource> m_depthStencil;
    	ComPtr<ID3D12DescriptorHeap> m_dsvHeap;
    
    	ComPtr<ID3D12Fence> m_fence;
    	UINT64 m_fenceValue;
    	HANDLE m_fenceEvent;
    	int m_frameIndex;
    
    	void GetHardwareAdapter(_In_ IDXGIFactory2* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter);
    	void CreateDevice();
    	void CreateRenderTarget();
    	void CreateDepthStencil();
    
    public:
    	Device(HWND hwnd, int wWidth, int wHeight, int frameCount, bool useWrap);
    	HRESULT CreateCommandList(ComPtr<ID3D12CommandAllocator>& commandAllocator, ComPtr<ID3D12GraphicsCommandList>& commandList);
    
    	void Present();
    	void PostCommand(ID3D12GraphicsCommandList* commandList);
    	void WaitGpu();
    
    	ID3D12Device* GetDevice() { return m_device.Get(); }
    	ID3D12DescriptorHeap* GetDepthStencilHeap() { return m_dsvHeap.Get(); };
    	ComPtr<ID3D12CommandQueue> GetCommandQueue() { return m_commandQueue; }
    	ID3D12Resource* GetRenderTargetResource() { return m_renderTargets[m_frameIndex].Get(); }
    	CD3DX12_CPU_DESCRIPTOR_HANDLE GetRenderTargetHandle()
    	{
    		CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap.Get()->GetCPUDescriptorHandleForHeapStart(), m_frameIndex, m_rtvDescriptorSize);
    		return rtvHandle;
    	}
    
    };
    
    
    
    //Device.cpp
    #include "stdafx.h"
    #include "Device.h"
    
    void Device::GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter)
    {
    	ComPtr<IDXGIAdapter1> adapter;
    	*ppAdapter = nullptr;
    
    	for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &adapter); ++adapterIndex)
    	{
    		DXGI_ADAPTER_DESC1 desc;
    		adapter->GetDesc1(&desc);
    
    		if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
    		{
    			// Don't select the Basic Render Driver adapter.
    			// If you want a software adapter, pass in "/warp" on the command line.
    			continue;
    		}
    
    		// Check to see if the adapter supports Direct3D 12, but don't create the
    		// actual device yet.
    		if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
    		{
    			break;
    		}
    	}
    
    	*ppAdapter = adapter.Detach();
    
    }
    
    void Device::CreateDevice()
    {
    	UINT dxgiFactoryFlags = 0;
    
    #if defined(_DEBUG)
    	// Enable the debug layer (requires the Graphics Tools "optional feature").
    	// NOTE: Enabling the debug layer after device creation will invalidate the active device.
    	{
    		ComPtr<ID3D12Debug> debugController;
    		if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
    		{
    			debugController->EnableDebugLayer();
    
    			// Enable additional debug layers.
    			dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG;
    		}
    	}
    #endif
    
    	ComPtr<IDXGIFactory4> factory;
    	CreateDXGIFactory2(dxgiFactoryFlags, IID_PPV_ARGS(&factory));
    	bool useWarpDevice = true;
    
    	if (useWarpDevice)
    	{
    		ComPtr<IDXGIAdapter> warpAdapter;
    		factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter));
    
    		D3D12CreateDevice(
    			warpAdapter.Get(),
    			D3D_FEATURE_LEVEL_11_0,
    			IID_PPV_ARGS(&m_device)
    		);
    	}
    	else
    	{
    		ComPtr<IDXGIAdapter1> hardwareAdapter;
    		GetHardwareAdapter(factory.Get(), &hardwareAdapter);
    
    		D3D12CreateDevice(
    			hardwareAdapter.Get(),
    			D3D_FEATURE_LEVEL_11_0,
    			IID_PPV_ARGS(&m_device)
    		);
    	}
    
    	D3D12_COMMAND_QUEUE_DESC queueDesc = {};
    	queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
    	queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
    
    	m_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue));
    
    	// Describe and create the swap chain.
    	DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
    	swapChainDesc.BufferCount = m_frameCount;
    	swapChainDesc.Width = m_width;
    	swapChainDesc.Height = m_height;
    	swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    	swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    	swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
    	swapChainDesc.SampleDesc.Count = 1;
    
    	ComPtr<IDXGISwapChain1> swapChain;
    	factory->CreateSwapChainForHwnd(
    		m_commandQueue.Get(),        // Swap chain needs the queue so that it can force a flush on it.
    		m_hwnd,
    		&swapChainDesc,
    		nullptr,
    		nullptr,
    		&swapChain
    	);
    
    	// This sample does not support fullscreen transitions.
    	factory->MakeWindowAssociation(m_hwnd, DXGI_MWA_NO_ALT_ENTER);
    
    	swapChain.As(&m_swapChain);
    	m_frameIndex = m_swapChain->GetCurrentBackBufferIndex();
    
    	m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence));
    	m_fenceValue = 1;
    
    	// Create an event handle to use for frame synchronization.
    	m_fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
    	if (m_fenceEvent == nullptr)
    	{
    		HRESULT_FROM_WIN32(GetLastError());
    	}
    
    }
    
    void Device::CreateRenderTarget()
    {
    	D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
    	rtvHeapDesc.NumDescriptors = m_frameCount;
    	rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
    	rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
    	
    	m_device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_rtvHeap));
    	m_rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
    
    	m_renderTargets.resize(m_frameCount);
    	CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart());
    	// Create a RTV for each frame.
    	for (UINT n = 0; n < m_frameCount; n++)
    	{
    		m_swapChain->GetBuffer(n, IID_PPV_ARGS(&m_renderTargets[n]));
    		m_device->CreateRenderTargetView(m_renderTargets[n].Get(), nullptr, rtvHandle);
    
    		NAME_D3D12_OBJECT_INDEXED(m_renderTargets, n);
    
    		rtvHandle.Offset(1, m_rtvDescriptorSize);
    	}
    
    }
    
    void Device::CreateDepthStencil()
    {
    	D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {};
    	dsvHeapDesc.NumDescriptors = 1;
    	dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
    	dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
    	ThrowIfFailed(m_device->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&m_dsvHeap)));
    
    	D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilDesc = {};
    	depthStencilDesc.Format = DXGI_FORMAT_D32_FLOAT;
    	depthStencilDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
    	depthStencilDesc.Flags = D3D12_DSV_FLAG_NONE;
    
    	D3D12_CLEAR_VALUE depthOptimizedClearValue = {};
    	depthOptimizedClearValue.Format = DXGI_FORMAT_D32_FLOAT;
    	depthOptimizedClearValue.DepthStencil.Depth = 1.0f;
    	depthOptimizedClearValue.DepthStencil.Stencil = 0;
    
    	m_device->CreateCommittedResource(
    		&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
    		D3D12_HEAP_FLAG_NONE,
    		&CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D32_FLOAT, m_width, m_height, 1, 0, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL),
    		D3D12_RESOURCE_STATE_DEPTH_WRITE,
    		&depthOptimizedClearValue,
    		IID_PPV_ARGS(&m_depthStencil)
    	);
    
    	NAME_D3D12_OBJECT(m_depthStencil);
    
    	m_device->CreateDepthStencilView(m_depthStencil.Get(), &depthStencilDesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart());
    
    }
    
    Device::Device(HWND hwnd, int width, int height, int frameCount, bool useWrap):
    	m_hwnd(hwnd),
    	m_width(width),
    	m_height(height),
    	m_frameCount(frameCount),
    	m_useWarpDevice(useWrap)
    {
    	CreateDevice();
    	CreateRenderTarget();
    	CreateDepthStencil();
    
    }
    
    HRESULT Device::CreateCommandList(ComPtr<ID3D12CommandAllocator>& commandAllocator, ComPtr<ID3D12GraphicsCommandList>& commandList)
    {
    	HRESULT hr = E_INVALIDARG;
    	ComPtr<ID3D12CommandAllocator> m_commandAllocator;
    
    	hr = m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_commandAllocator));
    	if (hr == S_OK) {
    		commandAllocator = m_commandAllocator;
    		NAME_D3D12_OBJECT(m_commandAllocator);
    
    		ComPtr<ID3D12GraphicsCommandList> m_commandList;
    		hr = m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), nullptr, IID_PPV_ARGS(&m_commandList));
    		commandList = m_commandList;
    
    		NAME_D3D12_OBJECT(m_commandList);
    	}
    	return hr;
    }
    
    void Device::Present()
    {
    	m_swapChain->Present(1, 0);
    
    	WaitGpu();
    
    }
    
    void Device::PostCommand(ID3D12GraphicsCommandList* commandList)
    {
    	ID3D12CommandList* ppCommandLists[] = { commandList };
    	m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
    
    }
    
    void Device::WaitGpu()
    {
    	const UINT64 fence = m_fenceValue;
    	m_commandQueue->Signal(m_fence.Get(), fence);
    	m_fenceValue++;
    
    	// Wait until the previous frame is finished.
    	if (m_fence->GetCompletedValue() < fence)
    	{
    		m_fence->SetEventOnCompletion(fence, m_fenceEvent);
    		WaitForSingleObject(m_fenceEvent, INFINITE);
    	}
    
    	m_frameIndex = m_swapChain->GetCurrentBackBufferIndex();
    
    }
    
    

    Scene的实现

    这个类准备一个命令表,通过这个命令表传递GPU绘图命令,创建相关的资源,如顶点,纹理等。最后交给命令队列去执行,将绘图结果放入后台缓冲,最后调用交互链的呈现接口,将生成的图像呈现在屏幕上。

    Scene.h
    #pragma once
    #include "Device.h"
    
    using namespace DirectX;
    using namespace DirectX::SimpleMath;
    class Scene
    {
    private:
    	CD3DX12_VIEWPORT m_viewport;
    	CD3DX12_RECT m_scissorRect;
    
    	Device* m_device;
    
    	std::unique_ptr<GraphicsMemory> m_graphicsMemory;
    	std::unique_ptr<DirectX::CommonStates> m_states;
    
    	ComPtr<ID3D12GraphicsCommandList> m_commandList;
    	ID3D12CommandQueue* m_commandQueue;
    	ComPtr<ID3D12CommandAllocator> m_commandAllocator;
    
    	DirectX::SimpleMath::Matrix m_world;
    	DirectX::SimpleMath::Matrix m_view;
    	DirectX::SimpleMath::Matrix m_proj;
    
    	using VertexType = DirectX::VertexPositionColor;
    
    	std::unique_ptr<DirectX::BasicEffect> m_effect;
    	std::unique_ptr<DirectX::PrimitiveBatch<VertexType>> m_batch;
    public:
    	HWND m_hwnd;
    	Scene(HWND hwnd, int width, int height);
    	~Scene() {};
    	void Render();
    };
    
    
    Scene.cpp
    #include "stdafx.h"
    #include "Scene.h"
    
    Scene::Scene(HWND hwnd, int width, int height) :
    	m_hwnd(hwnd),
    	m_viewport(0.0f, 0.0f, static_cast<float>(width), static_cast<float>(height)),
    	m_scissorRect(0, 0, static_cast<LONG>(width), static_cast<LONG>(height))
    
    {
    	m_device = new Device(hwnd, width, height, 3, true);
    	m_graphicsMemory = std::make_unique<GraphicsMemory>(m_device->GetDevice());
    	m_device->CreateCommandList(m_commandAllocator, m_commandList);
    	m_commandList->Close();
    	m_states = std::make_unique<CommonStates>(m_device->GetDevice());
    
    	m_batch = std::make_unique<PrimitiveBatch<VertexType>>(m_device->GetDevice());
    
    	RenderTargetState rtState(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_D32_FLOAT);
    
    	EffectPipelineStateDescription pd(
    		&VertexType::InputLayout,
    		CommonStates::Opaque,
    		CommonStates::DepthDefault,
    		CommonStates::CullNone,
    		rtState);
    
    	m_effect = std::make_unique<BasicEffect>(m_device->GetDevice(), EffectFlags::VertexColor, pd);
    
    	Matrix proj = Matrix::CreateScale(2.f / float(width),
    		-2.f / float(height), 1.f)
    		* Matrix::CreateTranslation(-1.f, 1.f, 0.f);
    	m_effect->SetProjection(proj);
    }
    
    void Scene::Render()
    {
    	m_commandAllocator->Reset();
    
    	m_commandList->Reset(m_commandAllocator.Get(),nullptr);
    
    	ID3D12DescriptorHeap* heaps[] = {  m_states->Heap() };
    	m_commandList->SetDescriptorHeaps(_countof(heaps), heaps);
    
    	m_commandList->RSSetViewports(1, &m_viewport);
    	m_commandList->RSSetScissorRects(1, &m_scissorRect);
    	ID3D12Resource* rt = m_device->GetRenderTargetResource();
    	m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(rt, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET));
    
    	CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle = m_device->GetRenderTargetHandle();
    	CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle(m_device->GetDepthStencilHeap()->GetCPUDescriptorHandleForHeapStart());
    	m_commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, &dsvHandle);
    	const float clearColor[] = { 0.5f, 0.2f, 0.4f, 0.5f };
    	m_commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr);
    	m_commandList->ClearDepthStencilView(dsvHandle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr);
    
    	m_effect->Apply(m_commandList.Get());
    
    	m_batch->Begin(m_commandList.Get());
    
    	VertexPositionColor v1(Vector3(400.f, 150.f, 0.f), Colors::Yellow);
    	VertexPositionColor v2(Vector3(600.f, 450.f, 0.f), Colors::Yellow);
    	VertexPositionColor v3(Vector3(200.f, 450.f, 0.f), Colors::Yellow);
    
    	m_batch->DrawTriangle(v1, v2, v3);
    
    	m_batch->End();
    
    	m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(rt, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));
    	m_commandList->Close();
    	m_device->PostCommand(m_commandList.Get());
    	m_device->Present();
    
    }
    
    
  • 相关阅读:
    懒惰了
    android环境搭建问题总结(0基础)
    android初次配置运行环境
    android 模拟器黑屏
    MapReduce——求每年最高气温
    MapReduce——调用HDFS
    11.Mapreduce实例——MapReduce自定义输出格式小
    MapReduce——Docker服务安装
    10.Mapreduce实例——MapReduce自定义输入格式
    Docker镜像操作——Mysql安装
  • 原文地址:https://www.cnblogs.com/icoolno1/p/12767154.html
Copyright © 2011-2022 走看看