OSDN Git Service

dbcd0c18ae80fc6f594434f914d0094940b1a245
[dtxmania/dtxmania.git] / FDK17プロジェクト / コード / 04.グラフィック / CTexture.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Text;\r
4 using System.Drawing;\r
5 using System.Drawing.Imaging;\r
6 using System.IO;\r
7 using System.Diagnostics;\r
8 using SlimDX;\r
9 using SlimDX.Direct3D9;\r
10 \r
11 namespace FDK\r
12 {\r
13         public class CTexture : IDisposable\r
14         {\r
15                 #region [ プロパティ ]\r
16 \r
17                 public bool b加算合成\r
18                 {\r
19                         get;\r
20                         set; \r
21                 }\r
22                 public float fZ軸中心回転\r
23                 {\r
24                         get;\r
25                         set;\r
26                 }\r
27                 public int n透明度\r
28                 {\r
29                         get\r
30                         {\r
31                                 return this._透明度;\r
32                         }\r
33                         set\r
34                         {\r
35                                 if( value < 0 )\r
36                                 {\r
37                                         this._透明度 = 0;\r
38                                 }\r
39                                 else if( value > 0xff )\r
40                                 {\r
41                                         this._透明度 = 0xff;\r
42                                 }\r
43                                 else\r
44                                 {\r
45                                         this._透明度 = value;\r
46                                 }\r
47                         }\r
48                 }\r
49                 public Size szテクスチャサイズ\r
50                 {\r
51                         get; \r
52                         protected set;\r
53                 }\r
54                 public Size sz画像サイズ\r
55                 {\r
56                         get;\r
57                         protected set;\r
58                 }\r
59                 public Texture texture\r
60                 {\r
61                         get;\r
62                         private set;\r
63                 }\r
64                 public Format Format\r
65                 {\r
66                         get;\r
67                         protected set;\r
68                 }\r
69                 public Vector3 vc拡大縮小倍率;\r
70                 #endregion\r
71 \r
72                 // コンストラクタ\r
73 \r
74                 public CTexture()\r
75                 {\r
76                         this.sz画像サイズ = new Size( 0, 0 );\r
77                         this.szテクスチャサイズ = new Size( 0, 0 );\r
78                         this._透明度 = 0xff;\r
79                         this.texture = null;\r
80                         this.cvPositionColoredVertexies = null;\r
81                         this.b加算合成 = false;\r
82                         this.fZ軸中心回転 = 0f;\r
83                         this.vc拡大縮小倍率 = new Vector3( 1f, 1f, 1f );\r
84 //                      this._txData = null;\r
85                 }\r
86                 \r
87                 /// <summary>\r
88                 /// <para>指定されたビットマップオブジェクトから Managed テクスチャを作成する。</para>\r
89                 /// <para>テクスチャのサイズは、BITMAP画像のサイズ以上、かつ、D3D9デバイスで生成可能な最小のサイズに自動的に調節される。\r
90                 /// その際、テクスチャの調節後のサイズにあわせた画像の拡大縮小は行わない。</para>\r
91                 /// <para>その他、ミップマップ数は 1、Usage は None、Pool は Managed、イメージフィルタは Point、ミップマップフィルタは\r
92                 /// None、カラーキーは 0xFFFFFFFF(完全なる黒を透過)になる。</para>\r
93                 /// </summary>\r
94                 /// <param name="device">Direct3D9 デバイス。</param>\r
95                 /// <param name="bitmap">作成元のビットマップ。</param>\r
96                 /// <param name="format">テクスチャのフォーマット。</param>\r
97                 /// <exception cref="CTextureCreateFailedException">テクスチャの作成に失敗しました。</exception>\r
98                 public CTexture( Device device, Bitmap bitmap, Format format )\r
99                         : this()\r
100                 {\r
101                         try\r
102                         {\r
103                                 this.Format = format;\r
104                                 this.sz画像サイズ = new Size( bitmap.Width, bitmap.Height );\r
105                                 this.szテクスチャサイズ = this.t指定されたサイズを超えない最適なテクスチャサイズを返す( device, this.sz画像サイズ );\r
106                                 this.rc全画像 = new Rectangle( 0, 0, this.sz画像サイズ.Width, this.sz画像サイズ.Height );\r
107 \r
108                                 using( var stream = new MemoryStream() )\r
109                                 {\r
110                                         bitmap.Save( stream, ImageFormat.Bmp );\r
111                                         stream.Seek( 0L, SeekOrigin.Begin );\r
112                                         int colorKey = unchecked( (int) 0xFF000000 );\r
113                                         this.texture = Texture.FromStream( device, stream, this.szテクスチャサイズ.Width, this.szテクスチャサイズ.Height, 1, Usage.None, format, poolvar, Filter.Point, Filter.None, colorKey );\r
114                                 }\r
115                         }\r
116                         catch ( Exception e )\r
117                         {\r
118                                 this.Dispose();\r
119                                 throw new CTextureCreateFailedException( "ビットマップからのテクスチャの生成に失敗しました。(" + e.Message + ")" );\r
120                         }\r
121                 }\r
122         \r
123                 /// <summary>\r
124                 /// <para>空の Managed テクスチャを作成する。</para>\r
125                 /// <para>テクスチャのサイズは、指定された希望サイズ以上、かつ、D3D9デバイスで生成可能な最小のサイズに自動的に調節される。\r
126                 /// その際、テクスチャの調節後のサイズにあわせた画像の拡大縮小は行わない。</para>\r
127                 /// <para>テクスチャのテクセルデータは未初期化。(おそらくゴミデータが入ったまま。)</para>\r
128                 /// <para>その他、ミップマップ数は 1、Usage は None、イメージフィルタは Point、ミップマップフィルタは None、\r
129                 /// カラーキーは 0x00000000(透過しない)になる。</para>\r
130                 /// </summary>\r
131                 /// <param name="device">Direct3D9 デバイス。</param>\r
132                 /// <param name="n幅">テクスチャの幅(希望値)。</param>\r
133                 /// <param name="n高さ">テクスチャの高さ(希望値)。</param>\r
134                 /// <param name="format">テクスチャのフォーマット。</param>\r
135                 /// <exception cref="CTextureCreateFailedException">テクスチャの作成に失敗しました。</exception>\r
136                 public CTexture( Device device, int n幅, int n高さ, Format format )\r
137                         : this( device, n幅, n高さ, format, Pool.Managed )\r
138                 {\r
139                 }\r
140                 \r
141                 /// <summary>\r
142                 /// <para>指定された画像ファイルから Managed テクスチャを作成する。</para>\r
143                 /// <para>利用可能な画像形式は、BMP, JPG, PNG, TGA, DDS, PPM, DIB, HDR, PFM のいずれか。</para>\r
144                 /// </summary>\r
145                 /// <param name="device">Direct3D9 デバイス。</param>\r
146                 /// <param name="strファイル名">画像ファイル名。</param>\r
147                 /// <param name="format">テクスチャのフォーマット。</param>\r
148                 /// <param name="b黒を透過する">画像の黒(0xFFFFFFFF)を透過させるなら true。</param>\r
149                 /// <exception cref="CTextureCreateFailedException">テクスチャの作成に失敗しました。</exception>\r
150                 public CTexture( Device device, string strファイル名, Format format, bool b黒を透過する )\r
151                         : this( device, strファイル名, format, b黒を透過する, Pool.Managed )\r
152                 {\r
153                 }\r
154                 public CTexture( Device device, byte[] txData, Format format, bool b黒を透過する )\r
155                         : this( device, txData, format, b黒を透過する, Pool.Managed )\r
156                 {\r
157                 }\r
158                 public CTexture( Device device, Bitmap bitmap, Format format, bool b黒を透過する )\r
159                         : this( device, bitmap, format, b黒を透過する, Pool.Managed )\r
160                 {\r
161                 }\r
162                 \r
163                 /// <summary>\r
164                 /// <para>空のテクスチャを作成する。</para>\r
165                 /// <para>テクスチャのサイズは、指定された希望サイズ以上、かつ、D3D9デバイスで生成可能な最小のサイズに自動的に調節される。\r
166                 /// その際、テクスチャの調節後のサイズにあわせた画像の拡大縮小は行わない。</para>\r
167                 /// <para>テクスチャのテクセルデータは未初期化。(おそらくゴミデータが入ったまま。)</para>\r
168                 /// <para>その他、ミップマップ数は 1、Usage は None、イメージフィルタは Point、ミップマップフィルタは None、\r
169                 /// カラーキーは 0x00000000(透過しない)になる。</para>\r
170                 /// </summary>\r
171                 /// <param name="device">Direct3D9 デバイス。</param>\r
172                 /// <param name="n幅">テクスチャの幅(希望値)。</param>\r
173                 /// <param name="n高さ">テクスチャの高さ(希望値)。</param>\r
174                 /// <param name="format">テクスチャのフォーマット。</param>\r
175                 /// <param name="pool">テクスチャの管理方法。</param>\r
176                 /// <exception cref="CTextureCreateFailedException">テクスチャの作成に失敗しました。</exception>\r
177                 public CTexture( Device device, int n幅, int n高さ, Format format, Pool pool )\r
178                         : this( device, n幅, n高さ, format, pool, Usage.None )\r
179                 {\r
180                 }\r
181                 \r
182                 public CTexture( Device device, int n幅, int n高さ, Format format, Pool pool, Usage usage )\r
183                         : this()\r
184                 {\r
185                         try\r
186                         {\r
187                                 this.Format = format;\r
188                                 this.sz画像サイズ = new Size( n幅, n高さ );\r
189                                 this.szテクスチャサイズ = this.t指定されたサイズを超えない最適なテクスチャサイズを返す( device, this.sz画像サイズ );\r
190                                 this.rc全画像 = new Rectangle( 0, 0, this.sz画像サイズ.Width, this.sz画像サイズ.Height );\r
191                 \r
192                                 using ( var bitmap = new Bitmap( 1, 1 ) )\r
193                                 {\r
194                                         using ( var graphics = Graphics.FromImage( bitmap ) )\r
195                                         {\r
196                                                 graphics.FillRectangle( Brushes.Black, 0, 0, 1, 1 );\r
197                                         }\r
198                                         using ( var stream = new MemoryStream() )\r
199                                         {\r
200                                                 bitmap.Save( stream, ImageFormat.Bmp );\r
201                                                 stream.Seek( 0L, SeekOrigin.Begin );\r
202 #if TEST_Direct3D9Ex\r
203                                                 pool = poolvar;\r
204 #endif\r
205                                                 // 中で更にメモリ読み込みし直していて無駄なので、Streamを使うのは止めたいところ\r
206                                                 this.texture = Texture.FromStream( device, stream, n幅, n高さ, 1, usage, format, pool, Filter.Point, Filter.None, 0 );\r
207                                         }\r
208                                 }\r
209                         }\r
210                         catch\r
211                         {\r
212                                 this.Dispose();\r
213                                 throw new CTextureCreateFailedException( string.Format( "テクスチャの生成に失敗しました。\n({0}x{1}, {2})", n幅, n高さ, format ) );\r
214                         }\r
215                 }\r
216 \r
217                 /// <summary>\r
218                 /// <para>画像ファイルからテクスチャを生成する。</para>\r
219                 /// <para>利用可能な画像形式は、BMP, JPG, PNG, TGA, DDS, PPM, DIB, HDR, PFM のいずれか。</para>\r
220                 /// <para>テクスチャのサイズは、画像のサイズ以上、かつ、D3D9デバイスで生成可能な最小のサイズに自動的に調節される。\r
221                 /// その際、テクスチャの調節後のサイズにあわせた画像の拡大縮小は行わない。</para>\r
222                 /// <para>その他、ミップマップ数は 1、Usage は None、イメージフィルタは Point、ミップマップフィルタは None になる。</para>\r
223                 /// </summary>\r
224                 /// <param name="device">Direct3D9 デバイス。</param>\r
225                 /// <param name="strファイル名">画像ファイル名。</param>\r
226                 /// <param name="format">テクスチャのフォーマット。</param>\r
227                 /// <param name="b黒を透過する">画像の黒(0xFFFFFFFF)を透過させるなら true。</param>\r
228                 /// <param name="pool">テクスチャの管理方法。</param>\r
229                 /// <exception cref="CTextureCreateFailedException">テクスチャの作成に失敗しました。</exception>\r
230                 public CTexture( Device device, string strファイル名, Format format, bool b黒を透過する, Pool pool )\r
231                         : this()\r
232                 {\r
233                         MakeTexture( device, strファイル名, format, b黒を透過する, pool );\r
234                 }\r
235                 public void MakeTexture( Device device, string strファイル名, Format format, bool b黒を透過する, Pool pool )\r
236                 {\r
237                         if ( !File.Exists( strファイル名 ) )               // #27122 2012.1.13 from: ImageInformation では FileNotFound 例外は返ってこないので、ここで自分でチェックする。わかりやすいログのために。\r
238                                 throw new FileNotFoundException( string.Format( "ファイルが存在しません。\n[{0}]", strファイル名 ) );\r
239 \r
240                         Byte[] _txData = File.ReadAllBytes( strファイル名 );\r
241                         MakeTexture( device, _txData, format, b黒を透過する, pool );\r
242                 }\r
243 \r
244                 public CTexture( Device device, byte[] txData, Format format, bool b黒を透過する, Pool pool )\r
245                         : this()\r
246                 {\r
247                         MakeTexture( device, txData, format, b黒を透過する, pool );\r
248                 }\r
249                 public void MakeTexture( Device device, byte[] txData, Format format, bool b黒を透過する, Pool pool )\r
250                 {\r
251                         try\r
252                         {\r
253                                 var information = ImageInformation.FromMemory( txData );\r
254                                 this.Format = format;\r
255                                 this.sz画像サイズ = new Size( information.Width, information.Height );\r
256                                 this.rc全画像 = new Rectangle( 0, 0, this.sz画像サイズ.Width, this.sz画像サイズ.Height );\r
257                                 int colorKey = ( b黒を透過する ) ? unchecked( (int) 0xFF000000 ) : 0;\r
258                                 this.szテクスチャサイズ = this.t指定されたサイズを超えない最適なテクスチャサイズを返す( device, this.sz画像サイズ );\r
259 #if TEST_Direct3D9Ex\r
260                                 pool = poolvar;\r
261 #endif\r
262                                 //                              lock ( lockobj )\r
263                                 //                              {\r
264                                 //Trace.TraceInformation( "CTexture() start: " );\r
265                                 this.texture = Texture.FromMemory( device, txData, this.sz画像サイズ.Width, this.sz画像サイズ.Height, 1, Usage.None, format, pool, Filter.Point, Filter.None, colorKey );\r
266                                 //Trace.TraceInformation( "CTexture() end:   " );\r
267                                 //                              }\r
268                         }\r
269                         catch\r
270                         {\r
271                                 this.Dispose();\r
272                                 // throw new CTextureCreateFailedException( string.Format( "テクスチャの生成に失敗しました。\n{0}", strファイル名 ) );\r
273                                 throw new CTextureCreateFailedException( string.Format( "テクスチャの生成に失敗しました。\n" ) );\r
274                         }\r
275                 }\r
276 \r
277                 public CTexture( Device device, Bitmap bitmap, Format format, bool b黒を透過する, Pool pool )\r
278                         : this()\r
279                 {\r
280                         MakeTexture( device, bitmap, format, b黒を透過する, pool );\r
281                 }\r
282                 public void MakeTexture( Device device, Bitmap bitmap, Format format, bool b黒を透過する, Pool pool )\r
283                 {\r
284                         try\r
285                         {\r
286                                 this.Format = format;\r
287                                 this.sz画像サイズ = new Size( bitmap.Width, bitmap.Height );\r
288                                 this.rc全画像 = new Rectangle( 0, 0, this.sz画像サイズ.Width, this.sz画像サイズ.Height );\r
289                                 int colorKey = ( b黒を透過する ) ? unchecked( (int) 0xFF000000 ) : 0;\r
290                                 this.szテクスチャサイズ = this.t指定されたサイズを超えない最適なテクスチャサイズを返す( device, this.sz画像サイズ );\r
291 #if TEST_Direct3D9Ex\r
292                                 pool = poolvar;\r
293 #endif\r
294                                 //Trace.TraceInformation( "CTExture() start: " );\r
295                                 unsafe  // Bitmapの内部データ(a8r8g8b8)を自前でゴリゴリコピーする\r
296                                 {\r
297                                         int tw =\r
298 #if TEST_Direct3D9Ex\r
299                                         288;            // 32の倍数にする(グラフによっては2のべき乗にしないとダメかも)\r
300 #else\r
301                                         this.sz画像サイズ.Width;\r
302 #endif\r
303 #if TEST_Direct3D9Ex\r
304                                         this.texture = new Texture( device, tw, this.sz画像サイズ.Height, 1, Usage.Dynamic, format, Pool.Default );\r
305 #else\r
306                                         this.texture = new Texture( device, this.sz画像サイズ.Width, this.sz画像サイズ.Height, 1, Usage.None, format, pool );\r
307 #endif\r
308                                         BitmapData srcBufData = bitmap.LockBits( new Rectangle( 0, 0, this.sz画像サイズ.Width, this.sz画像サイズ.Height ), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb );\r
309                                         DataRectangle destDataRectangle = texture.LockRectangle( 0, LockFlags.Discard );        // None\r
310 #if TEST_Direct3D9Ex\r
311                                         byte[] filldata = null;\r
312                                         if ( tw > this.sz画像サイズ.Width )\r
313                                         {\r
314                                                 filldata = new byte[ (tw - this.sz画像サイズ.Width) * 4 ];\r
315                                         }\r
316                                         for ( int y = 0; y < this.sz画像サイズ.Height; y++ )\r
317                                         {\r
318                                                 IntPtr src_scan0 = (IntPtr) ( (Int64) srcBufData.Scan0 + y * srcBufData.Stride );\r
319                                                 destDataRectangle.Data.WriteRange( src_scan0, this.sz画像サイズ.Width * 4  );\r
320                                                 if ( tw > this.sz画像サイズ.Width )\r
321                                                 {\r
322                                                         destDataRectangle.Data.WriteRange( filldata );\r
323                                                 }\r
324                                         }\r
325 #else\r
326                                         IntPtr src_scan0 = (IntPtr) ( (Int64) srcBufData.Scan0 );\r
327                                         destDataRectangle.Data.WriteRange( src_scan0, this.sz画像サイズ.Width * 4 * this.sz画像サイズ.Height );\r
328 #endif\r
329                                         texture.UnlockRectangle( 0 );\r
330                                         bitmap.UnlockBits( srcBufData );\r
331                                 }\r
332                                 //Trace.TraceInformation( "CTExture() End: " );\r
333                         }\r
334                         catch\r
335                         {\r
336                                 this.Dispose();\r
337                                 // throw new CTextureCreateFailedException( string.Format( "テクスチャの生成に失敗しました。\n{0}", strファイル名 ) );\r
338                                 throw new CTextureCreateFailedException( string.Format( "テクスチャの生成に失敗しました。\n" ) );\r
339                         }\r
340                 }\r
341                 // メソッド\r
342 \r
343                 /// <summary>\r
344                 /// テクスチャを 2D 画像と見なして描画する。\r
345                 /// </summary>\r
346                 /// <param name="device">Direct3D9 デバイス。</param>\r
347                 /// <param name="x">描画位置(テクスチャの左上位置の X 座標[dot])。</param>\r
348                 /// <param name="y">描画位置(テクスチャの左上位置の Y 座標[dot])。</param>\r
349                 public void t2D描画( Device device, int x, int y )\r
350                 {\r
351                         this.t2D描画( device, x, y, 1f, this.rc全画像 );\r
352                 }\r
353                 public void t2D描画( Device device, int x, int y, Rectangle rc画像内の描画領域 )\r
354                 {\r
355                         this.t2D描画( device, x, y, 1f, rc画像内の描画領域 );\r
356                 }\r
357                 public void t2D描画( Device device, float x, float y )\r
358                 {\r
359                         this.t2D描画( device, (int)x, (int)y, 1f, this.rc全画像 );\r
360                 }\r
361                 public void t2D描画( Device device, float x, float y, Rectangle rc画像内の描画領域 )\r
362                 {\r
363                         this.t2D描画( device, (int)x, (int)y, 1f, rc画像内の描画領域 );\r
364                 }\r
365                 public void t2D描画( Device device, int x, int y, float depth, Rectangle rc画像内の描画領域 )\r
366                 {\r
367                         if( this.texture == null )\r
368                                 return;\r
369 \r
370                         this.tレンダリングステートの設定( device );\r
371 \r
372                         if( this.fZ軸中心回転 == 0f )\r
373                         {\r
374                                 #region [ (A) 回転なし ]\r
375                                 //-----------------\r
376                                 float f補正値X = -0.5f;      // -0.5 は座標とピクセルの誤差を吸収するための座標補正値。(MSDN参照)\r
377                                 float f補正値Y = -0.5f;      //\r
378                                 float w = rc画像内の描画領域.Width;\r
379                                 float h = rc画像内の描画領域.Height;\r
380                                 float f左U値 = ( (float) rc画像内の描画領域.Left ) / ( (float) this.szテクスチャサイズ.Width );\r
381                                 float f右U値 = ( (float) rc画像内の描画領域.Right ) / ( (float) this.szテクスチャサイズ.Width );\r
382                                 float f上V値 = ( (float) rc画像内の描画領域.Top ) / ( (float) this.szテクスチャサイズ.Height );\r
383                                 float f下V値 = ( (float) rc画像内の描画領域.Bottom ) / ( (float) this.szテクスチャサイズ.Height );\r
384                                 this.color4.Alpha = ( (float) this._透明度 ) / 255f;\r
385                                 int color = this.color4.ToArgb();\r
386 \r
387                                 if( this.cvTransformedColoredVertexies == null )\r
388                                         this.cvTransformedColoredVertexies = new TransformedColoredTexturedVertex[ 4 ];\r
389 \r
390                                 // #27122 2012.1.13 from: 以下、マネージドオブジェクト(=ガベージ)の量産を抑えるため、new は使わず、メンバに値を1つずつ直接上書きする。\r
391 \r
392                                 this.cvTransformedColoredVertexies[ 0 ].Position.X = x + f補正値X;\r
393                                 this.cvTransformedColoredVertexies[ 0 ].Position.Y = y + f補正値Y;\r
394                                 this.cvTransformedColoredVertexies[ 0 ].Position.Z = depth;\r
395                                 this.cvTransformedColoredVertexies[ 0 ].Position.W = 1.0f;\r
396                                 this.cvTransformedColoredVertexies[ 0 ].Color = color;\r
397                                 this.cvTransformedColoredVertexies[ 0 ].TextureCoordinates.X = f左U値;\r
398                                 this.cvTransformedColoredVertexies[ 0 ].TextureCoordinates.Y = f上V値;\r
399 \r
400                                 this.cvTransformedColoredVertexies[ 1 ].Position.X = ( x + ( w * this.vc拡大縮小倍率.X ) ) + f補正値X;\r
401                                 this.cvTransformedColoredVertexies[ 1 ].Position.Y = y + f補正値Y;\r
402                                 this.cvTransformedColoredVertexies[ 1 ].Position.Z = depth;\r
403                                 this.cvTransformedColoredVertexies[ 1 ].Position.W = 1.0f;\r
404                                 this.cvTransformedColoredVertexies[ 1 ].Color = color;\r
405                                 this.cvTransformedColoredVertexies[ 1 ].TextureCoordinates.X = f右U値;\r
406                                 this.cvTransformedColoredVertexies[ 1 ].TextureCoordinates.Y = f上V値;\r
407 \r
408                                 this.cvTransformedColoredVertexies[ 2 ].Position.X = x + f補正値X;\r
409                                 this.cvTransformedColoredVertexies[ 2 ].Position.Y = ( y + ( h * this.vc拡大縮小倍率.Y ) ) + f補正値Y;\r
410                                 this.cvTransformedColoredVertexies[ 2 ].Position.Z = depth;\r
411                                 this.cvTransformedColoredVertexies[ 2 ].Position.W = 1.0f;\r
412                                 this.cvTransformedColoredVertexies[ 2 ].Color = color;\r
413                                 this.cvTransformedColoredVertexies[ 2 ].TextureCoordinates.X = f左U値;\r
414                                 this.cvTransformedColoredVertexies[ 2 ].TextureCoordinates.Y = f下V値;\r
415 \r
416                                 this.cvTransformedColoredVertexies[ 3 ].Position.X = ( x + ( w * this.vc拡大縮小倍率.X ) ) + f補正値X;\r
417                                 this.cvTransformedColoredVertexies[ 3 ].Position.Y = ( y + ( h * this.vc拡大縮小倍率.Y ) ) + f補正値Y;\r
418                                 this.cvTransformedColoredVertexies[ 3 ].Position.Z = depth;\r
419                                 this.cvTransformedColoredVertexies[ 3 ].Position.W = 1.0f;\r
420                                 this.cvTransformedColoredVertexies[ 3 ].Color = color;\r
421                                 this.cvTransformedColoredVertexies[ 3 ].TextureCoordinates.X = f右U値;\r
422                                 this.cvTransformedColoredVertexies[ 3 ].TextureCoordinates.Y = f下V値;\r
423                                 \r
424                                 device.SetTexture( 0, this.texture );\r
425                                 device.VertexFormat = TransformedColoredTexturedVertex.Format;\r
426                                 device.DrawUserPrimitives( PrimitiveType.TriangleStrip, 0, 2, this.cvTransformedColoredVertexies );\r
427                                 //-----------------\r
428                                 #endregion\r
429                         }\r
430                         else\r
431                         {\r
432                                 #region [ (B) 回転あり ]\r
433                                 //-----------------\r
434                                 float f補正値X = ( ( rc画像内の描画領域.Width % 2 ) == 0 ) ? -0.5f : 0f;     // -0.5 は座標とピクセルの誤差を吸収するための座標補正値。(MSDN参照)\r
435                                 float f補正値Y = ( ( rc画像内の描画領域.Height % 2 ) == 0 ) ? -0.5f : 0f;    // 3D(回転する)なら補正はいらない。\r
436                                 float f中央X = ( (float) rc画像内の描画領域.Width ) / 2f;\r
437                                 float f中央Y = ( (float) rc画像内の描画領域.Height ) / 2f;\r
438                                 float f左U値 = ( (float) rc画像内の描画領域.Left ) / ( (float) this.szテクスチャサイズ.Width );\r
439                                 float f右U値 = ( (float) rc画像内の描画領域.Right ) / ( (float) this.szテクスチャサイズ.Width );\r
440                                 float f上V値 = ( (float) rc画像内の描画領域.Top ) / ( (float) this.szテクスチャサイズ.Height );\r
441                                 float f下V値 = ( (float) rc画像内の描画領域.Bottom ) / ( (float) this.szテクスチャサイズ.Height );\r
442                                 this.color4.Alpha = ( (float) this._透明度 ) / 255f;\r
443                                 int color = this.color4.ToArgb();\r
444 \r
445                                 if( this.cvPositionColoredVertexies == null )\r
446                                         this.cvPositionColoredVertexies = new PositionColoredTexturedVertex[ 4 ];\r
447 \r
448                                 // #27122 2012.1.13 from: 以下、マネージドオブジェクト(=ガベージ)の量産を抑えるため、new は使わず、メンバに値を1つずつ直接上書きする。\r
449 \r
450                                 this.cvPositionColoredVertexies[ 0 ].Position.X = -f中央X + f補正値X;\r
451                                 this.cvPositionColoredVertexies[ 0 ].Position.Y = f中央Y + f補正値Y;\r
452                                 this.cvPositionColoredVertexies[ 0 ].Position.Z = depth;\r
453                                 this.cvPositionColoredVertexies[ 0 ].Color = color;\r
454                                 this.cvPositionColoredVertexies[ 0 ].TextureCoordinates.X = f左U値;\r
455                                 this.cvPositionColoredVertexies[ 0 ].TextureCoordinates.Y = f上V値;\r
456 \r
457                                 this.cvPositionColoredVertexies[ 1 ].Position.X = f中央X + f補正値X;\r
458                                 this.cvPositionColoredVertexies[ 1 ].Position.Y = f中央Y + f補正値Y;\r
459                                 this.cvPositionColoredVertexies[ 1 ].Position.Z = depth;\r
460                                 this.cvPositionColoredVertexies[ 1 ].Color = color;\r
461                                 this.cvPositionColoredVertexies[ 1 ].TextureCoordinates.X = f右U値;\r
462                                 this.cvPositionColoredVertexies[ 1 ].TextureCoordinates.Y = f上V値;\r
463 \r
464                                 this.cvPositionColoredVertexies[ 2 ].Position.X = -f中央X + f補正値X;\r
465                                 this.cvPositionColoredVertexies[ 2 ].Position.Y = -f中央Y + f補正値Y;\r
466                                 this.cvPositionColoredVertexies[ 2 ].Position.Z = depth;\r
467                                 this.cvPositionColoredVertexies[ 2 ].Color = color;\r
468                                 this.cvPositionColoredVertexies[ 2 ].TextureCoordinates.X = f左U値;\r
469                                 this.cvPositionColoredVertexies[ 2 ].TextureCoordinates.Y = f下V値;\r
470 \r
471                                 this.cvPositionColoredVertexies[ 3 ].Position.X = f中央X + f補正値X;\r
472                                 this.cvPositionColoredVertexies[ 3 ].Position.Y = -f中央Y + f補正値Y;\r
473                                 this.cvPositionColoredVertexies[ 3 ].Position.Z = depth;\r
474                                 this.cvPositionColoredVertexies[ 3 ].Color = color;\r
475                                 this.cvPositionColoredVertexies[ 3 ].TextureCoordinates.X = f右U値;\r
476                                 this.cvPositionColoredVertexies[ 3 ].TextureCoordinates.Y = f下V値;\r
477 \r
478                                 int n描画領域内X = x + ( rc画像内の描画領域.Width / 2 );\r
479                                 int n描画領域内Y = y + ( rc画像内の描画領域.Height / 2 );\r
480                                 var vc3移動量 = new Vector3( n描画領域内X - ( ( (float) device.Viewport.Width ) / 2f ), -( n描画領域内Y - ( ( (float) device.Viewport.Height ) / 2f ) ), 0f );\r
481                                 \r
482                                 var matrix = Matrix.Identity * Matrix.Scaling( this.vc拡大縮小倍率 );\r
483                                 matrix *= Matrix.RotationZ( this.fZ軸中心回転 );\r
484                                 matrix *= Matrix.Translation( vc3移動量 );\r
485                                 device.SetTransform( TransformState.World, matrix );\r
486 \r
487                                 device.SetTexture( 0, this.texture );\r
488                                 device.VertexFormat = PositionColoredTexturedVertex.Format;\r
489                                 device.DrawUserPrimitives( PrimitiveType.TriangleStrip, 2, this.cvPositionColoredVertexies );\r
490                                 //-----------------\r
491                                 #endregion\r
492                         }\r
493                 }\r
494 \r
495                 /// <summary>\r
496                 /// テクスチャを 3D 画像と見なして描画する。\r
497                 /// </summary>\r
498                 public void t3D描画( Device device, Matrix mat )\r
499                 {\r
500                         this.t3D描画( device, mat, this.rc全画像 );\r
501                 }\r
502                 public void t3D描画( Device device, Matrix mat, Rectangle rc画像内の描画領域 )\r
503                 {\r
504                         if( this.texture == null )\r
505                                 return;\r
506 \r
507                         float x = ( (float) rc画像内の描画領域.Width ) / 2f;\r
508                         float y = ( (float) rc画像内の描画領域.Height ) / 2f;\r
509                         float z = 0.0f;\r
510                         float f左U値 = ( (float) rc画像内の描画領域.Left ) / ( (float) this.szテクスチャサイズ.Width );\r
511                         float f右U値 = ( (float) rc画像内の描画領域.Right ) / ( (float) this.szテクスチャサイズ.Width );\r
512                         float f上V値 = ( (float) rc画像内の描画領域.Top ) / ( (float) this.szテクスチャサイズ.Height );\r
513                         float f下V値 = ( (float) rc画像内の描画領域.Bottom ) / ( (float) this.szテクスチャサイズ.Height );\r
514                         this.color4.Alpha = ( (float) this._透明度 ) / 255f;\r
515                         int color = this.color4.ToArgb();\r
516                         \r
517                         if( this.cvPositionColoredVertexies == null )\r
518                                 this.cvPositionColoredVertexies = new PositionColoredTexturedVertex[ 4 ];\r
519 \r
520                         // #27122 2012.1.13 from: 以下、マネージドオブジェクト(=ガベージ)の量産を抑えるため、new は使わず、メンバに値を1つずつ直接上書きする。\r
521 \r
522                         this.cvPositionColoredVertexies[ 0 ].Position.X = -x;\r
523                         this.cvPositionColoredVertexies[ 0 ].Position.Y = y;\r
524                         this.cvPositionColoredVertexies[ 0 ].Position.Z = z;\r
525                         this.cvPositionColoredVertexies[ 0 ].Color = color;\r
526                         this.cvPositionColoredVertexies[ 0 ].TextureCoordinates.X = f左U値;\r
527                         this.cvPositionColoredVertexies[ 0 ].TextureCoordinates.Y = f上V値;\r
528 \r
529                         this.cvPositionColoredVertexies[ 1 ].Position.X = x;\r
530                         this.cvPositionColoredVertexies[ 1 ].Position.Y = y;\r
531                         this.cvPositionColoredVertexies[ 1 ].Position.Z = z;\r
532                         this.cvPositionColoredVertexies[ 1 ].Color = color;\r
533                         this.cvPositionColoredVertexies[ 1 ].TextureCoordinates.X = f右U値;\r
534                         this.cvPositionColoredVertexies[ 1 ].TextureCoordinates.Y = f上V値;\r
535 \r
536                         this.cvPositionColoredVertexies[ 2 ].Position.X = -x;\r
537                         this.cvPositionColoredVertexies[ 2 ].Position.Y = -y;\r
538                         this.cvPositionColoredVertexies[ 2 ].Position.Z = z;\r
539                         this.cvPositionColoredVertexies[ 2 ].Color = color;\r
540                         this.cvPositionColoredVertexies[ 2 ].TextureCoordinates.X = f左U値;\r
541                         this.cvPositionColoredVertexies[ 2 ].TextureCoordinates.Y = f下V値;\r
542 \r
543                         this.cvPositionColoredVertexies[ 3 ].Position.X = x;\r
544                         this.cvPositionColoredVertexies[ 3 ].Position.Y = -y;\r
545                         this.cvPositionColoredVertexies[ 3 ].Position.Z = z;\r
546                         this.cvPositionColoredVertexies[ 3 ].Color = color;\r
547                         this.cvPositionColoredVertexies[ 3 ].TextureCoordinates.X = f右U値;\r
548                         this.cvPositionColoredVertexies[ 3 ].TextureCoordinates.Y = f下V値;\r
549 \r
550                         this.tレンダリングステートの設定( device );\r
551 \r
552                         device.SetTransform( TransformState.World, mat );\r
553                         device.SetTexture( 0, this.texture );\r
554                         device.VertexFormat = PositionColoredTexturedVertex.Format;\r
555                         device.DrawUserPrimitives( PrimitiveType.TriangleStrip, 2, this.cvPositionColoredVertexies );\r
556                 }\r
557 \r
558                 #region [ IDisposable 実装 ]\r
559                 //-----------------\r
560                 public void Dispose()\r
561                 {\r
562                         if( !this.bDispose完了済み )\r
563                         {\r
564                                 // テクスチャの破棄\r
565                                 if( this.texture != null )\r
566                                 {\r
567                                         this.texture.Dispose();\r
568                                         this.texture = null;\r
569                                 }\r
570 \r
571                                 this.bDispose完了済み = true;\r
572                         }\r
573                 }\r
574                 //-----------------\r
575                 #endregion\r
576 \r
577 \r
578                 // その他\r
579 \r
580                 #region [ private ]\r
581                 //-----------------\r
582                 protected int _透明度;\r
583                 private bool bDispose完了済み;\r
584                 protected PositionColoredTexturedVertex[] cvPositionColoredVertexies;\r
585                 protected TransformedColoredTexturedVertex[] cvTransformedColoredVertexies;\r
586                 private const Pool poolvar =                                                                                            // 2011.4.25 yyagi\r
587 #if TEST_Direct3D9Ex\r
588                         Pool.Default;\r
589 #else\r
590                         Pool.Managed;\r
591 #endif\r
592 //              byte[] _txData;\r
593                 static object lockobj = new object();\r
594 \r
595                 protected void tレンダリングステートの設定( Device device )\r
596                 {\r
597                         if( this.b加算合成 )\r
598                         {\r
599                                 device.SetRenderState( RenderState.AlphaBlendEnable, true );\r
600                                 device.SetRenderState( RenderState.SourceBlend, SlimDX.Direct3D9.Blend.SourceAlpha );                           // 5\r
601                                 device.SetRenderState( RenderState.DestinationBlend, SlimDX.Direct3D9.Blend.One );                                      // 2\r
602                         }\r
603                         else\r
604                         {\r
605                                 device.SetRenderState( RenderState.AlphaBlendEnable, true );\r
606                                 device.SetRenderState( RenderState.SourceBlend, SlimDX.Direct3D9.Blend.SourceAlpha );                           // 5\r
607                                 device.SetRenderState( RenderState.DestinationBlend, SlimDX.Direct3D9.Blend.InverseSourceAlpha );       // 6\r
608                         }\r
609                 }\r
610                 protected Size t指定されたサイズを超えない最適なテクスチャサイズを返す( Device device, Size sz指定サイズ )\r
611                 {\r
612                         bool b条件付きでサイズは2の累乗でなくてもOK = ( device.Capabilities.TextureCaps & TextureCaps.NonPow2Conditional ) != 0;\r
613                         bool bサイズは2の累乗でなければならない = ( device.Capabilities.TextureCaps & TextureCaps.Pow2 ) != 0;\r
614                         bool b正方形でなければならない = ( device.Capabilities.TextureCaps & TextureCaps.SquareOnly ) != 0;\r
615                         int n最大幅 = device.Capabilities.MaxTextureWidth;\r
616                         int n最大高 = device.Capabilities.MaxTextureHeight;\r
617                         var szサイズ = new Size( sz指定サイズ.Width, sz指定サイズ.Height );\r
618                         \r
619                         if( bサイズは2の累乗でなければならない && !b条件付きでサイズは2の累乗でなくてもOK )\r
620                         {\r
621                                 // 幅を2の累乗にする\r
622                                 int n = 1;\r
623                                 do\r
624                                 {\r
625                                         n *= 2;\r
626                                 }\r
627                                 while( n <= sz指定サイズ.Width );\r
628                                 sz指定サイズ.Width = n;\r
629 \r
630                                 // 高さを2の累乗にする\r
631                                 n = 1;\r
632                                 do\r
633                                 {\r
634                                         n *= 2;\r
635                                 }\r
636                                 while( n <= sz指定サイズ.Height );\r
637                                 sz指定サイズ.Height = n;\r
638                         }\r
639 \r
640                         if( sz指定サイズ.Width > n最大幅 )\r
641                                 sz指定サイズ.Width = n最大幅;\r
642 \r
643                         if( sz指定サイズ.Height > n最大高 )\r
644                                 sz指定サイズ.Height = n最大高;\r
645 \r
646                         if( b正方形でなければならない )\r
647                         {\r
648                                 if( szサイズ.Width > szサイズ.Height )\r
649                                 {\r
650                                         szサイズ.Height = szサイズ.Width;\r
651                                 }\r
652                                 else if( szサイズ.Width < szサイズ.Height )\r
653                                 {\r
654                                         szサイズ.Width = szサイズ.Height;\r
655                                 }\r
656                         }\r
657 \r
658                         return szサイズ;\r
659                 }\r
660 \r
661                 \r
662                 // 2012.3.21 さらなる new の省略作戦\r
663 \r
664                 protected Rectangle rc全画像;                                                                // テクスチャ作ったらあとは不変\r
665                 protected Color4 color4 = new Color4( 1f, 1f, 1f, 1f ); // アルファ以外は不変\r
666                 //-----------------\r
667                 #endregion\r
668         }\r
669 }\r