SlimDX DirectX11和文本精灵

时间:2014-10-06 15:26:12

标签: windows forms text directx-11 slimdx

我有一个SlimDX RenderForm(它继承了System.Windows.Forms.Form),我在其中有一个我在其上渲染地图的Panel。我想在地图上绘制城市名称。当用户放大和缩小地图时,文本不应改变大小,而是简单地进一步分开和靠近在一起。我想到了5种方法,每种方法都存在问题:

  1. 使用精灵来绘制文本。问题:DirectX11和Sprites不能混合。

  2. 等待DirectX11完成绘图,然后使用GDI手动将文本绘制到面板上。问题:处理尽可能多的文本需要花费太长时间,文本在每次重绘时都会有一个恼人的闪光。

  3. 基于Label创建自定义类,将类设置为允许透明背景,将Panel绘制为其父级,然后在用户缩放时移动这些标签。问题:为标签提供透明背景实际上并不会使其透明。它只是意味着它借用了Panel DirectX正在绘制的背景颜色并将自定义类的背景设置为它。我也尝试重写OnPaintBackground函数什么都不做,但这只是给标签一个黑色背景。

  4. 为表单提供TransparencyKey,并为面板提供该颜色的背景。然后,在这些面板之后,制作全新的RenderForms,在其上进行DirectX绘图,并将文本放在现在透明面板上的标签中。问题:单击地图空间会在后焦点中显示RenderForms,这意味着当单击该空间时,文本会在这些表单后面消失。我可以给主要的Form AlwaysOnTop,但我真的不想这样做,因为用户可能想在我的应用程序运行时做一些其他事情。另外,如果我打开另一个窗口,然后回到我的应用程序,这些表格不再显示在我的主表格后面。

  5. 执行类似于3的操作,并操作Region属性以匹配文本的GraphicsPath。问题:当我移动它们时,它有时不会尊重我所制作的区域,并且会回到黑色背景。

  6. 是否有任何我错过的解决方案,或以任何方式完成这些工作?

    修改

    基于给出答案的建议,我现在尝试使用GeometryShader来实质上制作一个精灵生成器。但是当我只有6个不同的精灵时,画画需要很长时间。只有1个精灵可以接受,但是当我尝试添加更多精灵时,它会变得太多。

1 个答案:

答案 0 :(得分:1)

我在自己的引擎中解决了这个问题。我基本上创建了一个粒子系统,其中粒子顶点包含世界位置,颜色,字符索引,大小和大小模式。然后,此点粒子将转换为几何着色器中的精灵。这两种模式是恒定的世界大小(精灵是世界坐标中的恒定大小)或恒定的屏幕大小(精灵在屏幕坐标中是恒定大小)。然后,您需要编写一个接收字符串的方法,并为每个顶点输出此粒子列表。如果操作正确,几何着色器会为您完成所有工作,即使相机移动,您也无需进行任何顶点缓冲区更新来定位文本。

就sprite批处理而言,无需担心绘制顺序。丢弃每个像素周围的透明像素以防止深度写入。

小心尝试在要绘制的面板上放置透明的.Net控件。这将需要控件在每次呈现场景时重绘,这会导致.Net限制帧速率(非常糟糕!)。如果需要,我将控件放在我的d3d面板上,但它们是不透明的,不需要不断绘画。

希望有所帮助。如果您需要更多详细信息,请与我们联系。

- 更新 -

我来定义2个术语。 “字符精灵”是一个包含单个字符图像的小精灵。 “字符串精灵”是角色精灵的集合,它们移动并表现为一个具有多个字符外观的大精灵。

用户在世界空间中定义字符串精灵的位置。字符串中的每个字符用于定义字符精灵。具体来说,每个字符精灵都被赋予一个与字符串精灵位置相对应的屏幕空间。这允许所有精灵定位在3d空间中,而屏幕空间中没有所有角色在彼此之上。

每个字符精灵都是具有“位置”(float3),“纹理坐标”(float2),“纹理编号”(int),“屏幕空间偏移”(float2)和“颜色”(float4)的点顶点。 “位置”对于字符串精灵中的所有字符精灵都是相同的。“每个字符的纹理可以在单个图像中定义,其中每个字符精灵都被赋予适当的纹理坐标(我做的)或纹理数组。

enter image description here

- 更新 -

这是我用于文本的图像(低质量)。

enter image description here

以下是根据角色精神分配给角色精灵的纹理坐标表。

