- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试以 60Fps 而不是 30Fps 运行游戏。游戏锁定为 30fps,因此我可以达到 60fps 的唯一方法是帧插值。
对于插值部分,我将使用 OpenCV,我找到了 this pretty good article .
此游戏使用 OpenGL。经过一番研究,我发现最好的抓屏方式是hook SwapBuffer函数。所以我选择 Hook 游戏来抓取屏幕并将它们发送到另一个应用程序,这将实时播放游戏并顺便添加插值帧以达到 60 FPS(如果你有更好的主意,我完全打开!)
我开始编写我的新 dll。我使用 C# 编写代码,并选择 EasyHook 来注入(inject)我的 DLL。
Hooking 运行良好,现在非常酷 =D。
但是,我现在卡住了,因为我完全不知道如何从游戏中抓取屏幕。
我尝试使用 OpenGL.Net和 SharpGL ,但我无法弄清楚我应该如何获取实际的 OpenGL 上下文以使用 glReadPixel!
这是我的实际代码:
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);
}
}
}
最佳答案
我怀疑您能否提高游戏的 FPS。顺便说一句,有一些可能性。
你在做什么是正确的方法。您只是错过了创建要显示的中间框架的 GL 代码(我建议使用当前的 GL 上下文在进程中创建它)。
问题是在执行 SwapBuffers
命令时显示视频帧。这是您 Hook 的那个,但问问自己和程序:为什么每秒调用 30 次 SwapBuffers
?
如果答案是“因为应用程序使用定时器挂起执行”,你就不能轻易解决这个问题:你的钩子(Hook)必须与应用程序一起工作,因此你需要了解应用程序如何休眠。
如果答案是“因为应用程序正在利用 WGL_EXT_swap_control”,那么您有一种可能性:
如何创建插值帧?如果您通过 CPU 进行操作,请将 glReadPixels 与后台缓冲区 (GL_BACK) 一起用作读取帧缓冲区(使用 glDrawBuffers)。这将下载帧缓冲区绑定(bind)的内容。然后使用混合方程得到插值像素。
关于C# Opengl Hook Swapbuffer 添加插值帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43877395/
我正在使用多线程 OpenGL 渲染到一个窗口中。如果我按下一个按钮,模型将旋转 5 秒。轮换后,我打印出 FPS。其余时间 OpenGL 什么都不做。模型不会随着时间的推移而改变,所有线程在旋转时都
我有一个 OpenGL 程序可以在我所有的计算机上运行,但只有一台。这是一款配备 Vista 64 和 Radeon HD4850 的台式机。问题似乎出在我对 SwapBuffers(hdc) 的
我正在主窗口中使用 OpenGL 创建一个 Win32 应用程序(不使用 GLUT)。我现在在 WM_PAINT 中有我的绘图代码,当我调用 swapBuffers 时,它必须使自己失效,因为它不断地
我发现 OpenGL 中的 SwapBuffers 将忙于等待,只要显卡未完成渲染或正在等待 V-Sync。 这对我来说是个问题,因为我不想在等待卡完成时浪费 100% 的 CPU 内核。我不是在写游
我正在寻找一种可移植方法来制作非阻塞 SwapBuffers(),即使 VSync 已激活。 换句话说,是否有可能收到事件通知或知道下一个 VSync 之前的延迟? 最佳答案 IIRC 此扩展可帮助:
Vsync 阻塞 SwapBuffers(),这正是我想要的。我的问题是,由于输入消息转到拥有窗口的同一个线程,因此在 SwapBuffers() 被阻止时进入的任何消息都不会立即处理,但只有在 vs
想象这样一种情况: 我使用双缓冲 我可以通过不调用 glClear() 来优化我的绘图代码,如果我假设后台缓冲区的状态与我离开它两个时的状态相同 swapBuffers()前。 我可以依赖这个假设吗?
我正在尝试以 60Fps 而不是 30Fps 运行游戏。游戏锁定为 30fps,因此我可以达到 60fps 的唯一方法是帧插值。 对于插值部分,我将使用 OpenCV,我找到了 this pretty
注意到 WebGL 中不存在 SwapBuffer 功能,如果是这种情况,我们如何在绘制调用中更改状态并在 WebGL 中绘制多个对象,WebGL 在什么时间点在内部调用 swapBuffer? 最佳
我编写了一个 OpenGL 应用程序,它会在某些机器上崩溃(在我自己的测试机器上运行:Windows 8、Windows 7、Windows Vista (x86) - 但在某些装有 Windows
我已经实现了GPUImage framework在我的 cocos2d 项目中,GPUImage 框架是一个 BSD 许可的 iOS 库,可让您将 GPU 加速滤镜和其他效果应用于图像、实时摄像机视频
好的,所以我在 Windows 上遇到了一些与 OpenGL 相关的线程问题。我正在使用 C# .NET 来包装 GL。我在 Windows7 x64 上。 所以我尝试了两种不同的测试。在每次测试中,
我是一名优秀的程序员,十分优秀!