Use Direct2D in Unity

Source: Internet
Author: User
In Unity, you may need to draw text and images on the texture. Such as game monitors and mobile phones. Too many. The Textute2D class of Unity provides pixel setting operations, but the efficiency is not flattering. The number of Chinese characters is huge. It is not convenient to change the font style because all the Chinese characters are attached to a graph. Use FreeType2 and other CPU computing

In Unity, you may need to draw text and images on the texture. Such as game monitors and mobile phones. Too many. The Textute2D class of Unity provides pixel setting operations, but the efficiency is not flattering. The number of Chinese characters is huge. It is not convenient to change the font style because all the Chinese characters are attached to a graph. Use FreeType2 and other CPU computing

In Unity, you may need to draw text and images on the texture. Such as game monitors and mobile phones. Too many.

The Textute2D class of Unity provides pixel setting operations, but the efficiency is not flattering.


The number of Chinese characters is huge. It is not convenient to change the font style because all the Chinese characters are attached to a graph.

The text font calculated using FreeType2 and other CPUs cannot draw much at a frame. After all, it must be submitted to the video memory.


So he aimed at Direct2D. When he first learned this image interface, he was attracted by Microsoft's "perfect interaction with Direct3D.

Fortunately, Unity supports DX11, and we can use Direct2D on Unity. Therefore, it can only run on machines that support DX11.


First, let's talk about the license. After all, Unity is a commercial software.

Unity clearly states that Unity Pro can only use Plug-in, that is, Plug-ins. The Unity Free version is unavailable.

However, it refers to "plug-ins" rather than "Local Code ".

If you have a pair of shoes, you will surely say that I am a chew. Neither is nor is it. "ins" refer to the code that follows the current environment and complies with its relevant provisions on interfaces.


What are the rules for the Unity plug-in?

UnitySetGraphicsDevice and UnityRenderEvent must be provided

The former obtains graphics device information and events related to Image devices, and the latter provides rendering events. These two interfaces are automatically called by Unity (or semi-automated ),

It cannot be explicitly called-because it doesn't make sense .....


Your local code provides these two interfaces, even if they are plug-ins. Otherwise, they are common local code libraries.

As a local code library, it cannot be placed in the plugin folder or called, because Unity considers it a plug-in and should be placed directly in the factory directory.


Furthermore, if you write a plug-in but put it in this directory, the two interfaces cannot be automatically called.



Okay, so we can create Direct2D. Which version? 1.0? 1.1? Even 1.2? Free!


However, I suggest doing this:

[Cpp]View plaincopyprint?

  1. # Include "windows. h"
  2. Hmodule winapi LoadLibraryWrapA (char * file_name ){
  3. Return LoadLibraryA (file_name );
  4. }
  5. Hmodule winapi LoadLibraryWrapW (wchar_t * file_name ){
  6. Return LoadLibraryW (file_name );
  7. }
  8. Bool winapi FreeLibraryWrap (HMODULE hLibModule ){
  9. Return FreeLibrary (hLibModule );
  10. }
  11. Farproc winapi GetProcAddressWrap (HMODULE hModule, char * lpProcName ){
  12. Return GetProcAddress (hModule, lpProcName );
  13. }

#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);}


The above code is encapsulated into a dll file, so that the dll file is explicitly called like C ++.

Benefits:

1. Convenience: I don't know if it is the reason for Unity. Anyway, if you want to use DllImport in Unity C # Like a dll,

After use, you cannot modify the dll file again unless Unity is disabled. This is a pain point. You need to modify a line of code:

Close Unity-> copy dll-> open Unity

2. for debugging convenience, in VS Express 2013 for Windows Desktop, select


Tool-attach to process and select Unity process


You can directly debug the dll file.


Use GetProcAddressWrap to obtain the function pointer and then use

Marshal. GetDelegateForFunctionPointer

You can replace the function pointer with the hosting method in C.


For example, first define:

[Csharp]View plaincopyprint?

  1. // Initialize the D2D Manager
  2. Publicdelegate System. UInt32 D2DManagerInit ();
  3. Public D2DManagerInit m_D2DManagerInit;

// Initialize D2D manager public delegate System. UInt32 D2DManagerInit (); public D2DManagerInit m_D2DManagerInit;

Usage:

[Csharp]View plaincopyprint?

  1. Proc = GetProcAddressWrap (m_unityd2ddll, "D2DManagerInit ");
  2. M_D2DManagerInit = (D2DManagerInit) Marshal. GetDelegateForFunctionPointer (proc, typeof (D2DManagerInit ));

            proc = GetProcAddressWrap(m_unityd2ddll, "D2DManagerInit");            m_D2DManagerInit = (D2DManagerInit)Marshal.GetDelegateForFunctionPointer(proc, typeof(D2DManagerInit));

Then use m_D2DManagerInit () to call the D2DManagerInit function in the dll file.


Finally, release it in OnApplicationQuit.




The process for creating D2D 1.0 is as follows:


First, create a common D2D factory. After all, you may create multiple


In Unity, Texture2D: GetNativeTextureID can get an ID3D11Texture2D pointer in the DX11 environment.


This pointer can get the D3D11 device, and the D3D11 device can get the context of the current D3D11 device.


D3D interaction with D2D requires D3D devices to have D3D11_CREATE_DEVICE_BGRA_SUPPORT (in the D3D11 environment)




D3D11 device -------> Create Texture2D and D3D11_TEXTURE2D_DESC as follows:

[Cpp]View plaincopyprint?

  1. SharedTextureDesc. Width = 512;
  2. SharedTextureDesc. width = 512;
  3. SharedTextureDesc. MipLevels = 1;
  4. SharedTextureDesc. ArraySize = 1;
  5. SharedTextureDesc. Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  6. SharedTextureDesc. SampleDesc. Count = 1;
  7. SharedTextureDesc. Usage = D3D11_USAGE_DEFAULT;
  8. 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 is required; otherwise, the rendering target Renderer cannot be created. Remember to keep this pointer.



Then, use QueryInterface on D3D11Textue2D to obtain the Dxgi surface.

Use this Dxgi surface to use the D2D factory CreateDxgiSurfaceRenderTarget to create RT

Okay. Remember to release the Dxgi surface:



Rendering D2D

As in general, but due to dll, some habits may need to be changed to C language.


D2D Rendering

After rendering, use

The CopyResource method of the D3D11 device context can copy the rendering result to the target texture:


DirectWrite is pretty good:




A little bit of code can mimic the effects of a game:


Well, it seems that it is not perfect. Come on again:


In other words, the Sprite player is very good.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.