30 대신 60Fps로 게임을 실행하려고합니다. 게임은 30fps로 고정되어 있으므로 60fps에 도달 할 수있는 유일한 방법은 프레임 보간입니다.C# Opengl Hook 스왑 버퍼 보간 프레임 추가
보간 부분은 OpenCV를 사용하려고합니다. this pretty good article입니다.
이 게임은 OpenGL을 사용합니다. 몇 가지 조사를 한 후에, 나는 화면을 잡는 가장 좋은 방법은 SwapBuffer 함수를 연결하는 것이라고 발견했다. 그래서 게임을 연결하여 화면을 잡고 다른 앱으로 보내면 실시간으로 게임을 스트리밍하고 60 fps에 도달하는 보간 프레임을 추가합니다 (더 좋은 아이디어가 있다면 완전히 open!)
나는 새 DLL을 작성하기 시작했다. 저는 C#으로 코딩하고 있으며, EasyHook을 선택하여 DLL을 주입했습니다.
후킹이 잘 작동하고 있으며, 지금은 매우 멋지다. = D.
그러나 게임에서 화면을 잡는 방법을 전혀 알지 못해서 지금은 막혀 있습니다.
OpenGL.Net과 SharpGL을 사용해 보았지만 실제 OpenGL 컨텍스트를 잡아 glReadPixel을 사용한다고 가정합니다. 난 당신이 게임의 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