DirectX11 With Windows SDK--00 目录

前言 (更新于 2020/6/15)

从第一次接触DirectX 11到现在已经有将近三年的时间了。记得当初学习DirectX 11,在用龙书的源码配置项目运行环境的时候都花了好几天的时间才搞定,又因为书中的代码的开发环境(VS 2010)与现在的情况有些冲突,还得忍受上千个无法避免的编译警告,不得不视警告为无物。而且里面的代码使用了Microsoft DirectX SDK(June 2010)开发包和里面的Effects 11框架,这些东西都已经是将近10年前的产物了。

后面到18年5月的时候,我先是在Github上翻到了微软对FX11(原Effects11)库一直都还在更新,然后发现了DirectX Tool KitDirectX SDK Samples,里面提供的教程写法和龙书的做法不一样。我才明白,微软其实已经将DirectX的相关组件随同Windows SDK一起更新。而我现在使用的是Visual Studio 2019 Community,里面就已经包含了Windows SDK。经过一段时间的文档和样例阅读后,决定尝试编写一个全新的教程尽可能地摆脱DirectX SDK的束缚。

但是在转移的时候也遇到了很多需要解决的问题,比如:

  1. 没有了诸如d3dx11.h, xnamath.h, dxerr.h, xnacollision.h等这些老旧的头文件
  2. 使用新的Effects 11框架的话引发编译器警告:X4717: Effects deprecated for D3DCompiler_47,提示Effects11未来可能不受D3DCompiler的支持
  3. 着色器需要手工进行管理,并且HLSL的写法上和FX有些差异(比如Sampler不能在HLSL中直接定义)
  4. 龙书11的示例代码有关Effects 11的部分基本上还得靠自己重新编写

这些问题都可以下面的教程中找到对应的解决/替代方案,在这里就不一一列举了。

知识储备

十分重要!由于该文章系列注重的是项目实践,并不是面向零基础的初学者。在学习本教程之前需要:

  1. 熟悉C++及面向对象编程,最好是了解C++11,并且能熟练使用指针、数组等内容熟悉Visual Studio的使用,有一定的项目开发经验。推荐阅读《C++ Primer》一书。

  2. 了解Win32 API,但窗口初始化不是本教程的重点,这部分内容自行了解即可。

  3. 对线性代数和3D数学基础有所掌握,推荐阅读《3D数学基础》一书。本教程只会花有限的篇幅进行讲解。

  4. 了解渲染管线基础,可以阅读过龙书11的第4章到第5章,用过游戏引擎进行开发,又或者是之前学过DirectX9/11 或 OpenGL

教程与项目特点

本教程与项目的特点如下:

  1. 完全脱离对DirectX SDK的依赖,下载项目编译后即可运行,并且兼容Win7-Win10平台
  2. 使用原生的HLSL编译器,并且不依赖于FX11(Effects)框架和fx5.0,虽然对实现细节要求更高了,但能够对底层实现有更加深入的了解
  3. 对Direct3D 11的一系列API有较为详细的讲解
  4. 代码尽可能地不使用高级C++特性(如模板元),以降低阅读源码带来的难度。并且项目内会有一些编写好的小模块,一定程度上降低代码编写的难度
  5. 各个项目都是独立的,没有依赖项,以降低它们的复杂度

尽管这边提供了大量的学习Demo,但还是鼓励大家边学习边自己编写代码,多动手实践,只有踩过的坑才是你自己的。此外项目并不是以追求极致效率为目的,这些事情还是在能够熟练使用Direct3D API的时候再考虑。

降低学习难度

如何让你的DirectX 11学习之路更为平坦?在此我给出几点调试相关的建议:

  1. 时间充裕者优先考虑补足知识储备再来学习DirectX 11
  2. 没学会单步调试、断点调试的一定要先去学会。
  3. **在调试程序的时候一定要留意输出窗口(来源为调试),一些D3D相关的函数运行失败都会在这里有十分详细的反馈。**了解这个可以省去你很多开发的时间,避免不必要的查找,这一点十分重要!
  4. 学会使用Visual Studio自带的图形调试器,这是必修知识。一定要能够区分开普通调试(CPU)图形调试(GPU)
  5. 善于利用一些函数返回的HRESULT类型错误码,可以使用我这边的DXTrace库来了解错误码的具体含义,也可以使用DirectX SDK中的Utilities\bin\x86\DXErr.exe来查询

下面是一个尝试使用显示适配器创建D3D设备引发的错误:


注意:
1. 考虑到现在DXTK库只是用到了它里面的键鼠类和纹理加载,现在已经单独提取出来使用,读者不需要过于关注这部分内容的实现细节。
2. 现在某些章节会有一些练习题,除了龙书里面有的部分进行挑选外,自己也尝试出了一些题目。但是题目并不会给出答案(大多数实现方法都并不唯一)
3. 本教程并不能代表Direct3D的方方面面,务必要善于利用下面参考资料中给予的MSDN文档来查询信息,培养自己的文档阅读能力。
4.教程的阅读顺序从入门篇开始,但需要先阅读里面提到的前置章节。对于进阶篇及高级篇的内容,你不必全部掌握,按需学习。
5.如果你只是单纯为了做一款游戏,那么学习使用Unity 3D来开发可能会更适合您。

