云渲染、云游戏核心技术之视频hook引擎的OpenGL(一)

本文详细介绍了云渲染和云游戏技术中视频hook引擎如何利用OpenGL进行核心操作。首先,阐述了采集端hook的流程,包括在渲染前将数据拷贝到共享GPU。接着,展示了如何注册回调函数以hook到视频渲染过程。然后,讲解了如何创建共享GPU资源,并将其应用于数据传输。最后,探讨了将数据从本地GPU拷贝到共享GPU的步骤。源码示例展示了具体实现细节。
摘要由CSDN通过智能技术生成

云渲染、云游戏核心技术之视频hook引擎的OpenGL(一)


云端共享GPU资源

前言

云渲染客户端 采集的工作


提示:以下是本篇文章正文内容,下面案例可供参考

一、 采集端hook的流程

  1. 在渲染前一帧的数据拿到 拷贝同享GPU中去,编码从共享GPU中读取数据

在这里面有GPU同享时, 一些理论理解, 在向同享GPU中写入数据时 , GPU是不拷贝的 ,但是GPU读取这块GPU内存时,就会拷贝GPU到新GPU显存

二、hook到视频渲染前回调函数注册

	// 拿到窗口销毁时回调地址
    wgl_dc_proc = base_get_proc("wglDeleteContext");
    // 交换
	wgl_slb_proc = base_get_proc("wglSwapLayerBuffers");
	// 要显示到屏幕上后一帧数据地址
	wgl_sb_proc = base_get_proc("wglSwapBuffers");

	// 注册回调函数事务开始
	DetourTransactionBegin();

	RealSwapBuffers = SwapBuffers;
	// 注册回调函数  先处理我们函数, 在我们函数中调用原来的函数
	DetourAttach((PVOID *)&RealSwapBuffers, hook_swap_buffers);
	if (wgl_dc_proc) 
	{
		RealWglDeleteContext = (PFN_WglDeleteContext)wgl_dc_proc;
		DetourAttach((PVOID *)&RealWglDeleteContext,
			     hook_wgl_delete_context);
	}
	if (wgl_slb_proc) 
	{
		RealWglSwapLayerBuffers = (PFN_WglSwapLayerBuffers)wgl_slb_proc;
		DetourAttach((PVOID *)&RealWglSwapLayerBuffers,
			     hook_wgl_swap_layer_buffers);
	}
	if (wgl_sb_proc) 
	{
		RealWglSwapBuffers = (PFN_WglSwapBuffers)wgl_sb_proc;
		DetourAttach((PVOID *)&RealWglSwapBuffers,
			     hook_wgl_swap_buffers);
	}
	// 注册回调函数事务结束
const LONG error = DetourTransactionCommit();
	const bool success = error == NO_ERROR;

三、 共享GPU创建


static inline bool gl_shtex_init_d3d11_tex(void)
{
	IDXGIResource* dxgi_res;
	HRESULT hr;

	D3D11_TEXTURE2D_DESC desc = {0};
	desc.Width = data.cx;
	desc.Height = data.cy;
	desc.MipLevels = 1;
	desc.ArraySize = 1;
	desc.Format = data.format;
	desc.SampleDesc.Count = 1;
	desc.Usage = D3D11_USAGE_DEFAULT;
	desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
	desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;

	hr = ID3D11Device_CreateTexture2D(data.d3d11_device, &desc, NULL,
					  &data.d3d11_tex);
	if (FAILED(hr)) {
		printf("gl_shtex_init_d3d11_tex: failed to create texture" );
		return false;
	}
	//
	 
	// 设置D3D11的同享GPU模式
	hr = ID3D11Device_QueryInterface(data.d3d11_tex, &GUID_IDXGIResource,
		(void**)&dxgi_res);
	if (FAILED(hr))
	{
		printf("gl_shtex_init_d3d11_tex: failed to get IDXGIResource");
		return false;
	}
	//共享GPU模式
	hr = IDXGIResource_GetSharedHandle(dxgi_res, &data.handle);
	IDXGIResource_Release(dxgi_res);

	if (FAILED(hr))
	{
		printf("gl_shtex_init_d3d11_tex: failed to get shared handle");
		return false;
	}
	return true;
}

四、 拷贝数据到共享GPU中

static void gl_copy_backbuffer(GLuint dst)
{
	 
	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, data.fbo);
	if (gl_error("gl_copy_backbuffer", "failed to bind FBO")) 
	{
		return;
	}

	glBindTexture(GL_TEXTURE_2D, dst);
	if (gl_error("gl_copy_backbuffer", "failed to bind texture")) 
	{
		return;
	}

	glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
			       GL_TEXTURE_2D, dst, 0);
	if (gl_error("gl_copy_backbuffer", "failed to set frame buffer")) 
	{
		return;
	}

	glReadBuffer(GL_BACK);

	/* darkest dungeon fix */
	darkest_dungeon_fix = glGetError() == GL_INVALID_OPERATION  && _strcmpi(process_name, "Darkest.exe") == 0 ;

	glDrawBuffer(GL_COLOR_ATTACHMENT0);
	if (gl_error("gl_copy_backbuffer", "failed to set draw buffer")) 
	{
		return;
	}
    // 复制GPU数据 位置参数
	glBlitFramebuffer(0, data.cy, data.cx, 0, 0, 0, data.cx, data.cy,
			  GL_COLOR_BUFFER_BIT, GL_LINEAR);
	gl_error("gl_copy_backbuffer", "failed to blit");
}
 

 static void gl_shtex_capture(void)
 {

	 GLint last_fbo;
	 GLint last_tex;
	 // 1. 加锁 GPU的内存
	 jimglDXLockObjectsNV(data.gl_device, 1, &data.gl_dxobj);

	 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &last_fbo);
	 if (gl_error("gl_shtex_capture", "failed to get last fbo"))
	 {
		 return;
	 }

	 glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_tex);
	 if (gl_error("gl_shtex_capture", "failed to get last texture"))
	 {
		 return;
	 }
     // 拷贝GPU到共享GPU中去
	 gl_copy_backbuffer(data.texture);

	 glBindTexture(GL_TEXTURE_2D, last_tex);
	 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, last_fbo);

     // 拷贝到共享GPU中去了
	 jimglDXUnlockObjectsNV(data.gl_device, 1, &data.gl_dxobj);


	 IDXGISwapChain_Present(data.dxgi_swap, 0, 0);
	
	 
	 return;
	
 }

源码地址:https://github.com/chensongpoixs/cd3d10_d3d11_d3d12_dxgi_opengl/blob/master/OpenGL_Hook/capture_window/gl-capture.c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值