【DirectX 11 SDK 学习笔记】Direct3D 11 Basics
来源:互联网 发布:中房网端口能不能退 编辑:程序博客网 时间:2024/06/05 11:31
在这个例子中,将要学习创建一个最小的Direct3D应用的基本元素,这些都是基本的功能属性,包括建立一个窗口和device对象,并且在窗口上显示颜色。
建立window:参见上例。
建立Direct3D11 device
创建窗口和消息循环的初始步骤在Direct3D9,Direct3D10,和Direct3D11中都是一样的。
目前,我们有一个可以显示的window了,能够继续创建Direct3D11 device。如果我们要进行渲染,这一步是必须的。
第一步就是创建3个对象:
1.adevice
2.animmediatecontext
3.a swapchain
其中,immediate context是Direct3D 11 中新加的对象。
在Direct10中,device对象被用来执行渲染和创建资源。在DirectX11中,这个程序通常通过immediatecontext来执行buffer上的渲染,而且,device中含有很多用来创建资源的函数。swap chain负责将buff数据传送到设备渲染器,而且将内容显示在真正的显示器屏幕上面。
通常swap chain包含两个或两个以上的buffer,其中最主要和最重要的是front buffer和back buffer,里面存放的是设备渲染器要按顺序渲染到屏幕上的纹理数据。front buff是正在呈现给用户的数据,就是看见的每一帧哦~而且这个front buffer是只读,不能被修改。back buff是device绘图的渲染目标,一旦完成绘图操作,swap chain将交换这两个buffer,back buffer变成front buffer,然后将交换后的front buffer呈现给用户。
如果要创建swap chain,我们首先要填充DXGI_SWAPCHAIN_DESC 结构体,这个结构体是用来描述我们所创建的swap chain,这里有几个值得注意的地方:
BackBufferUsage这个标记告诉应用back buffer将如何使用,如果我们想要渲染back buffer,在这种情况下,我们将这个标记设置为DXGI_USAGE_RENDER_TARGET_OUTPUT
OutputWindow表示swap chain将用来显示图像到屏幕上的窗口。
SampleDesc 用来开启multi-sampling。由于本例没有使用multi-sampling,所以SampleDesc.Count=1SampleDesc.Quality= 0 将multi-sampling功能关闭。
一旦DXGI_SWAPCHAIN_DESC结构体填充完成,我们可以调用D3D11CreateDeviceAndSwapChain函数来创建device和swap chain。下面是创建代码:
DXGI_SWAP_CHAIN_DESCsd;
ZeroMemory( &sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = 640;
sd.BufferDesc.Height =480;
sd.BufferDesc.Format =DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator =60;
sd.BufferDesc.RefreshRate.Denominator= 1;
sd.BufferUsage =DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = g_hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
if(FAILED( D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,featureLevels, numFeatureLevels,D3D11_SDK_VERSION, &sd, &g_pSwapChain
,&g_pd3dDevice, NULL, &g_pImmediateContext ) ) )
{
return FALSE;
}
接下来,我们需要创建render target view。它是Direct3D 11中resource view的一种。Resource view能够让 resource绑定在图形管线上的特定阶段。假若 resource view是C类型,一块在C类型的内存空间中的raw memory能够被转化为任何数据类型,整型数组,浮点数组,结构体,结构体数组等等。如果我们不知道raw memory的类型,它对于我们其实没什么用。Direct3D11 resource也是类似这样来转换的。例如,一个2D texture,类似于一个rawmemory,是原始底层资源,一旦我们拥有了这样的资源,我们可以创建不同的 resource view来绑定这个texture到不同的渲染管线阶段,将texture转换为不同的格式:作为将要渲染的render target,转换为能接受深度信息的depth stencil buffer ,或者作为texture resource,正如C类型能够允许memory chunk通过不同的方式来使用,Direct3D 11 resource views也是一样。
之所以我们要创建render target view,是因为我们想将swap chain的back buffer作为渲染目标。这样能够允许 Direct3D 11 在之上进行渲染。首先,我们通过调用GetBuffer()来得到back buffer对象,也可以通过填充D3D11_RENDERTARGETVIEW_DESC来描述将要创建的targetview。通常是CreateRenderTargetView的第二个参数。然而,对于这些教程,使用默认的target view就可以满足需求了,可以通过传递NULL参数来获得默认 target view。若我们已经创建了render target view,我们可以通过immediatecontext接口调用OMSetRenderTargets()来将它绑定到pipeline.这样能够保证pipeline的渲染输出能够写入到back buffer。
下面是创建和设置render target view的代码:
// Create a rendertarget view
ID3D11Texture2D*pBackBuffer;
if( FAILED(g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ),(LPVOID*)&pBackBuffer ) ) )
return FALSE;
hr =g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL,&g_pRenderTargetView );
pBackBuffer->Release();
if( FAILED( hr ) )
return FALSE;
g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView,NULL );
direct3d 11 能够渲染之前,我们还需要做最后一件事情,就是初始化viewport。viewport映射到空间坐标的时候,x和y的范围从-1到1,z范围从0到1,为了渲染一个目标空间,像总所周知的像素空间。在Direct3D 9中,如果应用程序没有建立viewport,将会创建一个和render target尺寸一样的默认viewport。在Direct3D11中,没有默认的viewpoint。所以,在我们能够看到屏幕上的任何东西之前,我们要创建一个viewport。假若我们想要渲染全部输出窗口,我们可以将左上角设置为 (0 , 0),长和宽设置和渲染目标一致。示例代码如下:
D3D11_VIEWPORTvp;
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 device,而且我们已经准备好渲染了,但是消息循环还有一个问题,它用GetMessage()来获取消息,这个函数的问题在于应用程序窗口队列里面没有消息,会一直阻塞不返回,直到有可以获取的消息出现。所以,如果我们的消息队列是空的,我们的程序会一直等待消息,而不是执行渲染动作。解决方法很简单,只需要用PeekMessage()代替GetMessage()。PeekMessage()具有和GetMessage()一样检索消息功能,但是不会等待消息,PeekMessage()会立即返回结果而不是像GetMessage()会阻塞。我们可以把这点时间利用起来进行渲染。修改后的消息队列,使用PeekMessage()看起来是这样的:
MSG msg = {0};
while( WM_QUIT != msg.message)
{
if( PeekMessage( &msg, NULL,0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg);
DispatchMessage( &msg);
}
else
{
Render(); // Do some rendering
}
}
渲染代码:
本例中的渲染代码是在Render()函数中调用执行的,渲染最简单的场景,只是将屏幕填充为单一颜色。在Direct3D 11 中,有一个简单的方法来用单色填充渲染目标,就是调用immediate context接口中的ClearRenderTargetView()方法。首先,我们定义一个四个float的数组来描述我们要填充到屏幕的颜色,接下来就是将它传递给ClearRenderTargetView()。在这个例子中,我们选择了一个暗蓝色,一旦我们填充好了back buffer,我们可以调用swap chain的Present()函数来结束渲染。Present()负责将swap chain的 backbuffer的内容呈现到屏幕上,这样,用户就能看见了。
Render()是长这个样子的:
void Render()
{
//
// Clear the backbuffer
//
float ClearColor[4] = { 0.0f,0.125f, 0.6f, 1.0f }; // RGBA
g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor);
g_pSwapChain->Present( 0, 0);
}
编码调试:
缺少头文件和lib库:
解决方法:
1.include头文件和lib目录
2.加入依赖库
d3d11.lib
d3dcompiler.lib
d3dx11d.lib
dxerr.lib
dxguid.lib
运行效果:
程序流程:
1.进入wWinMain函数
2.调用InitWindow函数,初始化窗口,在该函数中调用主要的RegisterClassEx,CreateWindow和ShowWindow函数,将生成的hwnd保存在 g_hWnd中。通过wcex.lpfnWndProc = WndProc;来指定函数WndProc为窗口过程函数。由于windows的程序流程很复杂,在初始化的时候无法跟踪,只能大致了解流程,这些是windows比较底层核心的流程.可以跳过.
3.设置的断点特别注意一定要在ShowWindow处设置断点,否则会看不清流程。
执行流程:
先进入wWinMain函数,执行其中的InitWindow,然后跳回来执行InitDevice,然后进入修改过的消息循环,可以看到不停的PeekMessage,当队列为空的时候,执行Render();
- 【DirectX 11 SDK 学习笔记】Direct3D 11 Basics
- Lesson 13: SDK文档:Tutorial 1 Direct3D 11 Basics分析
- DirectX 11游戏编程学习笔记之5: 第4章Direct3D Initialization(Direct3D初始化)
- Tutorial 1: Direct3D 11 Basics
- DirectX 11游戏编程学习笔记之8: 第6章Drawing in Direct3D(在Direct3D中绘制)(习题解答)
- Introduction to 3D Game Programming with DirectX 11学习笔记 4.1 初识Direct3D
- Introduction to 3D Game Programming with DirectX 11学习笔记 4.2Direct3D进行初始化
- Tutorial 1: Direct3D 10 Basics(Directx手册)
- 【DirectX 11 SDK 学习笔记】set up window
- 【DirectX 11 SDK 学习笔记】 Rendering a Triangle
- 【DirectX 11 SDK 学习笔记】Shaders and Effect System
- 【DirectX 11 SDK 学习笔记】3D Spaces
- 【DirectX 11 SDK 学习笔记】3D Transformation
- DirectX 11游戏编程学习笔记之7: 第6章Drawing in Direct3D(在Direct3D中绘制)(重点回顾+勘误)
- Introduction to 3D Game Programming with DirectX 11学习笔记 6 Direct3D中的绘制(一)
- Introduction to 3D Game Programming with DirectX 11学习笔记 6 Direct3D中的绘制(二)顶点着色器
- Introduction to 3D Game Programming with DirectX 11学习笔记 6 Direct3D中的绘制(三)像素着色器
- Introduction to 3D Game Programming with DirectX 11学习笔记 6 Direct3D中的绘制(四)渲染状态
- POJ 3017 单调队列dp
- SDUT 2174回文时间
- 分析cocos2d-x的lua项目中的工具方法
- 匿名函数的语法与使用
- 玩转互联网—创业之路源远长,有得有失有所成——成佩涛(cpthack)
- 【DirectX 11 SDK 学习笔记】Direct3D 11 Basics
- 写程序很难之logstash之file input插件实现分析
- MySql 新建用户,授权,删除用户,修改密码
- 集合
- Flume日志收集
- 【DirectX 11 SDK 学习笔记】 Rendering a Triangle
- IO流
- ORACLE 的函数
- android nice tools