Skip to content

Instantly share code, notes, and snippets.

@mfakane
Created April 4, 2012 16:43
Show Gist options
  • Save mfakane/2303707 to your computer and use it in GitHub Desktop.
Save mfakane/2303707 to your computer and use it in GitHub Desktop.
XNA と MMDX をコンソールウィンドウで。
/*
* コンソールウィンドウで XNA をドライヴする
* MMDX を動かしてコンソールウィンドウ上に描画、または画像ファイルに出力
* ・XNA Windows Game を新規作成して、Game1.cs を消して、Program.cs にこれを突っ込む
* ・コンテントプロジェクトに任意のモデルと任意のモーションを追加 (既定ではモデルは Miku、モーションは TrueMyHeart となっているものを使用する)
*/
// tmp/ フォルダを作ってそこに png を出力する
// undef するとコンソールウィンドウ上に描画するだけ
#define RENDER_TO_FILE
using System;
#if RENDER_TO_FILE
using System.IO;
using System.Reflection;
#endif
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using MikuMikuDance.Core.Motion;
using MikuMikuDance.XNA;
namespace MikuMikuConsole
{
static class Program
{
[DllImport("user32")]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
/// <summary>
/// アプリケーションのメイン エントリー ポイントです。
/// </summary>
static void Main(string[] args)
{
var t = Console.Title;
Console.Title = Guid.NewGuid().ToString();
Thread.Sleep(5);
var handle = FindWindow(null, Console.Title);
Console.Title = t;
var services = new GameServiceContainer();
var pp = new PresentationParameters
{
BackBufferFormat = SurfaceFormat.Color,
BackBufferWidth = 640,
BackBufferHeight = 480,
DepthStencilFormat = DepthFormat.Depth24,
PresentationInterval = PresentInterval.Immediate,
IsFullScreen = false,
MultiSampleCount = 0,
RenderTargetUsage = RenderTargetUsage.DiscardContents,
DeviceWindowHandle = handle,
};
#if RENDER_TO_FILE
var path = Path.Combine(Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).AbsolutePath), "tmp");
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
#endif
using (var content = new ContentManager(services, "Content"))
using (var g = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, GraphicsProfile.HiDef, pp))
{
var gds = new GraphicsDeviceService(g);
services.AddService(typeof(IGraphicsDeviceService), gds);
services.AddService(typeof(IGraphicsDeviceManager), gds);
using (var mmdx = MMDXCore.Instance)
using (var model = mmdx.LoadModel("Miku", content))
{
var motion = mmdx.LoadMotion("TrueMyHeart", content);
var track = new MMDMotionTrack(motion, MMDMotionTrackOptions.UpdateWhenStopped);
const string key = "TrueMyHeart";
model.AnimationPlayer.AddMotion(key, track);
model.PhysicsManager.Reset();
track.Start();
for (var i = 0; i < track.MaxFrame; i++)
{
Console.Write("\rrendering {0} of {1}..." + new string(' ', 10), i, track.MaxFrame);
mmdx.Update(1 / 30f);
#if RENDER_TO_FILE
using (var rt = new RenderTarget2D
(
g,
pp.BackBufferWidth,
pp.BackBufferHeight,
false,
pp.BackBufferFormat,
pp.DepthStencilFormat,
pp.MultiSampleCount,
pp.RenderTargetUsage
))
{
g.SetRenderTarget(rt);
g.RasterizerState = RasterizerState.CullCounterClockwise;
g.DepthStencilState = DepthStencilState.DepthRead;
g.BlendState = BlendState.AlphaBlend;
g.Clear(Color.Transparent);
model.Draw();
g.SetRenderTarget(null);
using (var fs = File.OpenWrite(Path.Combine(path, i + ".png")))
rt.SaveAsPng(fs, pp.BackBufferWidth, pp.BackBufferHeight);
}
#else
g.RasterizerState = RasterizerState.CullCounterClockwise;
g.DepthStencilState = DepthStencilState.DepthRead;
g.BlendState = BlendState.AlphaBlend;
g.Clear(Color.Transparent);
model.Draw();
g.Present();
Thread.Sleep(1000 / 30);
#endif
}
}
}
}
class GraphicsDeviceService : IGraphicsDeviceService, IGraphicsDeviceManager
{
public GraphicsDeviceService(GraphicsDevice g)
{
this.GraphicsDevice = g;
}
public event EventHandler<EventArgs> DeviceCreated;
public event EventHandler<EventArgs> DeviceDisposing;
public event EventHandler<EventArgs> DeviceReset;
public event EventHandler<EventArgs> DeviceResetting;
public GraphicsDevice GraphicsDevice
{
get;
private set;
}
public bool BeginDraw()
{
return true;
}
public void CreateDevice()
{
}
public void EndDraw()
{
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment