我对如何在游戏中实现重播感到好奇.
最初,我认为只会有一个游戏中所有玩家/动作的命令列表,然后它"重新玩"游戏并让引擎像往常一样渲染.但是,我已经看过FPS/RTS游戏中的重放,经过仔细检查,即使粒子和图形/听觉故障等内容也是一致的(这些故障通常是一致的).
那么这是怎么发生的呢.在固定摄像机角度游戏中,我可能只是将整个场景的每一帧写入存储的流然后只是重放流回来,但这对于允许您暂停和移动摄像机的游戏来说似乎不够周围.您必须在所有时间点存储场景中所有内容的位置(否?).因此对于像粒子这样的东西来说,这是推送的大量数据,这似乎是对游戏性能的重要影响.
这个问题与此类似
但是对于linux/X11.
更具体地说,我需要一种方法来捕获在X11显示器上运行的一个窗口(在windows中的alt-print屏幕的程序化等效物)的像素图像.
注意事项和要求:
1)即使在正在捕获的窗口顶部放置一个新窗口,像素图像仍应指向原始应用程序窗口而没有任何遮挡
2)不需要用户看到应用程序窗口,我只需要存储像素缓冲区/图像用于视频目的
我探索的其他替代方案是:
1)xvfb - 它可以工作,但它确实可以进行CPU渲染,这很慢并且浪费了很好的GPU
2)x11里面很多lxc - 理论上可以工作,但设置很复杂,我不确定它会很好地扩展,许多窗口被捕获
欢迎提出建议和想法
我使用基于RDP的Windows"远程客户端桌面"实用程序从我的笔记本电脑连接到我的桌面.它比TeamViewer等远程控制应用程序更快,看起来更好.
出于好奇,为什么RDP更好?
谢谢.
您是否有一些库可以将屏幕捕获为压缩视频文件或某些可以执行此操作的解决方案?
我知道如何使用GDI捕获屏幕,但它很慢(它几乎没有捕获10 fps)
我已经读过DirectX提供最佳速度.但在我开始学习DirectX之前,我想测试一个样本,看看它是否真的那么快.
我发现这个问题提供了一个示例代码来执行此操作:
void dump_buffer()
{
IDirect3DSurface9* pRenderTarget=NULL;
IDirect3DSurface9* pDestTarget=NULL;
const char file[] = "Pickture.bmp";
// sanity checks.
if (Device == NULL)
return;
// get the render target surface.
HRESULT hr = Device->GetRenderTarget(0, &pRenderTarget);
// get the current adapter display mode.
//hr = pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddisplaymode);
// create a destination surface.
hr = Device->CreateOffscreenPlainSurface(DisplayMde.Width,
DisplayMde.Height,
DisplayMde.Format,
D3DPOOL_SYSTEMMEM,
&pDestTarget,
NULL);
//copy the render target to the destination surface.
hr = Device->GetRenderTargetData(pRenderTarget, pDestTarget);
//save its contents to a bitmap file.
hr …Run Code Online (Sandbox Code Playgroud) 我想使用DirectX 10逐帧渲染视频.稍后将通过mencoder或ffmpeg等其他工具处理这些帧.
我在使用DX9时没有遇到任何问题D3DXSaveSurfaceToFile.
现在,在DX10中我发现了D3DX10SaveTextureToFile,但没有运气用它来保存我的后备箱.
我使用以下代码:
ID3D10Resource *backbufferRes;
_defaultRenderTargetView->GetResource(&backbufferRes);
D3D10_TEXTURE2D_DESC texDesc;
texDesc.ArraySize = 1;
texDesc.BindFlags = 0;
texDesc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
texDesc.Format = backbufferSurfDesc.Format;
texDesc.Height = backbufferSurfDesc.Height;
texDesc.Width = backbufferSurfDesc.Width;
texDesc.MipLevels = 1;
texDesc.MiscFlags = 0;
texDesc.SampleDesc = backbufferSurfDesc.SampleDesc;
texDesc.Usage = D3D10_USAGE_STAGING;
ID3D10Texture2D *texture;
HRESULT hr;
V( _device->CreateTexture2D(&texDesc, 0, &texture) );
_device->CopyResource(texture, backbufferRes);
V( D3DX10SaveTextureToFile(texture, D3DX10_IFF_DDS, filename) );
texture->Release();
Run Code Online (Sandbox Code Playgroud)
这会创建一个.dds图像,无法通过我所知道的任何类型的DDS视图/编辑器打开.
我的代码出了什么问题?
我的应用程序是捕获桌面屏幕(屏幕共享)并发送到其他设备.目前应用程序使用以下方法捕获屏幕
- 使用GDI(Bitblt)
- 使用DirectX(getFrontBufferData)
-
根据Windows版本和用例使用DXGI(桌面复制API),应用程序使用其中一个.
我正在寻找硬件加速api,它比现有的实现更快地完成这项工作.作为参考,我们在Mac OS中有一些东西点击这里.
在Windows中搜索硬件加速屏幕捕获之后,找到了以下一些选项:
- 基于GDI的捕获
- 它是一个常用的软件捕获库,它支持Windows 7中的硬件加速.
- 基于Directx的捕获
- 一些选项提出了以下参考文献中提到的direct3d9和direct3d11捕获.在directx方法中使用getfrontbufferData比gdi本身慢.
- 基于DXGI的捕获
- 它支持Windows 8和更高版本的Windows,它是我的应用程序中的direct3d11基础实现.
- 基于Windows媒体编码器9的捕获
参考文献:http://www.codeproject.com/Articles/5051/Various-methods-for-capturing-the-screen和
最快的屏幕捕获方法
但是这些引用看起来很旧,有没有最新版Windows中的此类功能.
前三种方法已经在我的应用程序中以某种方式使用.DXGI在某种程度上更好,因为它具有硬件加速(使用GPU).
我正在寻找一个类似于上部提到的mac应用程序的Windows应用程序/库.我们的用例很简单,可以在不影响系统性能的情况下以最佳方式捕获屏幕框架(我希望只有使用GPU才能实现,这将节省cpu周期).
使用位图对我来说是一个很新的事情,所以我一直在努力学习我已经阅读过的在线教程和策略.基本上我的目标是扫描屏幕上的特定RGB值.我相信这样做的步骤是捕获hBitmap中的屏幕,然后从中生成一个我可以扫描的RGB值数组.
我最初是用GetPixel开始的,但速度很慢.解决方案是使用GetDIBits生成RGB值数组.问题是它返回奇怪的,可能是随机的RGB值.
我正在使用以下从其他教程中找到的代码:
/* Globals */
int ScreenX = GetDeviceCaps(GetDC(0), HORZRES);
int ScreenY = GetDeviceCaps(GetDC(0), VERTRES);
BYTE* ScreenData = new BYTE[3*ScreenX*ScreenY];
void ScreenCap() {
HDC hdc = GetDC(GetDesktopWindow());
HDC hdcMem = CreateCompatibleDC (hdc);
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, ScreenX, ScreenY);
BITMAPINFOHEADER bmi = {0};
bmi.biSize = sizeof(BITMAPINFOHEADER);
bmi.biPlanes = 1;
bmi.biBitCount = 24;
bmi.biWidth = ScreenX;
bmi.biHeight = -ScreenY;
bmi.biCompression = BI_RGB;
bmi.biSizeImage = ScreenX * ScreenY;
SelectObject(hdcMem, hBitmap);
BitBlt(hdcMem, 0, 0, ScreenX, ScreenY, hdc, 0, 0, SRCCOPY);
GetDIBits(hdc, hBitmap, 0, …Run Code Online (Sandbox Code Playgroud) 我正在尝试在窗口上捕获屏幕的方法,从而决定最快的方法.最常见的是GDI方式.而且性能也不错.根据系统负载和静态/非静态屏幕内容,屏幕捕获率范围为27-47 fps(Windows 7,Intel i5 @2.6 GHz,8 GB RAM).
现在,使用DirectX前端缓冲区方法(使用GetFrontBufferData()API),性能相当,但稍微偏慢(我无法达到48 fps).
我仔细阅读了这篇文章:屏幕截图的最快方法,并尝试使用getRenderTarget()和getRenderTargetData()在接受的答案中建议,但正如评论中所建议的,我得到的只是一个黑色图像.这是我的完整代码,包括设备的初始配置:
IDirect3DSurface9* pRenderTarget=NULL;
IDirect3DSurface9* pDestTarget=NULL;
// sanity checks.
if (g_pd3dDevice == NULL){
return;
}
HRESULT hr;
// get the render target surface.
hr = g_pd3dDevice->GetRenderTarget(0, &pRenderTarget);
// get the current adapter display mode.
//hr = pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddisplaymode);
// create a destination surface.
hr = g_pd3dDevice->CreateOffscreenPlainSurface(1600, 900, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pDestTarget, NULL);
//copy the render target to the destination surface.
hr = g_pd3dDevice->GetRenderTargetData(pRenderTarget, pDestTarget);
D3DLOCKED_RECT lockedRect;
hr =pDestTarget->LockRect(&lockedRect,NULL, D3DLOCK_NO_DIRTY_UPDATE|D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY);
for( int …Run Code Online (Sandbox Code Playgroud) 我需要捕获给定窗口HWND句柄的窗口屏幕并将捕获结果存储在ID2D1Bitmap对象中,以便通过渲染目标绘制此位图。
我怎样才能达到这个结果?