在Unity中可能需要在纹理上面绘制文字、图像等。比如游戏中的显示器,手机等等等等等。太多了。 Unity的Textute2D类提供了设置像素的操作, 但是这效率实在不敢恭维。 汉字数量巨大,全部贴在一张图上既耗空间,不方便改变字体样式。 使用FreeType2等CPU计算
在Unity中可能需要在纹理上面绘制文字、图像等。比如游戏中的显示器,手机等等等等等。太多了。
Unity的Textute2D类提供了设置像素的操作,但是这效率实在不敢恭维。
汉字数量巨大,全部贴在一张图上既耗空间,不方便改变字体样式。
使用FreeType2等CPU计算的文字库一帧又画不了多少,毕竟还要提交到显存
于是瞄准了Direct2D,当初学习这图像接口时就被微软说的“能与Direct3D进行完美交互”所吸引。
好在Unity支持DX11了,我们能够在Unity上面使用Direct2D了。所以只能在支持DX11的机器上面运行。
首先得说一下授权许可,毕竟Unity是一款商业软件。
Unity明确指出:Unity Pro才能使用Plug-in,即插件。Unity Free版本是不可以使用的。
但是,它说的是“插件”,而不是“本地代码”。
有童鞋肯定就会说我这是咬文嚼字了。非也非也,“插件”是指遵循当前环境并按照其对接口的相关规定写的代码。
那么,Unity插件有什么规定呢?
需要提供UnitySetGraphicsDevice与UnityRenderEvent
前者获取图形设备信息与图像设备相关事件,后者提供渲染事件。这两个接口是Unity自动调用的(或者也算半自动),
不能显式调用——因为没意义.....
你的本地代码提供了这两个接口就算插件,否则就是普通的本地代码库。
作为本地代码库不能放在plugin文件夹内,不能调用,因为Unity会认为是个插件,而应该直接放在工厂目录下。
再者,假设你写了个插件却放在这个目录下,那么那两个接口不能自动被调用。
好了,就这样可以创建Direct2D了,那个版本的?1.0?1.1?甚至1.2?随意啦!
但是,我建议这样做:
[cpp] view plaincopyprint?
- #include "windows.h"
- HMODULE WINAPI LoadLibraryWrapA(char* file_name){
- return LoadLibraryA(file_name);
- }
- HMODULE WINAPI LoadLibraryWrapW(wchar_t* file_name){
- return LoadLibraryW(file_name);
- }
- BOOL WINAPI FreeLibraryWrap(HMODULE hLibModule){
- return FreeLibrary(hLibModule);
- }
- FARPROC WINAPI GetProcAddressWrap(HMODULE hModule, char* lpProcName){
- return GetProcAddress(hModule, lpProcName);
- }
#include "windows.h" HMODULE WINAPI LoadLibraryWrapA(char* file_name){ return LoadLibraryA(file_name); } HMODULE WINAPI LoadLibraryWrapW(wchar_t* file_name){ return LoadLibraryW(file_name); } BOOL WINAPI FreeLibraryWrap(HMODULE hLibModule){ return FreeLibrary(hLibModule); } FARPROC WINAPI GetProcAddressWrap(HMODULE hModule, char* lpProcName){ return GetProcAddress(hModule, lpProcName); }
面的代码封装成dll文件,这样像C++一样显式调用dll文件。
好处如下:
1. 方便: 不知道是不是Unity的原因,反正假设你想一般dll一样使用Unity C#中的DllImport,
使用后除非关闭Unity,否则不能再次修改dll文件。这简直蛋疼,修改一行代码就需要:
关闭Unity -> 复制dll -> 打开Unity
2. 方便调试,在VS Express 2013 for Windows Desktop中,选择
工具——附加到进程,选择Unity进程
就能直接调试dll文件了,很方便。
使用GetProcAddressWrap获取函数指针之后使用C#中的
Marshal.GetDelegateForFunctionPointer
就能将函数指针换成C#中的托管方法。
比如先定义:
[csharp] view plaincopyprint?
- // 初始化 D2D 管理器
- publicdelegate System.UInt32 D2DManagerInit();
- public D2DManagerInit m_D2DManagerInit;
// 初始化 D2D 管理器 public delegate System.UInt32 D2DManagerInit(); public D2DManagerInit m_D2DManagerInit;
使用:
[csharp] view plaincopyprint?
- proc = GetProcAddressWrap(m_unityd2ddll, "D2DManagerInit");
- m_D2DManagerInit = (D2DManagerInit)Marshal.GetDelegateForFunctionPointer(proc, typeof(D2DManagerInit));
proc = GetProcAddressWrap(m_unityd2ddll, "D2DManagerInit"); m_D2DManagerInit = (D2DManagerInit)Marshal.GetDelegateForFunctionPointer(proc, typeof(D2DManagerInit));
之后使用m_D2DManagerInit()就能调用dll文件中的D2DManagerInit函数了。
最后在OnApplicationQuit里面释放即可。
创建 D2D 1.0 的 流程:
首先创建一个公共的 D2D工厂 ,毕竟可能创建多个
Unity中 Texture2D::GetNativeTextureID在DX11环境下就能获取一个ID3D11Texture2D的指针
这个指针能获取 D3D11设备 ,D3D11设备 能获取当前 D3D11设备上下文。
D3D与D2D交互要D3D设备有D3D11_CREATE_DEVICE_BGRA_SUPPORT(D3D11环境下)
D3D11设备 -------> 创建Texture2D,D3D11_TEXTURE2D_DESC参考如下:
[cpp] view plaincopyprint?
- sharedTextureDesc.Width = 512;
- sharedTextureDesc.Height = 512;
- sharedTextureDesc.MipLevels = 1;
- sharedTextureDesc.ArraySize = 1;
- sharedTextureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- sharedTextureDesc.SampleDesc.Count = 1;
- sharedTextureDesc.Usage = D3D11_USAGE_DEFAULT;
- sharedTextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
sharedTextureDesc.Width = 512; sharedTextureDesc.Height = 512; sharedTextureDesc.MipLevels = 1; sharedTextureDesc.ArraySize = 1; sharedTextureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sharedTextureDesc.SampleDesc.Count = 1; sharedTextureDesc.Usage = D3D11_USAGE_DEFAULT; sharedTextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
必须有D3D11_BIND_RENDER_TARGET,否则不能创建渲染目标呈现器。记得保留这个指针。
然后对 D3D11Textue2D 使用QueryInterface获取 Dxgi表面
使用这个Dxgi表面利用D2D工厂CreateDxgiSurfaceRenderTarget创建RT
就好了,记得释放这个Dxgi表面:
渲染D2D
如同一般那样,不过由于变成了dll,可能一些习惯要改成C语言那样。
呈现D2D
渲染完成后,使用
D3D11设备上下文的CopyResource方法就能拷贝渲染结果到目标纹理了:
DirectWrite简直不错:
稍微写点代码就能模仿某游戏那样的效果:
嗯,看来还不够完善,再加油吧:
话说自带的Sprite着色器很不错,简直赞