项目下载

在开始教程之前务必下载一份源码,教程中的源码不会给全,只是根据实际需要进行展开说明。同时也希望能进去点个Star支持一下

GitHub项目浏览与下载
GitHub watchersGitHub starsGitHub forks
欢迎加入QQ群: 727623616 可以一起探讨DX11,以及有什么问题也可以在这里汇报。

项目概述

语言:
-C++11和少量C++14
-HLSL Shader Model 5.0

目前所有项目无需依赖第三方库的编译,而是从微软官方项目中提取了下述模块到项目中:
DirectXTex/DDSTextureLoader
DirectXTex/WICTextureLoader
DirectXTex/ScreenGrab
DXTK/Mouse(源码上有所修改)
DXTK/Keyboard(源码上有所修改)

教程需求与配置表

IDEVS2019VS2017VS2015
D3DComplier版本474747
Windows SDK版本10.0 (最新安装的版本)10.0.17763.010.0.14393.0
Windows开发/运行环境Windows 10Windows 10Windows 7 SP1及更高版本
平台x86/x64支持x86/x64支持x86/x64支持
配置Debug/Release支持Debug/Release支持Debug/Release支持

注意:

  1. 教程不支持VS2013及更低版本!
  2. VS2015在安装时需要勾选VS2015 更新 3, 以及Tools(1.4.1)和Windows 10 SDK(10.0.14393)
  3. Win7系统需要安装Service Pack 1以及KB2670838补丁以支持Direct3D 11.1

博客和项目维护不易,目前教程和项目仅由作者一人维持,精力有限。如果本系列教程对你有所帮助,希望能够扫码支持一下博主。

目录

杂项篇(优先度从高到低)

目录
教程项目无法编译、运行的解决方法
HLSL语法入门
HR宏关于dxerr库的替代方案
ComPtr智能指针
HLSL编译着色器的三种方法
Visual Studio图形调试器详细使用教程(基于DirectX11)
深入理解HLSL常量缓冲区打包规则
HLSL中矩阵的内存布局和mul函数探讨
深入理解与使用2D纹理资源
深入理解与使用缓冲区资源

实战篇

目录
实现一个3D魔方(1)
实现一个3D魔方(2)
实现一个3D魔方(3)

入门篇

目录
01 DirectX11初始化
02 顶点/像素着色器的创建、顶点缓冲区
03 索引缓冲区、常量缓冲区
04 变换
05 DirectXMath数学库
06 键盘和鼠标输入
07 添加光照与常用几何模型、光栅化状态
08 Direct2D与Direct3D互操作性以及利用DWrite显示文字
09 纹理映射与采样器状态
10 摄像机类

进阶篇

目录
11 混合状态
12 深度/模板状态
13 动手实现一个简易Effects框架、阴影效果绘制
14 深度测试
15 几何着色器初探
16 流输出阶段
17 利用几何着色器实现公告板效果
18 使用DirectXCollision库进行碰撞检测
19 模型加载:obj格式的读取及使用二进制文件提升读取效率
20 硬件实例化与视锥体裁剪
21 鼠标拾取
22 立方体映射:静态天空盒的读取与实现
23 立方体映射:动态天空盒的实现
24 Render-To-Texture(RTT)技术的应用、使用ScreenGrab保存纹理到文件
25 法线贴图

高级篇

目录
26 计算着色器:入门
27 计算着色器:双调排序
28 计算着色器:波浪(水波)
29 计算着色器:内存模型、线程同步;实现顺序无关透明度(OIT)
30 计算着色器:高斯模糊、索贝尔算子
31 阴影映射
32 SSAO(屏幕空间环境光遮蔽)
33 曲面细分阶段(Tessellation)
34 位移贴图
35 粒子系统
36 延迟渲染基础

参考资料

MSDN文档,同时推荐大家收藏以随时查阅:

Direct3D 11 Graphics API(Windows SDK)

Direct3D 11 Graphics(Windows SDK)

DXGI API(Windows SDK)

DXGI(Windows SDK)

DirectXMath

HLSL

参考到的一些网站:

DirectX SDK Samples

Rastertek–DX11

DirectX Tool Kit

Windows SDK

DirectXMath

DirectXTex

龙书网站

DXUT

参考书籍:

Introduction to 3D Game Programming with DirectX 11

Practical Rendering and Computation with Direct3D 11

Mathematics for 3D Game Programming and Computer Graphics, Third Edition

DirectX12 3D游戏开发实战

后记(更新于2022/3/5)

