1. FPS調整クラス作成
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using System.Diagnostics; | |
namespace WpfApplication1 | |
{ | |
/// <summary> | |
/// フレーム調整 | |
/// </summary> | |
public class FpsTicker : Stopwatch | |
{ | |
public double Fps { get; private set; } | |
public int SkipTimes { get; private set; } | |
public double ElpasedSec { get { return ElapsedTicks / (double)Stopwatch.Frequency; } } | |
private double prevSec = 0.0; | |
/// <summary> | |
/// 開始 | |
/// </summary> | |
public new void Start() | |
{ | |
SkipTimes = 0; | |
prevSec = ElpasedSec; | |
base.Start(); | |
} | |
/// <summary> | |
/// フレーム待ち処理 | |
/// </summary> | |
/// <param name="fps"></param> | |
/// <returns>true:描画実行 false:描画スキップ</returns> | |
public bool Wait(int fps = 60) | |
{ | |
double waitSec = 1.0 / fps; | |
double nowSec = ElpasedSec; | |
double diffSec = nowSec - prevSec; | |
if (diffSec > waitSec) | |
{ | |
SkipTimes++; | |
prevSec = nowSec; | |
return false; | |
} | |
SkipTimes = 0; | |
while (diffSec < waitSec) | |
{ | |
nowSec = ElpasedSec; | |
diffSec = nowSec - prevSec; | |
} | |
prevSec = nowSec - (diffSec - waitSec); | |
Fps = 1.0 / diffSec; | |
return true; | |
} | |
public override string ToString() | |
{ | |
return string.Format("{0:#0.00} ({1})", Fps, SkipTimes); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using System.Windows; | |
using System.Windows.Controls; | |
using System.Windows.Interop; | |
using System.Windows.Media; | |
using System.Windows.Threading; | |
using System.Diagnostics; | |
using DxLibDLL; | |
namespace WpfApplication1 | |
{ | |
public class DxLibImage : D3DImage | |
{ | |
private DX.SetRestoreGraphCallbackCallback RestoreGraphCallback; | |
private FpsTicker fpsTicker = new FpsTicker(); | |
public event EventHandler Reset; | |
public event EventHandler Update; | |
public event EventHandler Render; | |
public int BufferWidth { get; set; } | |
public int BufferHeight { get; set; } | |
public string Fps { get { return fpsTicker.ToString(); } } | |
/// <summary> | |
/// コンストラクタ | |
/// </summary> | |
public DxLibImage() | |
{ | |
BufferWidth = 800; | |
BufferHeight = 600; | |
} | |
/// <summary> | |
/// DxLibの初期化 | |
/// </summary> | |
public void Init_DxLib() | |
{ | |
if (DX.DxLib_IsInit() == DX.TRUE) | |
DX.DxLib_End(); | |
HwndSource hwnd = new HwndSource(0, 0, 0, 0, 0, "DxLib", IntPtr.Zero); | |
DX.SetUserWindow(hwnd.Handle); // 描画ウィンドウの設定 | |
DX.SetGraphMode(BufferWidth, BufferHeight, 32); // グラフィックモードの設定 | |
DX.SetAlwaysRunFlag(DX.TRUE); // 非アクティブ時も処理続行 | |
DX.SetDrawScreen(DX.DX_SCREEN_BACK); // 描画先をバックバッファへ設定 | |
DX.SetUseFPUPreserveFlag(DX.TRUE); // FPUの精度を落とさない | |
DX.SetWaitVSyncFlag(DX.FALSE); // VSync同期を無効 | |
DX.SetOutApplicationLogValidFlag(DX.FALSE); // ログ出力停止 | |
DX.SetDoubleStartValidFlag(DX.TRUE); // 多重起動を許可 | |
DX.SetUseIMEFlag(DX.TRUE); // IMEを有効 | |
DX.SetBackgroundColor(0, 0, 0); | |
if (DX.DxLib_Init() == -1) | |
{ | |
throw new Exception("Dxlib_Init"); | |
} | |
// GC対策(不要?) | |
DX.SetUseGraphBaseDataBackup(DX.FALSE); // 自分ででデバイスロスト時の処理を行う | |
RestoreGraphCallback = RestoreGraph; | |
DX.SetRestoreGraphCallback(RestoreGraphCallback); // デバイスリセット時のイベントを設定 | |
// メインループ | |
ComponentDispatcher.ThreadIdle += ComponentDispatcher_ThreadIdle; | |
// 描画ループ | |
CompositionTarget.Rendering += CompositionTarget_Rendering; | |
IsFrontBufferAvailableChanged += d3dImage_IsFrontBufferAvailableChanged; | |
SetBackBuffer(); | |
fpsTicker.Start(); | |
} | |
/// <summary> | |
/// メインループ | |
/// </summary> | |
/// <param name="sender"></param> | |
/// <param name="e"></param> | |
void ComponentDispatcher_ThreadIdle(object sender, EventArgs e) | |
{ | |
OnUpdate(); | |
if (fpsTicker.Wait()) | |
{ | |
DX.ClearDrawScreen(); | |
OnRender(); | |
DX.ScreenFlip(); | |
} | |
} | |
/// <summary> | |
/// デバイスリセット発生 | |
/// </summary> | |
void RestoreGraph() | |
{ | |
OnReset(); | |
} | |
/// <summary> | |
/// バックバッファの設定 | |
/// </summary> | |
void SetBackBuffer() | |
{ | |
Lock(); | |
SetBackBuffer(D3DResourceType.IDirect3DSurface9, DX.GetUseDirect3D9BackBufferSurface()); | |
Unlock(); | |
} | |
/// <summary> | |
/// 表示の更新 | |
/// </summary> | |
/// <param name="sender"></param> | |
/// <param name="e"></param> | |
void CompositionTarget_Rendering(object sender, EventArgs e) | |
{ | |
try | |
{ | |
if (IsFrontBufferAvailable) | |
{ | |
Lock(); | |
SetBackBuffer(D3DResourceType.IDirect3DSurface9, DX.GetUseDirect3D9BackBufferSurface()); | |
AddDirtyRect(new Int32Rect(0, 0, PixelWidth, PixelHeight)); | |
Unlock(); | |
} | |
} | |
catch (Exception ex) | |
{ | |
Trace.WriteLine(ex.ToString()); | |
} | |
} | |
/// <summary> | |
/// フロントバッファの更新 | |
/// </summary> | |
/// <param name="sender"></param> | |
/// <param name="e"></param> | |
void d3dImage_IsFrontBufferAvailableChanged(object sender, DependencyPropertyChangedEventArgs e) | |
{ | |
fpsTicker.Stop(); | |
if (IsFrontBufferAvailable) | |
{ | |
CompositionTarget.Rendering += CompositionTarget_Rendering; | |
} | |
else | |
{ | |
CompositionTarget.Rendering -= CompositionTarget_Rendering; | |
} | |
fpsTicker.Start(); | |
} | |
/// <summary> | |
/// デバイスロスト発生 | |
/// </summary> | |
public virtual void OnReset() | |
{ | |
if (Reset != null) | |
Reset(null, EventArgs.Empty); | |
} | |
/// <summary> | |
/// プログラム更新処理 | |
/// </summary> | |
public virtual void OnUpdate() | |
{ | |
if (Update != null) | |
Update(null, EventArgs.Empty); | |
} | |
/// <summary> | |
/// 描画処理 | |
/// </summary> | |
public virtual void OnRender() | |
{ | |
if (Render != null) | |
Render(null, EventArgs.Empty); | |
} | |
/// <summary> | |
/// DxLibの開放 | |
/// </summary> | |
public void End_DxLib() | |
{ | |
if (DX.DxLib_IsInit() != DX.TRUE) | |
return; | |
DX.DxLib_End(); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Window x:Class="WpfApplication1.MainWindow" | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:me="clr-namespace:WpfApplication1" | |
Title="MainWindow" Loaded="Window_Loaded" Closed="Window_Closed" SizeToContent="WidthAndHeight" ResizeMode="CanMinimize"> | |
<Canvas Width="800" Height="600"> | |
<Image> | |
<Image.Source> | |
<me:DxLibImage x:Name="dxImage" Render="dxImage_Render" Reset="dxImage_Reset" Update="dxImage_Update" /> | |
</Image.Source> | |
</Image> | |
<TextBlock x:Name="debugText" Height="600" Canvas.Left="600" TextWrapping="Wrap" Canvas.Top="0" Width="200" Foreground="Yellow" TextAlignment="Right"/> | |
</Canvas> | |
</Window> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using System.Windows; | |
using System.Windows.Controls; | |
using System.Windows.Data; | |
using System.Windows.Documents; | |
using System.Windows.Input; | |
using System.Windows.Media; | |
using System.Windows.Media.Imaging; | |
using System.Windows.Navigation; | |
using System.Windows.Shapes; | |
using System.Windows.Interop; | |
using System.Diagnostics; | |
using DxLibDLL; | |
namespace WpfApplication1 | |
{ | |
public partial class MainWindow : Window | |
{ | |
public MainWindow() | |
{ | |
InitializeComponent(); | |
} | |
private void Window_Loaded(object sender, RoutedEventArgs e) | |
{ | |
// DxLibの初期化 | |
dxImage.Init_DxLib(); | |
} | |
private void Window_Closed(object sender, EventArgs e) | |
{ | |
// DxLibの終了 | |
dxImage.End_DxLib(); | |
} | |
private void dxImage_Reset(object sender, EventArgs e) | |
{ | |
// グラフィックのリセット | |
} | |
private void dxImage_Update(object sender, EventArgs e) | |
{ | |
// プログラムの更新処理 | |
debugText.Text = dxImage.Fps; | |
} | |
private void dxImage_Render(object sender, EventArgs e) | |
{ | |
// 描画処理 | |
if (this.WindowState == WindowState.Minimized) | |
return; | |
DX.DrawBox(0, 0, 200, 200, DX.GetColor(255, 0, 0), DX.TRUE); | |
} | |
} | |
} |
超今更ですが
返信削除自分の環境ではInit前に
DX.SetUseDirect3DVersion(DX.DX_DIRECT3D_9EX);
を指定しないとBackBafferが取得できませんでした