首先我搜到了不少大佬说,VS2017自带了DirectX你不需要搞那么繁复的配置(以前的DirectX+VS配置非常复杂)。 但我这个憨憨还是找不到自带的DirectX在哪里。。。
这个时候,八成是你安装VS2017时没有勾选正确的包。
打开这个【Visual Studio Installer】,就是回到你刚安装VS2017选包的那一步,怎么打开?
1. 可以从控制面板,进去找到VS,右键有卸载和修改。选修改
2. 新建项目时左下角有个直达电梯(入口),如下图
ok,勾上两个
这玩意写的也是有点让人头秃,我之前就勾过使用C++的游戏开发。。。你看他这介绍还写了,有DirectX.....
然后别人打开创建项目时可以找到DirectX11项目,我就找不到。。罪魁祸首就是没勾下面这个平台开发
咱看看平台开发右侧有什么??DirectX你怎么又出现在了这里。。。
这两个都勾上就可以再创建项目时找到DirectX了,11,12都有。。
打开直接run一下试试 ,我一下还没run成功。。报了一个错:
【由于错误800704C7 无法获取开发人员许可证】
弹出设置界面,选择开发人员模式即可
wooooooo!!!!
后面的...我碰到之后,再慢慢更新啦~
啊我觉得这个VS2017自带的框架真的真的很奇怪,和市面上所有DX11的教程都不同,而且感觉出入还挺大。本来还在犹豫要不要照着别的教程做算了,从空项目开始搞。但又觉得放着好端端的框架不用太浪费。
我还是努努力看懂这个框架吧....
网上说学过Opengl的人入手DirectX是分分钟的事,为什么我连个VS自带框架都看的似懂非懂o(╥﹏╥)o,我可太下饭了。下文是结合官方文档和VS自带框架,二者结合起来阅读的一些理解。
VS2017自带框架的组织结构:
为了画一个渐变色立方体旋转就这么多文件。。我以前学过opengl,我以为画立方体就搞8个点,在vertex shader里空间转换, fragment shader里上色就行了。转起来也不过就是对model加个与时间相关的旋转变换。可是这个框架里真的蛮多代码。菜鸡表示有点惶恐,只能选择细细的看看。。
这是入口,可以看出是new了一个对象(D3D应用),然后把它作为参数塞进了一个系统自带的Run函数。我用F12追进去看发现,Direct3DApplicationSource是继承自IframeWorkViewSource类的,但它有个需要重写的虚函数:CreateView()。就是说IframeWorkViewSource类的CreateView(),Direct3DApplicationSource类里的CreateView() 要覆盖替换掉基类的功能。
让我们看看CreateView()是如何重写的,就在main函数的正下方
可以看出这个函数其实就是又返回了一个对象。是调用App类构造函数new出来的一个实例。行啊 再去看看App类的定义和其构造函数:
他这命名都很相似,一不留神就会看错。 所以现在整理一下:
App类是IFrameworkView的派生类,
Direct3DApplicationSource是IframeWorkViewSource的派生类
下面一行这个XXXsource的类只有一个Create()的功能,IframeWorkViewSource对应IFrameworkView,Direct3DApplicationSource对应App()
有没有点似曾相识的感觉?
这是不是很像个工厂模式。。
我发现 为什么我看不懂,是因为我不懂windows shell, 不理解IframeworkView到底是个什么接口。所以再追深一点看一下IframeworkView:
这是微软官方文档里关于IframeworkView的介绍
官方例子是教大家如何用IframeworkView实现一个简单的Direct3D view provider.
一个个看我们app类里的方法吧。
首先构造函数很简单:
CoreApplicationView 是系统自带的一个类。
CoreApplication也是自带的。
Resuming和Suspending追进去看也是自带的。
这些就都感觉是比较底层的。最后一行m_deviceResources是个智能指针 shared_ptr,自此,app类里四个private的东西,就算有三个交代过了(构造函数里搞了两个,这里一个)。
Iniatialize已经看过了,就是处理底层接口外加赋值了一个shared_ptr(m_deviceResources)
再看load,搞了剩下的unique_ptr(m_main)
再整理一下:
App::app():设置了m_windowClosed(false), m_windowVisible(true)
App::Initialize():设置了m_deviceResources = std::make_shared
App::load():设置m_main = std::unique_ptr
dxtest1Main也是一个类。dxtest1就是我创建解决方案时的名字,等于说 Initiallize里是打通了硬件问题,然后将备好的硬件作为参数传进dxtest1Main的构造函数。dxtest1Main先不深入,免得枝叶散的太大了又搞不清了。
继续App类的其他函数:
可以看出App::Run()函数就是在window没有closed时,循环调用m_main的update(),m_main的Render(),Render()是准备呈现帧的作用,如果已经ready则返回true,随之调用m_deviceResources的Present(),这个Present()函数就是交换前后缓冲区的。这个知识点之前学习opengl的时候了解过,就是显示器有两个buffer,在幕后的buffer上先画好再刷新到台前,这样两个buffer前后交换可以减少绘制的卡顿。暂时也不深挖了知道是这个功能即可。
所以其实这个App::Run()就是游戏的经典大循环逻辑(如下),我是没写过游戏但也听说过orz:
while(不退出){
update() 更新游戏逻辑,可能是处理输入或者加减血量修改数据之类的。
render() 渲染画面
}
App还有几个方法:
刚说过的Run() Load() Initialize()都是IFramework自带的方法,App类里是以虚函数的形式重写了他们
还有两个Iframework自带方法:Setwindow()和Uninitialize()
Setwindow()是创建(或重新创建) CoreWindow 对象时调用,体感偏底层,最后也是和设备打交道。
Uninitialized()示例里面是空的
App还有几个新的方法:
生命周期处理程序OnActivated,OnSuspending,OnResuming
窗口事件处理程序OnWindowSizeChanged,OnVisibilityChanged,OnWindowClosed
===============
to be continue...