30の代わりに60Fpsでゲームを実行しようとしています。ゲームは30fpsにロックされているので、60fpsに達する唯一の方法はフレーム補間です。補間フレームを追加するOpenGLフックスワップバッファ
補間部分については、OpenCVを使用するつもりですが、this pretty good articleが見つかりました。
このゲームではOpenGLを使用しています。いくつかの調査の後、私は、画面をつかむための最良の方法はSwapBuffer関数をフックすることであることが分かった。だから私は、画面をつかむためにゲームをフックし、リアルタイムでゲームをストリーミングするように他のアプリに送ります。そして、60 FPSに達するように補間フレームを追加します(あなたが良いアイデアを持っているなら、 open!)
新しいdllを書き始めました。私はC#でコーディングしていますが、EasyHookを選択してDLLを挿入しました。
フックがうまくいきました。
しかし、私は今、ゲームからスクリーンを取得する方法が全くわからないために立ち往生しています。
私はOpenGL.NetとSharpGLを使ってみましたが、glReadPixelを使うためにどのように実際のOpenGLコンテキストを取得すると思いますか?私はあなたがゲームのFPSを増やすことができます疑う
using System;
using System.Runtime.InteropServices;
namespace Hook
{
public class ServerInterface : MarshalByRefObject
{
public void IsInstalled(int clientPID)
{
Console.WriteLine("This programm has injected dll into process {0}.\r\n", clientPID);
}
public void ReportMessage(int clientPID, string message)
{
Console.WriteLine(message);
}
public void ReportException(Exception e)
{
Console.WriteLine("The target process has reported an error:\r\n" + e.ToString());
}
public void Ping()
{
Console.WriteLine("Ping !");
}
}
//Point d'entrée
public class InjectionEntryPoint : EasyHook.IEntryPoint
{
//Serveur :
ServerInterface server = null;
public InjectionEntryPoint(EasyHook.RemoteHooking.IContext context, string channelName)
{
//Constructeur
//Objectif : vérifier si la communication entre les deux programmes peut etre établit
server = EasyHook.RemoteHooking.IpcConnectClient<ServerInterface>(channelName);
server.Ping();
}
public void Run(EasyHook.RemoteHooking.IContext context, string channelName)
{
try
{
var SwapBuffersHook = EasyHook.LocalHook.Create(EasyHook.LocalHook.GetProcAddress("opengl32.dll", "wglSwapBuffers"), new SwapBuffers_Delegate(SwapBuffers_Hook), this);
SwapBuffersHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
server.ReportMessage(EasyHook.RemoteHooking.GetCurrentProcessId(), "SwapBuffers Hooked");
}
catch (Exception ExtInfo)
{
server.ReportException(ExtInfo);
return;
}
server.IsInstalled(EasyHook.RemoteHooking.GetCurrentProcessId());
EasyHook.RemoteHooking.WakeUpProcess();
//Waiting years
while(true)
{
System.Threading.Thread.Sleep(10000);
}
// Finalise cleanup of hooks
EasyHook.LocalHook.Release();
}
//Deleguate
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
delegate IntPtr SwapBuffers_Delegate(IntPtr hdc);
//Original
[DllImport("opengl32.dll", CharSet = CharSet.Unicode, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
static extern IntPtr wglSwapBuffers(IntPtr hdc);
//Hook function
public IntPtr SwapBuffers_Hook(IntPtr hdc)
{
server.ReportMessage(EasyHook.RemoteHooking.GetCurrentProcessId(), "I'm in SwapBuffers =DDDD");
//Here I need to grab frames
//Return
return wglSwapBuffers(hdc);
}
}
}
また、コンテキスト作成プロセスにフックして情報を保存することもできます。しかし、既にバッファスワッププロセスに関わっているので、バッファスワップを実行するスレッドに正しいOpenGLコンテキストがすでにバインドされていてはいけませんか? – BDL