Github-LearnDirectX-DX3D11 tutorial01

概述

在这第一篇教程中,我们将通过介绍创建最小Direct3D应用程序所必需的元素。每一个Direct3D应用程序必需拥有这些元素才能正常地工作。这些元素包括设置窗口和设备对象,以及在窗口上显示颜色。

资源目录

(SDK root)\Samples\C++\Direct3D11\Tutorials\Tutorial01

设置Direct3D 11 设备

第一步是创建一个窗口和消息循环,这些在Direct3D 9, Direct3D 10, 和Direct3D 11都是相同的。有关此过程的介绍,请参阅Direct3D 10教程00:Win 32 Basics。现在我们有了一个正在显示的窗口,我们可以继续设置一个Direct3D 11设备。如果我们将要渲染任何3D场景,设置这个是有必要的。首先要做的是创建三个对象:一个设备(device),一个直接的上下文(immediate context),一个交换链(swap chain)。直接上下文是Direct3d 11中的一个新对象。

在Direct3D 10中,设备对象用于执行渲染和资源的创建。在Direct3D 11中,应用程序使用直接上下文对缓冲区执行渲染,设备中包含创建资源的方法。

交换链负责接收设备渲染的缓冲区,并在实际监视器屏幕上显示内容。交换链包含两个或多个缓冲区,主要是前面和后面。这些纹理是设备为了在监视器上显示而呈现的纹理。前台缓冲区是当前呈现给用户的内容。这个缓冲区是只能读,不能做修改。后台缓冲区是设备将要绘制的渲染目标。一旦设备完成了绘图操作,交换链将通过交换两个缓冲区来显示后台缓冲区。此时后台缓冲区变成了前台缓冲区,反之亦然。

为了创建交换链,我们填写 DXGI_SWAPCHAIN_DESC 结构来描述我们即将创建的交换链。有一些字段值得一提。BackBufferUsage是一个标志,它告诉应用程序如何使用后台缓冲区。 在这种情况下,我们想要渲染到后台缓冲区,因此我们将 BackBufferUsage 设置为 DXGI_USAGE_RENDER_TARGET_OUTPUT。OutputWindow字段表示交换链将用于在屏幕上显示图像的窗口。SampleDesc用于启用多次采样。 由于本教程不使用多次采样,因此SampleDesc的Count设置为1,Quality设置为0以禁用多次采样。

填写完描述后,我们可以调用D3D11CreateDeviceAndSwapChain函数为我们创建设备和交换链。以下是创建设备和交换链的代码:

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

  

接下来我们要做的事情是创建一个渲染目标的视图。

渲染目标视图是Direct3D 11里的一种资源视图。资源视图允许资源在特定场合绑定到图形管道上。将资源视图看成是C语言中的类型转换。C中的一块原始内存可以转换为任何数据类型。我们可以将这块内存转换为整数数组,浮点数组,结构数组,结构数组等等。如果我们不知道它的类型,原始内存本身对我们没有太大用处。Direct3D 11中的资源视图与该方法类似。例如,一个2D纹理,类似于原始内存块,是原始的底层资源。一旦我们拥有了该资源,我们就可以创建不同的资源视图,将该纹理绑定到不同格式的图形管道中的不同阶段:作为要渲染的渲染目标,作为将接收深度信息的深度模板缓冲区,或作为纹理资源。在C语言类型转换中允许以不同的方式使用内存块的情况下,Direct3D 11资源视图也是如此。

我们需要创建一个渲染目标视图,因为我们想将交换链中的后台缓冲区绑定为我们的渲染目标。这样能够使Direct3D 11渲染到它上面。我们首先调用GetBuffer()来获取后台缓冲区对象。或者,我们可以填写D3D11_RENDERTARGETVIEW_DESC结构,该结构描述要创建的渲染目标视图。此描述通常是CreateRenderTargetView的第二个参数。然而,对于这些教程,默认的渲染目标视图已经足够了。可以通过传递NULL作为第二个参数来获取默认的渲染目标视图。一旦我们创建了渲染目标视图,我们就可以在直接上下文中调用OMSetRenderTargets()来将它绑定到管道上。这可确保管道呈现的输出被写入后台缓冲区。创建和设置渲染目标视图的代码如下:

 // Create a render target 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渲染之前我们需要设置的最后一件事是初始化视口。

视口映射剪辑空间坐标,其中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()会阻塞,并且在消息可用之前不会返回。因此,当消息队列为空时,我们的应用程序在GetMessage()内等待,而不是像渲染那样。我们可以使用PeekMessage()而不是GetMessage()来解决这个问题。 PeekMessage()可以检索像GetMessage()那样的消息,但是当没有消息等待时,PeekMessage()会立即返回而不是阻塞。 然后我们可以花时间做一些渲染。 使用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中,使用单一颜色填充渲染目标的简单方法是使用直接上下文的ClearRenderTargetView()方法。

  • 首先,我们定义一个由四个浮点数组成的数组,用于描述我们想要填充屏幕的颜色。
  • 接着,我们将它传递给ClearRenderTargetView()。在这个例子中,我们选择了蓝色的阴影。
  • 填充后台缓冲区后,我们调用交换链的Present()方法来完成渲染。 Present()负责将交换链的后台缓冲区内容显示在屏幕上,以便用户可以看到它。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 );
}

  

