显卡通常会把它们的输出写到我可以访问的内存中的某个地方吗?我一定要用司机吗?如果是的话,我可以使用OpenGL吗?
我想知道是否有可能在Linux上“捕获”VM的输出,它可以直接访问GPU,并且正在运行Windows。理想情况下,我可以直接从内存中访问输出,而无需接触GPU,因为这段代码可以在Linux主机上运行。
另一种选择是编写Windows驱动程序,该驱动程序读取GPU的输出并将其写入内存中的某个位置。然后,在Linux方面,程序可以读取这个内存。这似乎有点不可能,因为我不太确定如何让主机上的进程与来宾上的进程共享内存。
是否可以执行选项1,只读取内存中的输出?
发布于 2016-07-24 07:00:45
我不使用Linux编写代码,但在Windows中(您无论如何都是在模拟器中运行它),您可以使用WinAPI直接从3派对应用程序访问任何窗口甚至桌面的画布。有些GPU覆盖可能很难捕捉(特别是基于DirectX的),但目前为止,我的GL/GLSL没有问题。
如果您可以访问App,您可以直接使用glReadPixels从GL中提取图像(但这只适用于当前基于GL的呈现)。
glReadPixels的
如前所述,这必须在目标应用程序中直接实现,因此您需要有源代码或在正确的地点/时间注入代码。我用来截取这段代码:
虚空OpenGLscreen::屏幕截图(图形:TBitmap *bmp) { if (bmp==NULL)返回;int *dat=new intxs*ys,x,y,a,*p;if (dat==NULL)返回;bmp->HandleType=bmDIB;bmp->PixelFormat=pf32bit;if (bmp->宽度!=xs!=(bmp->高度!=ys) bmp->SetSize(xs,ys);如果(bmp->宽度=xs)&(bmp->高度=ys){ glReadPixels(0,0,xs,ys,GL_BGRA,GL_UNSIGNED_BYTE,dat);glFinish();for (a=0,y=ys-1;y>=0;y-) (p=(int*)bmp->ScanLiney,x=0;x在xs,ys是OpenGL窗口分辨率的地方,您可以忽略整个bmp内容(这是用于存储屏幕快照的VCL位图),也可以忽略for --它只是将图像从缓冲区复制到位图。所以重要的事情就是:
int *dat=new intxs*ys;//每个像素为32位int glReadPixels(0,0,xs,ys,GL_BGRA,GL_UNSIGNED_BYTE,dat);glFinish();
您需要在呈现完成后执行此代码,否则将获得未完成的或空的缓冲区。我在重绘/重绘事件之后使用它。如前所述,这将只获得GL呈现的内容,所以如果您的应用程序结合了GDI+OpenGL,那么最好使用下一种方法。bmp和画布scr重写为您的编程环境样式。此外,它还包含了一些_mmap_h代码块,它们只用于调试/跟踪内存指针,这些指针与我当时所面临的一些讨厌的编译器错误有关,我编写了以下文章。
用法很简单:
// globals scrcap;// init cap.init();// on屏幕截图cap.capture();//此处使用cap.bmp
如果您调用cap.init(),它将锁定整个windows桌面。如果您调用cap.init(window_handle),它将锁定特定的可视窗口/组件。若要从第3应用程序端获取窗口句柄,请参见:- [is ther a way an app can display a message without the use of messagebox API?](https://reverseengineering.stackexchange.com/a/11920/4709)对不起,它是在SE/RE上,而不是在SE/SO上,但是我在这里回答这个话题的内容被删除了。我用这个拍摄视频..。我的答案中的所有动画GIF都是由这个代码创建的。在我这个答案的底部还可以看到另一个例子:
- [Image to ASCII art conversion](https://stackoverflow.com/a/32987834/2521214)正如您所看到的,它也适用于媒体播放器经典的DirectX覆盖(即使是PrintScreen函数也不能正确地实现)。正如我所写的,我对此还没有任何问题。
必须从应用程序主线程(WNDPROC)调用Beware可视内容 WinAPI 调用,否则可能会发生严重问题,导致应用程序中任意位置的随机无关WinAPI调用异常。
https://stackoverflow.com/questions/38535809
复制相似问题