(SDK root)SamplesC++Direct3D11TutorialsTutorial01
第一步是创建一个窗口和消息循环,这些在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函数为我们创建设备和交换链。以下是创建设备和交换链的代码:
接下来我们要做的事情是创建一个渲染目标的视图。
渲染目标视图是Direct3D 11里的一种资源视图。资源视图允许资源在特定场合绑定到图形管道上。将资源视图看成是C语言中的类型转换。C中的一块原始内存可以转换为任何数据类型。我们可以将这块内存转换为整数数组,浮点数组,结构数组,结构数组等等。如果我们不知道它的类型,原始内存本身对我们没有太大用处。Direct3D 11中的资源视图与该方法类似。例如,一个2D纹理,类似于原始内存块,是原始的底层资源。一旦我们拥有了该资源,我们就可以创建不同的资源视图,将该纹理绑定到不同格式的图形管道中的不同阶段:作为要渲染的渲染目标,作为将接收深度信息的深度模板缓冲区,或作为纹理资源。在C语言类型转换中允许以不同的方式使用内存块的情况下,Direct3D 11资源视图也是如此。
我们需要创建一个渲染目标视图,因为我们想将交换链中的后台缓冲区绑定为我们的渲染目标。这样能够使Direct3D 11渲染到它上面。我们首先调用GetBuffer()来获取后台缓冲区对象。或者,我们可以填写D3D11_RENDERTARGETVIEW_DESC结构,该结构描述要创建的渲染目标视图。此描述通常是CreateRenderTargetView的第二个参数。然而,对于这些教程,默认的渲染目标视图已经足够了。可以通过传递NULL作为第二个参数来获取默认的渲染目标视图。一旦我们创建了渲染目标视图,我们就可以在直接上下文中调用OMSetRenderTargets()来将它绑定到管道上。这可确保管道呈现的输出被写入后台缓冲区。创建和设置渲染目标视图的代码如下:
在Direct3D 11渲染之前我们需要设置的最后一件事是初始化视口。
视口映射剪辑空间坐标,其中X和Y的范围为-1到1,Z的范围为0到1,以渲染目标空间,有时称为像素空间。 在Direct3D 9中,如果应用程序未设置视口,则默认视口设置为与渲染目标的大小相同。在Direct3D 11中,默认情况下不设置视口。 因此,我们必须在屏幕上看到任何内容之前这样做。由于我们希望将整个渲染目标用于输出,因此我们将左上角的点设置为(0,0),将宽度和高度设置为与渲染目标的大小相同。 为此,请使用以下代码:
我们已经设置了窗口和Direct3D 11设备并且我们已准备好渲染。 但是,我们的消息循环仍然存在问题:它使用GetMessage()来获取消息。GetMessage()的问题在于,如果应用程序窗口的队列中没有消息,则GetMessage()会阻塞,并且在消息可用之前不会返回。因此,当消息队列为空时,我们的应用程序在GetMessage()内等待,而不是像渲染那样。我们可以使用PeekMessage()而不是GetMessage()来解决这个问题。 PeekMessage()可以检索像GetMessage()那样的消息,但是当没有消息等待时,PeekMessage()会立即返回而不是阻塞。 然后我们可以花时间做一些渲染。 使用PeekMessage()的修改后的消息循环如下所示:
渲染在Render()函数中完成。
在这个教程中,我们将渲染最简单的场景,即用单一颜色填充屏幕。在Direct3D 11中,使用单一颜色填充渲染目标的简单方法是使用直接上下文的ClearRenderTargetView()方法。
- 首先,我们定义一个由四个浮点数组成的数组,用于描述我们想要填充屏幕的颜色。
- 接着,我们将它传递给ClearRenderTargetView()。在这个例子中,我们选择了蓝色的阴影。
- 填充后台缓冲区后,我们调用交换链的Present()方法来完成渲染。 Present()负责将交换链的后台缓冲区内容显示在屏幕上,以便用户可以看到它。Render()函数看起来像是这样的:
本教程最终的运行效果:
本教程是我在学习DirectX中查看SDK文档中看到的,因此想在国庆期间翻译成中文,方便以后查阅。
教程总共有七篇:
希望翻译过的教程能对学习DX的朋友们有所帮助,本教程的源码我已上传至Github(在本文首部)。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/java-jiao-cheng/17362.html