OSDN Git Service

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