本教程最终的运行效果:

小结

本教程是我在学习DirectX中查看SDK文档中看到的,因此想在国庆期间翻译成中文,方便以后查阅。

教程总共有七篇:

希望翻译过的教程能对学习DX的朋友们有所帮助,本教程的源码我已上传至Github(在本文首部)。

Direct3D 11 Tutorial 1: Basics_Direct3D 11 教程1:基础的更多相关文章

  1. Direct3D 11 Tutorial 6:Lighting_Direct3D 11 教程6:灯光

    概述 在之前的教程中,世界看起来很无聊,因为所有对象都以相同的方式点亮. 本教程将介绍简单照明的概念及其应用方法. 使用的技术将是朗伯照明. 本教程的结果将修改前面的示例以包含光源. 该光源将附在轨道 ...

  2. Java 11 Tutorial

    Java 11 Tutorial 参考 https://blog.csdn.net/sihai12345/article/details/82889827 原文 https://winterbe.co ...

  3. 【转】正则表达式简介及在C++11中的简单使用教程

    正则表达式Regex(regular expression)是一种强大的描述字符序列的工具.在许多语言中都存在着正则表达式,C++11中也将正则表达式纳入了新标准的一部分,不仅如此,它还支持了6种不同 ...

  4. Gitlab 11.9.1 高可用教程

    Gitlab 11.9.1 高可用教程 一. PostgreSQL数据迁移 由于默认Gitlab的安装会内置Postgres数据库,并且没有对外,所以我们需要通过设置对应的Gitlab的配置将其中的数 ...

  5. MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.7 Adding a wms layer

    MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.7 Adding a wms layer 前言 Add OGC WMS Layers( ...

  6. MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.6 Defining Projections and Extents

    MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.6 Defining Projections and Extents 一.前言 当在m ...

  7. MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.3 Displaying Classes in a Layer

    MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.3 Displaying Classes in a Layer 一.前言 关于第一节的 ...

  8. PSU 离11.2.0.3.0 -> 11.2.0.3.11 如果解决冲突的整个

    Oracle rdbms 扑灭psu离11.2.0.3.0升级到11.2.0.3.11 参考patch :18522512 停止应用,停止听音乐并DB,将db的oracle_home在下面OPatch ...

  9. Oracle DataGuard 升级 [11.2.0.1 -> 11.2.0.4]

    Oracle DataGuard 升级 [11.2.0.1 -> 11.2.0.4] Primary: 11.2.0.1 单机,Site A. Standby: 11.2.0.1 单机,Site ...

随机推荐

  1. 安装完最小化 RHEL/CentOS 7 后需要做的 30 件事情7. 安装 PHP PHP 是用于 web 基础服务的服务器端脚本语言。它也经常被用作通用编程语言。在最小化安装的 CentOS 中安

    CentOS 是一个工业标准的 Linux 发行版,是红帽企业版 Linux 的衍生版本.你安装完后马上就可以使用,但是为了更好地使用你的系统,你需要进行一些升级.安装新的软件包.配置特定服务和应用程 ...

  2. 双向BFS—>NOIP2002 字串变换

    如果目标也已知的话,用双向BFS能很大提高速度 单向时,是 b^len的扩展. 双向的话,2*b^(len/2)  快了很多,特别是分支因子b较大时 至于实现上,网上有些做法是用两个队列,交替节点搜索 ...

  3. CodeForce VKcup B

    题目描述:给了n个单词和m,还有一堆YES和NO表示在序列1-m,2-(m+1),3-(m+2)......中是否存在重复的单词,没重复的是YES,有重复的是NO 题目链接:点我 如果是NO的话,就使 ...

  4. 【map离散&容斥】Ghosts @Codeforces Round #478 (Div. 2) D

    传送门 题意:给你一条直线的斜率a和截距b,和某一时刻n个在直线上的点的横坐标,以及沿坐标轴方向的速度.问你这些点在(-∞,+∞)的时间内的碰撞次数. solution 设两个点在t时刻相碰,有: x ...

  5. poj2229 Sumsets (递推)

    http://poj.org/problem?id=2229 看到题目能感觉到多半是动态规划,但是没有清晰的思路. 打表找规律: #include<cstdio> #include< ...

  6. 【转】SQL Server 事务隔离级别详解

    SQL 事务隔离级别 概述 隔离级别用于决定如果控制并发用户如何读写数据的操作,同时对性能也有一定的影响作用. 步骤 事务隔离级别通过影响读操作来间接地影响写操作:可以在回话级别上设置事务隔离级别也可 ...

  7. Vue 2.3、2.4 知识点小结

    2.3 style 多重值: <div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }">< ...

  8. ELK架构设计

    1.架构一 2.架构二 3.架构三 4.架构四 示例1: 示例二: ELKB简述 E:Elasticsearch 是一个基于Lucene的分布式搜索和分析引擎,具有高可伸缩.高可靠和易管理等特点.支持 ...

  9. [DevExpress使用随笔]之NavBarControl控件(一)【转】

    https://blog.csdn.net/HXC_HUANG/article/details/78614092 NavBarControl是具有可扩展组的侧导航控件.一.在Winform窗口中拖入N ...

  10. js格式化格林威治时间

    格式化时间:Sat Aug 05 00:00:00 CST 2017 function fermitTime(time){ var now = new Date(time); var year = n ...