キャプチャ後表示されるまで
@@ -4,15 +4,119 @@ | ||
4 | 4 | using System.Text; |
5 | 5 | using SlimMMDXDemoFramework; |
6 | 6 | using System.Windows.Forms; |
7 | +using MikuMikuDance.Core.Model; | |
8 | +using MikuMikuDance.Core.Motion; | |
9 | +using MikuMikuDance.SlimDX; | |
10 | +using SlimDX.Direct3D9; | |
11 | +using System.Drawing; | |
12 | +using System.IO; | |
13 | +using MikuMikuDance.SlimDX.Accessory; | |
14 | +using SlimDX; | |
15 | +using System.Runtime.InteropServices; | |
7 | 16 | |
8 | 17 | namespace SlimMMDXDemo2 |
9 | 18 | { |
19 | + [StructLayout(LayoutKind.Sequential)] | |
20 | + struct CustomVertex | |
21 | + { | |
22 | + public Vector4 Position; | |
23 | + public Vector2 Texture; | |
24 | + | |
25 | + public static VertexElement[] VertexElements = new[] | |
26 | + { | |
27 | + new VertexElement(0, 0, DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.PositionTransformed, 0), | |
28 | + new VertexElement(0, 16,DeclarationType.Float2,DeclarationMethod.Default,DeclarationUsage.TextureCoordinate,0), | |
29 | + VertexElement.VertexDeclarationEnd | |
30 | + }; | |
31 | + } | |
10 | 32 | class Demo2 : DemoFramework |
11 | 33 | { |
34 | + //モデル | |
35 | + MMDModel model; | |
36 | + //モーション | |
37 | + MMDMotion motion; | |
38 | + //スクリーンマネージャ | |
39 | + ScreenManager screenManager; | |
40 | + //画面貼りつけ用 | |
41 | + VertexBuffer vertex; | |
42 | + CustomVertex[] screenVertex; | |
43 | + VertexDeclaration vertexDec; | |
44 | + | |
12 | 45 | public Demo2(Control targetControl) |
13 | 46 | : base(targetControl) |
14 | 47 | { |
15 | 48 | |
16 | 49 | } |
50 | + protected override void LoadContent() | |
51 | + { | |
52 | + //トゥーンテクスチャのパスを準備(SlimMMDXではトゥーンフォルダを別に用意する必要がある) | |
53 | + string[] toonTexPath = new string[10]; | |
54 | + string baseDir = Path.GetDirectoryName(Application.ExecutablePath); | |
55 | + for (int i = 1; i <= 10; ++i) | |
56 | + { | |
57 | + toonTexPath[i - 1] = Path.Combine(baseDir, Path.Combine("toons", "toon" + i.ToString("00") + ".bmp")); | |
58 | + } | |
59 | + SlimMMDXCore.Setup(GraphicsDevice, toonTexPath); | |
60 | + //モデルの読み込み | |
61 | + model = SlimMMDXCore.Instance.LoadModelFromFile("models/Miku-metal.pmd"); | |
62 | + //モーションの読み込み | |
63 | + motion = SlimMMDXCore.Instance.LoadMotionFromFile("motions/TrueMyHeart.vmd"); | |
64 | + //モーションの登録 | |
65 | + model.AnimationPlayer.AddMotion("TrueMyHeart", motion, MMDMotionTrackOptions.UpdateWhenStopped); | |
66 | + //スクリーンマネージャの作成 | |
67 | + screenManager = new ScreenManager(TargetControl.Width, TargetControl.Height); | |
68 | + //スクリーンマネージャの登録 | |
69 | + SlimMMDXCore.Instance.ScreenManager = screenManager; | |
70 | + //スクリーンを画面に描画する用の頂点を作成 | |
71 | + screenVertex = new CustomVertex[6]; | |
72 | + screenVertex[0].Position = new Vector4(0, 0, 0.5f, 1.0f); | |
73 | + screenVertex[0].Texture = new Vector2(0, 0); | |
74 | + screenVertex[1].Position = new Vector4(TargetControl.Width, 0, 0.5f, 1.0f); | |
75 | + screenVertex[1].Texture = new Vector2(1, 0); | |
76 | + screenVertex[2].Position = new Vector4(TargetControl.Width, TargetControl.Height, 0.5f, 1.0f); | |
77 | + screenVertex[2].Texture = new Vector2(1, 1); | |
78 | + screenVertex[3].Position = new Vector4(0, 0, 0.5f, 1.0f); | |
79 | + screenVertex[3].Texture = new Vector2(0, 0); | |
80 | + screenVertex[4].Position = new Vector4(TargetControl.Width, TargetControl.Height, 0.5f, 1.0f); | |
81 | + screenVertex[4].Texture = new Vector2(1, 1); | |
82 | + screenVertex[5].Position = new Vector4(0, TargetControl.Height, 0.5f, 1.0f); | |
83 | + screenVertex[5].Texture = new Vector2(0, 1); | |
84 | + | |
85 | + vertex = new VertexBuffer(SlimMMDXCore.Instance.Device, 6 * Marshal.SizeOf(typeof(CustomVertex)), Usage.WriteOnly, VertexFormat.None, Pool.Managed); | |
86 | + DataStream stream = vertex.Lock(0, 0, LockFlags.None); | |
87 | + stream.WriteRange(screenVertex); | |
88 | + vertex.Unlock(); | |
89 | + vertexDec = new VertexDeclaration(SlimMMDXCore.Instance.Device, CustomVertex.VertexElements); | |
90 | + base.LoadContent(); | |
91 | + } | |
92 | + protected override void Update(float frameDelta) | |
93 | + { | |
94 | + SlimMMDXCore.Instance.Update(frameDelta); | |
95 | + base.Update(frameDelta); | |
96 | + } | |
97 | + protected override void Draw(float frameDelta) | |
98 | + { | |
99 | + //スクリーンキャプチャの開始 | |
100 | + screenManager.StartCapture(Color.CornflowerBlue); | |
101 | + //モデルの描画 | |
102 | + model.Draw(); | |
103 | + //スクリーンキャプチャの終了 | |
104 | + screenManager.EndCapture(); | |
105 | + //スクリーンの描画 | |
106 | + GraphicsDevice.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.CornflowerBlue, 1.0f, 0); | |
107 | + SlimMMDXCore.Instance.Device.VertexDeclaration = vertexDec; | |
108 | + SlimMMDXCore.Instance.Device.SetStreamSource(0, vertex, 0, Marshal.SizeOf(typeof(CustomVertex))); | |
109 | + | |
110 | + SlimMMDXCore.Instance.Device.SetRenderState(RenderState.AlphaBlendEnable, false); | |
111 | + SlimMMDXCore.Instance.Device.SetRenderState(RenderState.AlphaTestEnable, false); | |
112 | + SlimMMDXCore.Instance.Device.SetTexture(0, screenManager.Screen); | |
113 | + SlimMMDXCore.Instance.Device.DrawPrimitives(PrimitiveType.TriangleList, 0, 2); | |
114 | + base.Draw(frameDelta); | |
115 | + } | |
116 | + protected override void Dispose(bool disposeManagedResources) | |
117 | + { | |
118 | + SlimMMDXCore.Instance.Dispose(); | |
119 | + base.Dispose(disposeManagedResources); | |
120 | + } | |
17 | 121 | } |
18 | 122 | } |
@@ -16,11 +16,12 @@ | ||
16 | 16 | { |
17 | 17 | Application.EnableVisualStyles(); |
18 | 18 | Application.SetCompatibleTextRenderingDefault(false); |
19 | - using (Form1 form = new Form1()) | |
19 | + Form1 form = new Form1(); | |
20 | + using (Demo2 demo = new Demo2(form.pnlDraw)) | |
20 | 21 | { |
21 | - Demo2 demo = new Demo2(form.pnlDraw); | |
22 | 22 | demo.Run(); |
23 | 23 | } |
24 | + | |
24 | 25 | //SlimMMDXの解放処理 |
25 | 26 | foreach (var item in ObjectTable.Objects) |
26 | 27 | item.Dispose(); |
@@ -12,10 +12,10 @@ | ||
12 | 12 | /// </summary> |
13 | 13 | public class ScreenManager |
14 | 14 | { |
15 | - Texture screen; | |
16 | - Surface renderSurface; | |
17 | - Surface depthBuffer; | |
18 | - | |
15 | + Texture[] screen = new Texture[2]; | |
16 | + Surface[] renderSurface = new Surface[2]; | |
17 | + Surface[] depthBuffer = new Surface[2]; | |
18 | + int bufferIndex = 1; | |
19 | 19 | Surface oldTarget = null; |
20 | 20 | Surface oldDepth = null; |
21 | 21 |
@@ -23,7 +23,7 @@ | ||
23 | 23 | /// <summary> |
24 | 24 | /// このインスタンスが保持しているテクスチャ |
25 | 25 | /// </summary> |
26 | - public Texture Screen { get { return screen; } } | |
26 | + public Texture Screen { get { return screen[bufferIndex]; } } | |
27 | 27 | |
28 | 28 | /// <summary> |
29 | 29 | /// コンストラクタ |
@@ -41,9 +41,12 @@ | ||
41 | 41 | /// <param name="height">バックバッファ高さ</param> |
42 | 42 | public void Restore(int width, int height) |
43 | 43 | { |
44 | - screen = new Texture(SlimMMDXCore.Instance.Device, width, height, 1, Usage.RenderTarget, Format.X8R8G8B8, Pool.Default); | |
45 | - renderSurface = screen.GetSurfaceLevel(0); | |
46 | - depthBuffer = Surface.CreateDepthStencil(SlimMMDXCore.Instance.Device, width, height, Format.D16, MultisampleType.None, 0, true); | |
44 | + for (int i = 0; i < 2; i++) | |
45 | + { | |
46 | + screen[i] = new Texture(SlimMMDXCore.Instance.Device, width, height, 1, Usage.RenderTarget, Format.X8R8G8B8, Pool.Default); | |
47 | + renderSurface[i] = screen[i].GetSurfaceLevel(0); | |
48 | + depthBuffer[i] = Surface.CreateDepthStencil(SlimMMDXCore.Instance.Device, width, height, Format.D16, MultisampleType.None, 0, true); | |
49 | + } | |
47 | 50 | } |
48 | 51 | /// <summary> |
49 | 52 | /// スクリーンキャプチャスタート |
@@ -56,10 +59,11 @@ | ||
56 | 59 | //レンダリングターゲットを退避 |
57 | 60 | oldTarget = SlimMMDXCore.Instance.Device.GetRenderTarget(0); |
58 | 61 | oldDepth = SlimMMDXCore.Instance.Device.DepthStencilSurface; |
59 | - | |
62 | + | |
60 | 63 | //レンダリングターゲットを変更 |
61 | - SlimMMDXCore.Instance.Device.SetRenderTarget(0, renderSurface); | |
62 | - SlimMMDXCore.Instance.Device.DepthStencilSurface = depthBuffer; | |
64 | + SlimMMDXCore.Instance.Device.SetRenderTarget(0, renderSurface[bufferIndex]); | |
65 | + SlimMMDXCore.Instance.Device.DepthStencilSurface = depthBuffer[bufferIndex]; | |
66 | + bufferIndex = (bufferIndex + 1) % 2; | |
63 | 67 | |
64 | 68 | //レンダーターゲットをクリア |
65 | 69 | SlimMMDXCore.Instance.Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, clearColor, 1.0f, 0); |
@@ -74,6 +78,8 @@ | ||
74 | 78 | SlimMMDXCore.Instance.Device.DepthStencilSurface = oldDepth; |
75 | 79 | oldTarget.Dispose(); |
76 | 80 | oldDepth.Dispose(); |
81 | + oldDepth = null; | |
82 | + oldTarget = null; | |
77 | 83 | } |
78 | 84 | |
79 | 85 | } |
@@ -17,7 +17,7 @@ | ||
17 | 17 | Device device; |
18 | 18 | |
19 | 19 | protected Device GraphicsDevice { get { return device; } } |
20 | - | |
20 | + protected Control TargetControl { get { return targetControl; } } | |
21 | 21 | public DemoFramework(Control targetControl) |
22 | 22 | { |
23 | 23 | form = targetControl.FindForm(); |
@@ -74,9 +74,13 @@ | ||
74 | 74 | |
75 | 75 | public void Dispose() |
76 | 76 | { |
77 | - form.Dispose(); | |
77 | + Dispose(true); | |
78 | 78 | } |
79 | 79 | |
80 | 80 | #endregion |
81 | + protected virtual void Dispose(bool disposeManagedResources) | |
82 | + { | |
83 | + form.Dispose(); | |
84 | + } | |
81 | 85 | } |
82 | 86 | } |