Reputation: 479
I am trying to figure out how to draw text on screen in SlimDX.
Initial research is not encouraging. The only concrete example I found was this:
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.
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?
P.S. 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. It does seem slightly insane to do this though.
Upvotes: 4
Views: 3827
Reputation: 8963
There's a nice DirectWrite wrapper called 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).
Here is simple example:
.h file
#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
#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));
}
Upvotes: 3
Reputation: 32597
Rendering text is a bit complex, indeed. The only way to render general text is to use Direct2D / DirectWrite. And this is only supported in DirectX10. So you have to create a DirectX 10 device, DirectWrite and Direct2D Factories. You then can create a shared texture that can be used by both DirectX 10 and 11 devices.
This texture will contain the text after rendering. Aaron uses this texture to blend it with the full screen. Therefore, you can use DirectWrite to draw complete strings. 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. See methods AssertDevice
and CreateCharTable
Upvotes: 4