简体   繁体   English

使用DX11渲染文本

[英]Rendering text with DX11

I am trying to figure out how to draw text on screen in SlimDX. 我想弄清楚如何在SlimDX中在屏幕上绘制文本。

Initial research is not encouraging. 初步研究并不令人鼓舞。 The only concrete example I found was this: 我发现的唯一具体例子是:

http://www.aaronblog.us/?p=36 http://www.aaronblog.us/?p=36

I am trying to port this to my code, but it's proving extremely difficult, and I'm beginning to wonder after 4 hours if this is the right way to go. 我试图把它移植到我的代码中,但它证明是非常困难的,并且我开始怀疑4小时后这是否是正确的方法。

Essentially it seems quite difficult to do something as simple as writing text to the screen. 从本质上讲,做一些简单的事情似乎很难,比如在屏幕上写文字。 Aaron's method seems the only one out there which is practical at the moment. 亚伦的方法似乎是目前唯一实用的方法。 There are no other points of comparison. 没有其他比较点。

Does anyone else have any advice they could offer? 有没有人有任何可以提供的建议?

PS I suspect I could have created individual images for letters by now, and coded a routine to convert a string into a series of sprites. PS我怀疑我现在可以为字母创建单独的图像,并编写一个例程来将字符串转换为一系列精灵。 It does seem slightly insane to do this though. 尽管如此,这似乎有点疯狂。

Rendering text is a bit complex, indeed. 实际上,渲染文本有点复杂。 The only way to render general text is to use Direct2D / DirectWrite. 呈现常规文本的唯一方法是使用Direct2D / DirectWrite。 And this is only supported in DirectX10. 这只在DirectX10中得到支持。 So you have to create a DirectX 10 device, DirectWrite and Direct2D Factories. 因此,您必须创建DirectX 10设备,DirectWrite和Direct2D工厂。 You then can create a shared texture that can be used by both DirectX 10 and 11 devices. 然后,您可以创建可供DirectX 10和11设备使用的共享纹理。

This texture will contain the text after rendering. 此纹理将包含渲染后的文本。 Aaron uses this texture to blend it with the full screen. Aaron使用此纹理将其与全屏融合。 Therefore, you can use DirectWrite to draw complete strings. 因此,您可以使用DirectWrite绘制完整的字符串。 Essentially, this is just like drawing a textured quad. 基本上,这就像绘制纹理四边形。

Another way of doing this is, as you already mentioned, drawing a sprite sheet and splitting strings into several sprites. 另一种方法是,正如您已经提到的那样,绘制一个精灵表并将字符串分成几个精灵。 I assume, the latter way is a bit faster, but I haven't tested it yet. 我假设,后一种方式有点快,但我还没有测试过。 I used this method in my Sprite & Text engine . 我在我的Sprite&Text引擎中使用了这个方法。 See methods AssertDevice and CreateCharTable 请参阅方法AssertDeviceCreateCharTable

There's a nice DirectWrite wrapper called http://fw1.codeplex.com/ 有一个很好的DirectWrite包装器,名为http://fw1.codeplex.com/

It's in c++ but it's very simple to make a mixed mode wrapper for it (which is what i did for my c# projects). 它是用c ++编写的,但为它制作混合模式包装器非常简单(这就是我为我的c#项目所做的)。

Here is simple example: 这是一个简单的例子:

.h file .h文件

#pragma once
#include "Lib/FW1FontWrapper.h"
using namespace System::Runtime::InteropServices;

public ref class DX11FontWrapper
{
public:
    DX11FontWrapper(SlimDX::Direct3D11::Device^ device);
    void Draw(System::String^ str,float size,int x,int y,int color);
private:
    SlimDX::Direct3D11::Device^ device;
    IFW1FontWrapper* pFontWrapper;
};

.cpp file .cpp文件

#include "StdAfx.h"
#include "DX11FontWrapper.h"

DX11FontWrapper::DX11FontWrapper(SlimDX::Direct3D11::Device^ device)
{
    this->device = device;

    IFW1Factory *pFW1Factory;
    FW1CreateFactory(FW1_VERSION, &pFW1Factory);
    ID3D11Device* dev = (ID3D11Device*)device->ComPointer.ToPointer();

    IFW1FontWrapper* pw;

    pFW1Factory->CreateFontWrapper(dev, L"Arial", &pw); 
    pFW1Factory->Release();

    this->pFontWrapper = pw;
}

void DX11FontWrapper::Draw(System::String^ str,float size,int x,int y, int color)
{
    ID3D11DeviceContext* pImmediateContext = 
        (ID3D11DeviceContext*)this->device->ImmediateContext->ComPointer.ToPointer();

    void* txt = (void*)Marshal::StringToHGlobalUni(str);
    pFontWrapper->DrawString(pImmediateContext, (WCHAR*)txt, size, x, y, color, 0);
    Marshal::FreeHGlobal(System::IntPtr(txt));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM