SlimDX DirectX11和文本精灵

问题描述:

我有一个SlimDX RenderForm(它继承了System.Windows.Forms.Form),其中我有一个Panel用于渲染地图。我想在地图上画出城市的名字。当用户放大和缩小地图时,文本不应该改变大小,但只需要将它们分开并靠得更近。我想到了5种方法可以做到这一点,并且每种方法都存在一个问题:SlimDX DirectX11和文本精灵

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

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

  3. 根据Label创建一个自定义类,设置类以允许透明背景,将面板设置为其父类,并在用户缩放时移动这些标签。问题:将标签赋予透明背景实际上并不会使其透明。这只是意味着它借用了Panel DirectX的背景颜色,并将自定义类的背景设置为该背景。我也尝试覆写OnPaintBackground函数,什么都不做,但是这只是给了标签黑色背景。

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

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

有没有我错过的解决方案或任何方式来使这些工作?

编辑:

基础上给出一个答案的建议,我现在试图用几何着色器基本上做一个子画面产生。但是当我只有6个不同的精灵时,绘制需要很长的时间。只有1个精灵可以接受,但是当我尝试添加更多时,它变得太多了。

+0

虽然我没有用SlimDX自己,它看起来像有在SlimDX.Toolkit包雪碧和字体渲染支持:https://code.google.com/p/slimdx/source/browse/ branches/lite/SlimDX.Toolkit /?r = 2195#SlimDX.Toolkit%2FFonts – megadan 2014-10-06 22:00:09

+0

是的,但我非常肯定,这些将不适用于DirectX-11的使用,但仅适用于DirectX-9,或者可能适用于DirectX -10 – KairisCharm 2014-10-07 15:11:14

+0

看着源代码,它们是用D3D11对象编写的,所以我不确定它们为什么不起作用。精灵只是在屏幕空间中定义的两个带纹理的三角形,没有透视投影。 D3D11中没有像D3DX9那样的内置sprite批处理。 – megadan 2014-10-07 16:17:53

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

就精灵配料而言,无需担心绘制顺序。丢弃每个像素周围的透明像素以防止深度写入。

小心地尝试在您要绘制的面板上放置透明的.Net控件。这将需要控制重绘每次你呈现你的场景导致.Net来限制你的帧速率(真的很差!)。如果需要,我将控件放置在我的d3d面板上,但它们不透明,不需要不断绘画。

希望有所帮助。让我知道你是否需要更多细节。

- 更新 -

让我定义2个术语。 “角色精灵”是一个包含单个角色图像的小精灵。 “字符串精灵”是字符精灵的集合,它移动并表现为一个大精灵,并出现几个字符。

用户定义字符串精灵在世界空间中的位置。字符串中的每个字符用于定义字符精灵。具体来说,每个字符精灵都会得到一个与字符串精灵位置相距的屏幕空间偏移量。这使得所有的精灵都可以放置在三维空间中,而不需要在屏幕空间中将所有字符放在彼此的顶部。 (float3),“纹理坐标”(float2),“纹理编号”(int),“屏幕空间偏移量”(float2)和“颜色”(float4)的点顶点。 。 “位置”对于字符精灵中的所有字符精灵都是相同的。“每个字符的纹理可以在单个图像中定义,其中每个字符精灵都被赋予适当的纹理坐标(我所做的)或纹理数组中。

enter image description here

- 更新 -

这里是我使用的文本(低质量)图像

enter image description here

这里是TEX的表。根据字符分配给字符精灵的坐标。

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几何体着色器的片段。有了这个着色器,以及适当的顶点和像素着色器,我可以虚拟地渲染整段文本,以影响性能。 > 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); 
    } 
} 
+0

有趣。我一定会考虑这个解决方案。我必须承认我之前从未做过粒子系统。我需要一些时间来解决它,但如果我这样做,我一定会将其标记为答案。谢谢。 – KairisCharm 2014-10-09 19:59:21

+0

我开始回来了。我一直忙于其他项目。 我在想这个,我在想你的解决方案的参数是什么?你有没有把它放在每个精灵都是不同的图像的地方?因为那是我需要的。一次有大约250张不同的图像,性能会好吗? – KairisCharm 2014-11-04 23:00:01

+0

我已经添加了一些更新的答案。 – 2014-11-05 19:47:47