Char    ASCII   StrtPix EndPix  PixWdth StartUTexCoord  EndUTexCoord

    32  0   0   40  0   0
!   33  16  34  18  0.002222222 0.004722222
"   34  56  97  41  0.007777778 0.013472222
#   35  113 197 84  0.015694444 0.027361111
$   36  212 279 67  0.029444444 0.03875
%   37  290 412 122 0.040277778 0.057222222
&   38  423 512 89  0.058750000 0.071111111
\   39  512 567 55  0.071111111 0.07875
(   40  572 611 39  0.079444444 0.084861111
)   41  625 664 39  0.086805556 0.092222222
*   42  681 743 62  0.094583333 0.103194444
+   43  761 842 81  0.105694444 0.116944444
,   44  859 888 29  0.119305556 0.123333333
-   45  902 945 43  0.125277778 0.13125
.   46  981 997 16  0.136250000 0.138472222
/   47  991 1048    57  0.137638889 0.145555556
0   48  1122    1188    66  0.155833333 0.165
1   49  1142    1194    52  0.158611111 0.165833333
2   50  1214    1278    64  0.168611111 0.1775
3   51  1292    1355    63  0.179444444 0.188194444
4   52  1365    1436    71  0.189583333 0.199444444
5   53  1450    1511    61  0.201388889 0.209861111
6   54  1524    1591    67  0.211666667 0.220972222
7   55  1602    1668    66  0.222500000 0.231666667
8   56  1680    1748    68  0.233333333 0.242777778
9   57  1756    1824    68  0.243888889 0.253333333
:   58  1849    1866    17  0.256805556 0.259166667
;   59  1896    1925    29  0.263333333 0.267361111
<   60  1954    2027    73  0.271388889 0.281527778
=   61  2054    2129    75  0.285277778 0.295694444
>   62  2156    2229    73  0.299444444 0.309583333
?   63  2250    2305    55  0.312500000 0.320138889
@   64  2319    2425    106 0.322083333 0.336805556
A   65  2434    2518    84  0.338055556 0.349722222
B   66  2528    2599    71  0.351111111 0.360972222
C   67  2607    2685    78  0.362083333 0.372916667
D   68  2698    2779    81  0.374722222 0.385972222
E   69  2792    2856    64  0.387777778 0.396666667
F   70  2871    2932    61  0.398750000 0.407222222
G   71  2936    3020    84  0.407777778 0.419444444
H   72  3036    3109    73  0.421666667 0.431805556
I   73  3126    3165    39  0.434166667 0.439583333
J   74  3172    3217    45  0.440555556 0.446805556
K   75  3236    3312    76  0.449444444 0.46
L   76  3321    3381    60  0.461250000 0.469583333
M   77  3389    3473    84  0.470694444 0.482361111
N   78  3492    3565    73  0.485000000 0.495138889
O   79  3579    3667    88  0.497083333 0.509305556
P   80  3682    3744    62  0.511388889 0.52
Q   81  3751    3841    90  0.520972222 0.533472222
R   82  3853    3932    79  0.535138889 0.546111111
S   83  3935    4008    73  0.546527778 0.556666667
T   84  4011    4091    80  0.557083333 0.568194444
U   85  4097    4170    73  0.569027778 0.579166667
V   86  4178    4264    86  0.580277778 0.592222222
W   87  4266    4383    117 0.592500000 0.60875
X   88  4389    4468    79  0.609583333 0.620555556
Y   89  4469    4547    78  0.620694444 0.631527778
Z   90  4552    4625    73  0.632222222 0.642361111
[   91  4642    4677    35  0.644722222 0.649583333
\   92  4687    4744    57  0.650972222 0.658888889
]   93  4749    4793    44  0.659583333 0.665694444
^   94  4805    4886    81  0.667361111 0.678611111
_   95  4893    4975    82  0.679583333 0.690972222
'   96  4982    4998    16  0.691944444 0.694166667
a   97  5010    5071    61  0.695833333 0.704305556
b   98  5089    5152    63  0.706805556 0.715555556
c   99  5161    5219    58  0.716805556 0.724861111
d   100 5226    5287    61  0.725833333 0.734305556
e   101 5303    5367    64  0.736527778 0.745416667
f   102 5373    5418    45  0.746250000 0.7525
g   103 5418    5479    61  0.752500000 0.760972222
h   104 5499    5559    60  0.763750000 0.772083333
i   105 5577    5597    13  0.774583333 0.776378888
j   106 5595    5634    39  0.777083333 0.7825
k   107 5652    5715    63  0.785000000 0.79375
l   108 5725    5738    13  0.795138889 0.796944444
m   109 5757    5860    103 0.799583333 0.813888889
n   110 5878    5937    59  0.816388889 0.824583333
o   111 5952    6016    64  0.826666667 0.835555556
p   112 6030    6093    63  0.837500000 0.84625
q   113 6103    6165    62  0.847638889 0.85625
r   114 6184    6229    45  0.858888889 0.865138889
s   115 6232    6287    55  0.865555556 0.873194444
t   116 6293    6338    45  0.874027778 0.880277778
u   117 6348    6407    59  0.881666667 0.889861111
v   118 6419    6488    69  0.891527778 0.901111111
w   119 6493    6588    95  0.901805556 0.915
x   120 6593    6661    68  0.915694444 0.925138889
y   121 6666    6735    69  0.925833333 0.935416667
z   122 6742    6798    56  0.936388889 0.944166667
{   123 6810    6869    59  0.945833333 0.954027778
|   124 6900    6913    13  0.958333333 0.960138889
}   125 6944    7003    59  0.964444444 0.972638889
~   126 7022    7104    82  0.975277778 0.986666667