这个博客系列断断续续写了快4年的时间,中间经历了太多太多的事情,而且还要准备考研,当然现在也已经上岸了。**现在的初步打算是会继续出下去。**感谢大家对本项目和教程的支持。一开始只是想着告诉人怎么过渡到Windows SDK版的DX,然后初期的代码基本上就是DirectX-SDK-Samples跟龙书的缝合框架。写到后面有什么好的想法还可能要经常回头改代码,当然这些代码只有在自己实现一遍的时候才会感触良深,受益匪浅。再后来就是认识到了更多的dl,也感受到自己还有很多很多不懂的东西。当然,理论上如果你能看完整个博客系列,你就对Direct3D 11的主线知识基本上都了解的差不多了,对于那些比较边缘的知识此时读者应当有能力自己去根据需要来探寻。这里自问自答几个问题:

  • 为什么不讲多线程渲染?我认为如果要学多线程渲染的话,还不如留到学DX12的时候学会更好一些。
  • 骨骼动画、Assimp、ImGui怎么鸽了?最主要的问题是我一直都在克制自己,不给这个系列项目引入第三方的代码,如果引入了势必会对后续的更新带来麻烦。 自从用了cmake之后,好像配置起来也没那么麻烦了,当然还是会尽量克制一些的。能跟我教程这么久的读者我觉得应该也有能力去自己尝试加入一些外面的东西了吧。

现在要考虑的问题是接下来学什么?下面是一些可以尝试的内容:

  • 30
    点赞
  • 102
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
以下是使用Windows SDKDirectX SDK来构建dxgi截屏的步骤: 1. 安装Windows SDKDirectX SDK 2. 创建工程,并将以下头文件包含进来: ``` #include <d3d11.h> #include <dxgi1_2.h> #include <iostream> #include <fstream> #include <vector> #include <string> ``` 3. 创建一个D3D11设备和设备上下文: ``` D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0; D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &m_pd3dDevice, NULL, &m_pd3dDeviceContext); ``` 4. 获取DXGI设备: ``` IDXGIDevice* pDXGIDevice; m_pd3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&pDXGIDevice); ``` 5. 获取DXGI适配器: ``` IDXGIAdapter* pDXGIAdapter; pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&pDXGIAdapter); ``` 6. 获取DXGI工厂: ``` IDXGIFactory* pIDXGIFactory; pDXGIAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&pIDXGIFactory); ``` 7. 枚举所有显示器: ``` std::vector<IDXGIOutput*> arrOutputs; IDXGIOutput* pOutput; for (int i = 0; pIDXGIFactory->EnumOutputs(i, &pOutput) != DXGI_ERROR_NOT_FOUND; ++i) { arrOutputs.push_back(pOutput); } ``` 8. 获取输出的描述: ``` DXGI_OUTPUT_DESC outputDesc; arrOutputs[0]->GetDesc(&outputDesc); ``` 9. 获取DXGI输出: ``` IDXGIOutput1* pDXGIOutput1; arrOutputs[0]->QueryInterface(__uuidof(IDXGIOutput1), (void**)&pDXGIOutput1); ``` 10. 获取桌面信息: ``` DXGI_OUTDUPL_DESC outputDuplDesc; pDXGIOutput1->DuplicateOutput(m_pd3dDevice, &outputDuplDesc); ``` 11. 创建DXGI资源: ``` ID3D11Texture2D* pTexture; D3D11_TEXTURE2D_DESC desc; desc.Width = outputDuplDesc.ModeDesc.Width; desc.Height = outputDuplDesc.ModeDesc.Height; desc.Format = outputDuplDesc.ModeDesc.Format; desc.ArraySize = 1; desc.BindFlags = D3D11_BIND_FLAG::D3D11_BIND_RENDER_TARGET; desc.Usage = D3D11_USAGE::D3D11_USAGE_DEFAULT; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.MipLevels = 1; desc.CPUAccessFlags = 0; desc.MiscFlags = 0; m_pd3dDevice->CreateTexture2D(&desc, NULL, &pTexture); ``` 12. 创建渲染目标视图: ``` ID3D11RenderTargetView* pRenderTargetView; m_pd3dDevice->CreateRenderTargetView(pTexture, NULL, &pRenderTargetView); ``` 13. 设置渲染目标: ``` m_pd3dDeviceContext->OMSetRenderTargets(1, &pRenderTargetView, NULL); ``` 14. 渲染: ``` m_pd3dDeviceContext->ClearRenderTargetView(pRenderTargetView, DirectX::Colors::Black); m_pd3dDeviceContext->Draw(3, 0); ``` 15. 保存截屏: ``` D3D11_TEXTURE2D_DESC desc; pTexture->GetDesc(&desc); D3D11_MAPPED_SUBRESOURCE mappedResource; m_pd3dDeviceContext->Map(pTexture, 0, D3D11_MAP_READ, 0, &mappedResource); std::ofstream ofs("screenshot.bmp", std::ios::binary); const uint8_t* src = (const uint8_t*)mappedResource.pData; for (int y = 0; y < desc.Height; ++y) { const uint8_t* row = src + mappedResource.RowPitch * y; for (int x = 0; x < desc.Width; ++x) { const uint8_t* pixel = row + x * 4; ofs.put(pixel[2]); ofs.put(pixel[1]); ofs.put(pixel[0]); } } m_pd3dDeviceContext->Unmap(pTexture, 0); ofs.close(); ``` 以上就是使用Windows SDKDirectX SDK来构建dxgi截屏的步骤。需要注意的是,如果您正在使用Windows 10或更高版本,则可以使用Windows.Graphics.Capture命名空间来实现更简单的截屏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值