由于个人觉得龙书里面第4章提供嘚Direct3D 初始化sdk是什么项目封装得比较好而且DirectX SDK Samples里面的初始化sdk是什么程序过于精简,不适合后续使用故选择了以Init Direct3D项目作为框架,然后还使用了微软提供的示例项目两者结合到一起。建议下载项目配合阅读
这一章内容大部分属于龙书的内容,但仍有一些不同的地方因为后续嘚所有项目都使用该基础框架,你也可以直接使用第一章的项目源码然后需要了解以下差异部分:
其中前面两个部分在下面的链接可以看到:
欢迎加入QQ群: 可以一起探讨DX11,以及有什么问题也可以在这里汇报
如果你打算从VS2015开始,则在安装的时候需要勾选下列选项:
編程语言那一项会自动被勾选
而如果是使用VS2017或19的话,则在安装的时候需要勾选下列选项:
安装完成后新建项目需要从空项目开始。
如果你曾经用过DX SDK来编写DX项目务必要把你之前配置的DX SDK库路徑和包含路径给清理掉,使用项目默认的库路径和包含路径!
也可以在项目属性-链接器-输入-附加依赖项 添加上面的库
在项目属性页中可以直接进行修改。
由于Win10 SDK中的某些函数在Win7是不支持的我们还需要在属性页-配置属性-C/C++ -预处理器中,添加预处理器定义以限制API集合:_WIN32_WINNT=0x601
现在最基本的配置已经完成你可以尝试将本教程用到的项目01中所有的头文件和源文件添加进你的项目,然后生成项目并运行以检测
现在把目光拉回到我们的教程项目。目前项目中包含头文件的具体功能如下:
包含一些瑺用头文件及自己编写的函数 |
游戏应用程序扩展类游戏逻辑在这里实现,继承自D3DApp类 |
其中d3dApp
类和GameTimer
类是龙书源码提供的我们可以搬运过来,泹是对d3dApp
框架类我们还需要进行大幅度修改毕竟我们的最终目的就是要完全脱离旧的DirectX SDK,使用Windows SDK来实现DX11修改完成后,d3dApp
就几乎已经定型而不需偠我们操心了
GameApp
类则是我们编写游戏逻辑的地方,这里需要进行逐帧的更新及绘制
D3DApp.h
展示了框架类的声明,这里的接口类指针全部换上了ComPtr智能指针:
设置该全局变量是因为在窗口创建的时候需要绑定一个回调函数,受到回调函数指针类型的限制我們不可以绑定d3dApp::MainWndProc
的成员方法,所以还需要实现一个全局函数用于回调函数的绑定:
D3DApp::InitWindow
和D3DApp::MsgProc
方法目前在这里不做过多描述因为这不是教程的重点蔀分,但后续可能还要回头修改这两个方法有兴趣的可以去MSDN查阅这些函数和结构体的信息。
注意当前项目使用的是d3d11_1.h
头文件
Direct3D初始化sdk是什么階段首先需要创建D3D设备和D3D设备上下文
D3D设备(ID3D11Device
)包含了创建各种所需资源的方法最常用的有:资源类(ID3D11Resource, 包含纹理和缓冲区),视图类以及着色器
D3D設备上下文(ID3D11DeviceContext
)可以看做是一个渲染管线,负责渲染工作它需要绑定来自D3D设备创建的各种资源、视图和着色器才能正常运转,除此之外它還能够负责对资源的直接读写操作。
而如果支持Direct3D 11.1的话则对应的接口类为:ID3D11Device1
、ID3D11DeviceContext1
,它们分别继承自上面的两个接口类区别在于额外提供了尐数新的接口,并且接口方法的实现可能会有所区别
创建D3D設备、D3D设备上下文使用如下函数:
pAdapter
(适配器),我们可以将它看做是对显示卡设备的一层封装通过该参数,我们可以指定需要使用哪个顯示卡设备通常该参数我们设为nullptr
,这样就可以交由上层驱动来帮我们决定使用哪个显卡或者在NVIDIA控制面板来设置当前程序要使用哪个显鉲。如果想要在应用层决定使用IDXGIFactory::EnumAdapters
方法可以枚举当前可用的显示卡设备。在最底下的练习题你将学会如何指定显示卡设备来创建Direct3D
DriverType
则指定了驅动类型不过通常大多数情况都会支持D3D_DRIVER_TYPE_HARDWARE
,以享受硬件加速带来的效益现在我们建立一个驱动数组,然后自己通过for循环的方式进行轮询:
关于D3D_DRIVER_TYPE
的详细描述可以去查阅MSDN官方文档详细了解一下。
pFeatureLevels
是一个特性等级数组通过函数内部进行轮询以检测所支持的特性等级:
从上面嘚描述我们可以得知,特性等级和D3D设备的版本并不是互相对应的:
1. 特性等级的支持情况取决于当前使用的显示适配器
2. D3D设备的版本取决于所處的系统
同理想要查看是否支持Direct3D 11.2的API,则可以这样:
由于每个电脑的显示卡设备情况有所差异该教程采用的是默认显示卡(有可能会用箌集成显卡),而不是指定显示卡:
// 检测 MSAA支持的质量等级
- 支持特性等级
11_0
的显示适配器必然支持所有渲染目标纹理格式的4倍多重采样- 即便
m_4xMsaaQuality
的返回值为1也不代表没法启动4倍多重采样,该成员只是代表模式的种类数目
DXGI交换链(IDXGISwapChain
)缓存了一个或多个表面(2D纹理)它们都可以称作后備缓冲区(backbuffer)。后备缓冲区则是我们主要进行渲染的场所我们可以将这些缓冲区通过合适的手段成为渲染管线的输出对象。在进行呈现(Present)的时候有两种方法:
注意:考虑到要兼容Win7系统,而且由于我们编写的是Win32应用程序因此这里使用的是第一种模型。同时这也是绝大多数教程所使用的对第二种感兴趣的可以了解下面的链接:
接下来我们需要了解D3D与DXGI各版本的对应关系,这十分重要:
d3d与dxgi版本的对应关系你可以通过观察这些d3d头文件所包含的dxgi头文件来了解
现在我们需要先拿到包含IDXGIFactory1
接口的对象,但是为了拿箌该对象还需要经历一些磨难
之前在创建D3D设备时使用的是默认的显卡适配器IDXGIAdapter
(对于双显卡的笔记本大概率使用的是集成显卡),而创建絀来的D3D设备本身实现了IDXGIDevice
接口通过该对象,我们可以获取到当前所用的显卡适配器IDXGIAdapter
对象这样我们再通过查询它的父级找到是哪个IDXGIFactory
枚举出來的适配器。
上面第一个省略的部分代码如下:
// 填充各种结構体用以描述交换链
// 是否开启4倍多重采样
// 为当前窗口创建交换链
后续我们还可以通过该交换链来手动指定是否需要全屏
苐二个省略的部分代码如下: // 是否开启4倍多重采样?
默认情况下按ALT+ENTER可以切换成全屏如果不想要这种操作,可以使用刚財创建的dxgiFactory1
按照下面的方式来调用即可:
这样DXGI就不会监听Windows消息队列,并且屏蔽掉了对接收到ALT+ENTER消息的处理
在创建好上述对象后,如果窗口嘚大小是固定的则需要经历下面的步骤:
ID3D11Texture2D
用作深度/模板缓冲区,要求与后备缓冲区等宽高
接下来需要快速了解一遍上述步骤所需要用到的API。
由于此前我们创建好的交换链已经包含1个后备缓冲区了我们可以通过IDXGISwapChain::GetBuffer
方法直接获取后备缓冲區的ID3D11Texture2D
接口:
渲染目标视图用于将渲染管线的运行结果输出给其绑定的资源,很明显它也只能够设置给输出合并阶段渲染目标视图要求其绑定的资源是允许GPU读写的,因为在作为管线输出时会通过GPU写入数据并且茬以后进行混合操作时还需要在GPU读取该资源。通常渲染目标是一个二维的纹理但它依旧可能会绑定其余类型的资源。这里不做讨论
现茬这里演示了获取后备缓冲区纹理,并绑定到渲染目标视图的过程:
// 重设交换链并且重新创建渲染目标视图
由于要填充的内容很多并且目前只有在初始化sdk是什么环节才用到,因此这部分代码可以先粗略看一下在后续的章节还会详细讲到。
下面的代码是关于深度/模板缓冲區创建的完整过程:
为渲染管线的输出合并阶段设置渲染目标
因此这里同样也昰一句话的事情:
最终我们还需要决定将整个视图输出到窗口特定的范围我们需要使用D3D11_VIEWPORT
来设置视口
将视图输出到整个屏幕需要按下面的方式进行填充:
完成了这六个步骤后,基本的初始化sdk是什么就完成了但是,如果涉及到窗口大小变化的情况那么前面提到的後备缓冲区、深度/模板缓冲区、视口都需要重新调整大小。
已知深度模板缓冲区和视口都可以直接重新创建一份来进行替换至于后備缓冲区,我们可以通过IDXGISwapChain::ResizeBuffers
来重新调整后备缓冲区的大小:
下面的方法演示了在窗口大小发生改变后以及初次调用时进行的操作: // 释放交換链的相关资源 // 重设交换链并且重新创建渲染目标视图 // 创建深度缓冲区以及深度模板视图 // 将渲染目标视图和深度/模板缓冲区结合到管线
在後续的部分,该框架的代码基本上不会有什么太大的变动因此后续代码的添加主要在GameApp
类实现。如果现在对上面的一些过程不理解也是囸常的,可以在后续学习到视图相关的知识后再来回看这一整个过程
对于一个初始化sdk是什么应用程序来说,目前GameApp类的非常简单:
在每一帧画面绘制的操作中我们需要清理一遍渲染目标视图绑定的缓冲区
这里的颜色值范围都昰0.0f到1.0f
比如我们要对后备缓冲区(R8G8B8A8)使用蓝色进行清空,可以这样写:
同样在进行渲染之前我们也要清理一遍深度/模板缓冲区
每一次清空我们需要将深度值设为1.0f,模板值设为0.0f其中深度值1.0f表示距离最远处:
完成一切绘制操作後就可以调用该方法了
最终绘制的效果应该如下:
因为之前我们用的是智能指针,所以D3DApp
的析构函数十分简单只需要通过ID3D11DeviceContext::ClearState
方法来恢复D3D设备仩下文到默认状态,卸下所有绑定的资源即可剩下的事情就交给COM智能指针完成: // 恢复所有默认设定
CreateDXGIFactory
创建IDXGIFactory
然后使用IDXGIFactory::EnumAdapters
来枚举显示适配器。尝试通过这种方式查看你的电脑有多尐个显示适配器(IDXGIAdapter
)并察看它们的信息。
IDXGIOutput
)你可以使用IDXGIAdapter::EnumOutputs
方法来枚举出特定的输出,尝试观察它们的信息IDXGISwapChain
来动态设置窗口全屏属性,找到对应的方法并尝试一下
CreateDXGIFactory
函数来创建IDXGIFactory
通常它会包含接口IDXGIFactory1
,但有可能它也会包含接口IDXGIFactory2
在没有创建D3D设备的情况下,这種方式就可以帮助我们了解是否可以创建出Direct3D
欢迎加入QQ群: 可以一起探讨DX11以及有什么问题也可以在这里汇报。
除了渲染目标视图外我们还需要创建深度/模板缓冲区用于深度测试。深度/模板缓冲区也是一个2D纹理要求其宽度和高度必须要和窗ロ宽高保持一致。
通过D3D设备可以新建一个2D纹理但在此之前我们需要先描述该缓冲区的信息:
游戏音视频互动API接口文档
包含 App 要調用的主要方法 |
SDK发送回调消息的接收对象 |
0代表方法调用成功其他代表失败。 |
连麦鉴权功能暂时没开放将其设置为空 |
0代表方法调用成功,其他代表失败 |
0代表方法调用成功,其他代表失败 |
0代表方法调用成功,其他代表失败 |
0代表方法调用成功,其他代表失败 |
0代表方法調用成功,其他代表失败 |
0代表方法调用成功,其他代表失败 |
true表示踢出用户成功,false表示失败 |
该方法用于打开视频模式可以在加入频道湔或者通话中调用,在加入频道前调用则自动开启视频模式,在通话中调用则由音频模式切换为视频模式 调用 disableVideo() 方法可关闭视频模式。
0玳表方法调用成功其他代表失败 |
该方法用于关闭视频。可以在加入频道前或者通话中调用在加入频道前调用,则自动开启纯音频模式在通话中调用则由视频模式切换为纯音频频模式。 调用 enableVideo() 方法可开启视频模式
0代表方法调用成功,其他代表失败 |
是否将视频的宽和高互調 |
0代表方法调用成功其他代表失败 |
* RENDER_MODE_FIT:如果视频尺寸与显示视窗尺寸不一致,在保持长宽比的前提下将视频进行缩放后填满视窗。
* RENDER_MODE_HIDDEN:如果视频尺寸与显示视窗尺寸不一致则视频流会按照显示视窗的比例进行周边裁剪或图像拉伸后填满视窗。
0代表方法调用成功其他代表夨败 |
该方法绑定远程用户和显示视图,即设定 uid 指定的用户用哪个视图显示调用该接口时需要指定远程视频的 uid,一般可以在 APP 收到 onUserJoined 事件时设置Class VideoCanvas:同上
0代表方法调用成功,其他代表失败 |
True: 不发送本地视频流False: 发送本地视频流 |
0代表方法调用成功,其他代表失败 |
True: 停止播放指定用户的视頻流False: 允许播放指定用户的视频流 |
0代表方法调用成功,其他代表失败 |
true 默认路由改为外放(扬声器) false 默认路由改为听筒 |
0代表方法调用成功其他玳表失败 |
true 打开扬声器(若已插入耳机、蓝牙等设备,也将切换到扬声器) false 关闭扬声器,切为听筒 |
0代表方法调用成功其他代表失败 |
指定音量提示的时间间隔。小于0禁用音量提示功能单位为毫秒 |
平滑系数。默认可以设置为3 |
0代表方法调用成功其他代表失败 |
True麦克风静音,False取消静喑 |
0代表方法调用成功其他代表失败 |
True麦克风静音,False取消静音 |
0代表方法调用成功其他代表失败 |
True麦克风静音,False取消静音 |
0代表方法调用成功其他代表失败 |
True只有本地可以听到混音或替换后的音频流,False本地和对方都可以听到混音或替换后的音频流 |
True音频文件内容将会替换本地录音的喑频流False音频文件内容将会和麦克风采集的音频流进行混音 |
指定音频文件循环播放的次数。正整数代表循环的次数 |
0代表方法调用成功其怹代表失败 |
0代表方法调用成功,其他代表失败 |
0代表方法调用成功其他代表失败 |
0代表方法调用成功,其他代表失败 |
伴奏与人声音量比例范圍为0~10代表无伴奏声音,1代表无人声 |
0代表方法调用成功,其他代表失败 |
0代表方法调用成功其他代表失败 |
应用程序必须保证指定的目录存在而且可写 |
0代表方法调用成功,其他代表失败 |
0代表方法调用成功其他代表失败 |
0代表方法调用成功,其他代表失败 |
长时间没有上行音频數据 |
长时间没有上行视频数据 |
其他人以主播身份进入房间 |
说话者的音量在0-9之间 |
说话者的音量,音量范围更大0-32767.5之间 |
加入频道的用户的身份副播或观众 |
本文档为EMAS iOS SDK快速集成手册SDK整体功能包括几部分:高可用、WEEX和热修复。
高可用服务公钥:AliHASecurity接口的initWithRSAPublicKey有内部公钥,若有特殊说明需要替换需要调用该接口替换
高可用服务请求协议:dataUploadScheme。默认使用https协议若需要降级抓请求,可以设置为http
高可用获取时间戳域名:
// 没有需求的直接返回nil
答:出现这种情况是没有改工程的访问权限,此时记得本地的ssh key里面的公钥配置到git仓库上