以下是我使用的HLSL几何着色器的片段。使用此着色器以及相应的顶点和像素着色器,我可以虚拟渲染整个文本段落以影响性能。 &gt; 1,000个字符是不可察觉的。

struct VertexOutput
{
    float4 Pos  : SV_Position;
    float4 Color    : COLOR;
    float2 TexCoords    : TEXCOORD;
    float4 Size : TEXCOORD1;
};

struct GeometryOutput
{
    float4 Pos  : SV_Position;
    float4 Color    : COLOR;
    float2 TexCoords    : TEXCOORDS;
};

struct Camera
{
    float4x4 ViewProjection;
    float4x4 Projection;
    float4x4 View;
    float4 Position;
    float4 LookAt;
};

texture2D <float> TextTextures : register(t6);

[maxvertexcount(4)]
void GShader( point VertexOutput Input[1], inout TriangleStream<GeometryOutput> OutputStream )
{
    if(Input[0].TexCoords.x != Input[0].TexCoords.y)
    {
        GeometryOutput Output1 = (GeometryOutput)0;
        GeometryOutput Output2 = (GeometryOutput)0;
        GeometryOutput Output3 = (GeometryOutput)0;
        GeometryOutput Output4 = (GeometryOutput)0;

        if(Input[0].Pos.w == 1)
            Output1.Pos = mul(Input[0].Pos, Cameras[0].ViewProjection);
        else
        {
            Input[0].Pos.w = 1;
            Output1.Pos = mul(Input[0].Pos, Cameras[0].ViewProjection);
            Output1.Pos.xyz /= Output1.Pos.w;
            Output1.Pos.w = 1;
        }
        Output2.Pos = Output1.Pos;
        Output3.Pos = Output1.Pos;
        Output4.Pos = Output1.Pos;

        Output1.Pos.x += (Input[0].Size.z - Input[0].Size.x) / Resolution.x/2;
        Output2.Pos.x += (Input[0].Size.z + Input[0].Size.x) / Resolution.x/2;
        Output3.Pos.x += (Input[0].Size.z - Input[0].Size.x) / Resolution.x/2;
        Output4.Pos.x += (Input[0].Size.z + Input[0].Size.x) / Resolution.x/2;

        Output1.Pos.y += (Input[0].Size.w - Input[0].Size.y)  / Resolution.y/2;
        Output2.Pos.y += (Input[0].Size.w - Input[0].Size.y)  / Resolution.y/2;
        Output3.Pos.y += (Input[0].Size.w + Input[0].Size.y)  / Resolution.y/2;
        Output4.Pos.y += (Input[0].Size.w + Input[0].Size.y)  / Resolution.y/2;

        Output1.Color = Input[0].Color;
        Output2.Color = Input[0].Color;
        Output3.Color = Input[0].Color;
        Output4.Color = Input[0].Color;

        Output1.TexCoords = float2(Input[0].TexCoords.x,1);
        Output2.TexCoords = float2(Input[0].TexCoords.y,1);
        Output3.TexCoords = float2(Input[0].TexCoords.x,0);
        Output4.TexCoords = float2(Input[0].TexCoords.y,0);

        OutputStream.Append( Output1 );
        OutputStream.Append( Output3 );
        OutputStream.Append( Output2 );
        OutputStream.Append( Output4 );
    }
}