mysqloffersvariousStorageengines,每个suitedfordferentusecases:1)InnodBisidealForapplicationsNeedingingAcidComplianCeanDhighConcurncurnency,supportingtransactionsancions and foreignkeys.2)myisamisbestforread-Heavy-Heavywyworks,lackingtransactionsactionsacupport.3)记忆

MySQL中常见的安全漏洞包括SQL注入、弱密码、权限配置不当和未更新的软件。1.SQL注入可以通过使用预处理语句防止。2.弱密码可以通过强制使用强密码策略避免。3.权限配置不当可以通过定期审查和调整用户权限解决。4.未更新的软件可以通过定期检查和更新MySQL版本来修补。

在MySQL中识别慢查询可以通过启用慢查询日志并设置阈值来实现。1.启用慢查询日志并设置阈值。2.查看和分析慢查询日志文件,使用工具如mysqldumpslow或pt-query-digest进行深入分析。3.优化慢查询可以通过索引优化、查询重写和避免使用SELECT*来实现。

要监控MySQL服务器的健康和性能,应关注系统健康、性能指标和查询执行。1)监控系统健康:使用top、htop或SHOWGLOBALSTATUS命令查看CPU、内存、磁盘I/O和网络活动。2)追踪性能指标:监控查询每秒数、平均查询时间和缓存命中率等关键指标。3)确保查询执行优化:启用慢查询日志,记录并优化执行时间超过设定阈值的查询。

MySQL和MariaDB的主要区别在于性能、功能和许可证:1.MySQL由Oracle开发,MariaDB是其分支。2.MariaDB在高负载环境中性能可能更好。3.MariaDB提供了更多的存储引擎和功能。4.MySQL采用双重许可证,MariaDB完全开源。选择时应考虑现有基础设施、性能需求、功能需求和许可证成本。

MySQL使用的是GPL许可证。1)GPL许可证允许自由使用、修改和分发MySQL,但修改后的分发需遵循GPL。2)商业许可证可避免公开修改,适合需要保密的商业应用。

选择InnoDB而不是MyISAM的情况包括:1)需要事务支持,2)高并发环境,3)需要高数据一致性;反之,选择MyISAM的情况包括:1)主要是读操作,2)不需要事务支持。InnoDB适合需要高数据一致性和事务处理的应用,如电商平台,而MyISAM适合读密集型且无需事务的应用,如博客系统。

在MySQL中,外键的作用是建立表与表之间的关系,确保数据的一致性和完整性。外键通过引用完整性检查和级联操作维护数据的有效性,使用时需注意性能优化和避免常见错误。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具