Direct11 学习笔记(一)

创建Direct3D 11设备

首先创建一个窗口,当显示了一个窗口后,下面继续创建一个Direct3D 11设备,这个设备用于绘制3D场景。首先必须创建三个对象,包括设备设备上下文交换链

当显示了一个窗口后,下面继续创建一个Direct3D 11设备,这个设备用于绘制3D场景。首先必须创建三个对象:一个设备、一个立即执行上下文(immediate context)和一个交换链(Swap Chain),立即执行上下文对象是Direct3D 11中新添加的。

设备:用于创建资源。

立即执行上下文:立即执行上下文用于将内容绘制到缓存。

交换链:交换链表示对缓冲(即设备绘制的和显示在屏幕上的内容)的操作。交换链包含两个或两个以上的缓冲,主要是前缓冲和后备缓冲,它们就是设备绘制形成的纹理,用于显示在屏幕上。前缓冲(front buffer)就是当前显示在屏幕上的内容,这个缓冲是只读的,无法修改。后备缓冲(back buffer)是设备将要绘制的渲染目标,一旦它完成了绘制操作,交换链就会通过交换前缓冲和后备缓冲,将后备缓冲的内容显示在屏幕上,此时后备缓冲就变成了前缓冲。

要创建交换链,我们需要设置一个DXGI_SWAPCHAIN_DESC结构体。

typedef struct DXGI_SWAP_CHAIN_DESC {
  DXGI_MODE_DESC   BufferDesc;
  DXGI_SAMPLE_DESC SampleDesc;
  DXGI_USAGE       BufferUsage;
  UINT             BufferCount;
  HWND             OutputWindow;
  BOOL             Windowed;
  DXGI_SWAP_EFFECT SwapEffect;
  UINT             Flags;
} DXGI_SWAP_CHAIN_DESC;

  结构说明:

(Back)BufferUsage:使用后备缓冲区的方式。将BackBufferUsage设置为DXGI_USAGE_RENDER_TARGET_OUTPUT,表示将绘制到后备缓冲。(描述后台缓存的表面用法和CPU访问设置。后台缓存能使用渲染输入或渲染目标输出)

OutputWindow:表示交换链将使用的窗口,在这个窗口上我们显示图像。

SampleDesc:用来开启多重采样(multi-sampling)。SampleDesc的Count设置为1,Quality设置为0,这样就禁用了多重采样。

扫描二维码关注公众号,回复: 2378014 查看本文章

BufferDesc:一个DXGI_MODE_DESC结构体,用来描述后台缓存显示模式。

BufferCount:这个值用于描述交换链的缓存数量,包含前置缓存。

Windowed:如果值为true将会以窗口模式显示;全屏则为false。

SwapEffect:描述处理目前的缓存和目前的表面的设置。

Flags:描述交换链接行为设置。

设置好DXGI_SWAPCHAIN_DESC结构体后,通过调用  D3D11CreateDeviceAndSwapChaing()  函数来创建一个设备和交换链。

下一步需要创建一个渲染目标视图(render target view)。渲染目标视图是Direct3D 11中一种资源视图(resource view)。资源视图可以让一个资源绑定到图形管线的某个阶段。可以将资源视图看成C中的类型转换,C中的一块原始内存(raw memory)可以被转换为任意数据结构,我们可以将一块内存转换为整数数组,浮点数数组,结构,结构数组等。如果我们不知道原始内存的类型,那么它对我们来说用处不大。Direct3D 11的资源视图工作原理类似,例如一张2D纹理就类似于一块原始内存,就是一种原始基础资源,有了这个原始资源,我们就可以创建不同的资源视图将这个纹理以不同的格式绑定到图形管线的不同阶段,而不同的格式可以是要绘制的渲染目标,接收深度信息的深度模板缓冲,或者也可以是一个纹理资源。C中的类型转换可以以不同方式使用一块内存,而在Direct3D 11中是资源视图进行类似的操作。

因为我们需要将交换链中的后备缓冲绑定为一个渲染目标,所以需要创建一个渲染目标视图,这样Direct3D 11就可以在其上进行绘制了。我们首先调用  GetBuffer()   方法获取后备缓冲对象。我们可以使用一个D3D11_RENDERTARGETVIEW_DESC结构体表示要创建的渲染目标视图,这个结构体通常是CreateRenderTargetView方法的第二个参数。但是,在本教程中,默认的渲染目标视图就能满足需要,所以第二个参数为NULL表示使用默认的渲染目标视图。创建了渲染目标视图后,我们就可以调用   OMSetRenderTargets()  方法将它绑定到图形管线,这样管线的绘制输出被写到了后备缓冲中。创建并设置渲染目标视图的代码如下:

// Create a render target view
ID3D11Texture2D* pBackBuffer;
hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (LPVOID* )&pBackBuffer );
if( FAILED( hr ) )
    returnhr;
 
hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );
pBackBuffer->Release();
if( FAILED( hr ) )
    returnhr;
 
g_pd3dDevice->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );

最后,我们需要初始化视口(viewport)。视口剪裁空间坐标(X和Y的范围从-1到1,Z的范围从0到1)映射到渲染空间(有时又称为像素空间)。在Direct3D 9中,如果程序没有设置视口,会创建一个与渲染目标相同大小的默认视口。在Direct3D 11中,没有默认视口,我们必须事先设定。因为我们想将整个渲染目标输出,所以设置左上点为(0, 0),宽度和高度与渲染目标相同。代码如下:

// 设置视口
D3D11_VIEWPORT vp;
vp.Width = (FLOAT)width;
vp.Height = (FLOAT)height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
g_pImmediateContext->RSSetViewports( 1, &vp );

修改消息循环

创建了窗口和Direct3D 11设备后,就做好了绘制的准备。但是在处理消息循环环节还有一个问题:我们使用的是  GetMessage() 获取消息,使用  GetMessage()  带来的问题是当没有消息可返回给应用程序时,  GetMessage()  会将应用程序置于“睡眠”状态。这样会导致在程序进行绘制时,当消息队列为空时,应用程序会处于等待状态。我们可以使用  PeekMessage()  代替 GetMessage()  来解决这个问题。  PeekMessage()  像 GetMessage()  一样可以接收消息,当没有消息处于等待时,PeekMessage()  会立即返回给应用程序一个FALSE值而不是处于休眠状态。这样我们就可以利用这段时间进行绘制的工作。修改过的消息循环的代码如下:

// Main message loop
MSG msg = {0};
while( WM_QUIT != msg.message )
{
    if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
    else
    {
        Render();
    }
}

绘制

绘制过程是在Render()方法中进行的。要将一种颜色填充渲染目标的简单方法就是使用设备的  ClearRenderTargetView()  方法。我们首先定义一个包含四个浮点数的数组设置要显示的颜色,然后将这个数组传递到  ClearRenderTargetView()  方法中。本例中使用的是蓝色。填充了后备缓冲后,就可以调用交换链的  Present()  方法完成绘制。  Present()  负责将后备缓冲的内容显示在屏幕上。  Render()  方法的代码如下:

void Render()
{
    // Just clear the backbuffer
    floatClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; //red,green,blue,alpha
    g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
    g_pSwapChain->Present( 0, 0 );
}

猜你喜欢

转载自blog.csdn.net/qq_37304699/article/details/81188662