【obs-studio开源项目从入门到放弃】预览窗口中source的UI操作绘制处理

文章目录

    • 前言
    • 获取鼠标位置
    • 绘制选中框
    • 裁剪源
    • 拉伸源
    • 移动源
    • 总结


前言

obs-studio项目简介和架构:https://blog.csdn.net/qq_33844311/article/details/121479224

在obs的预览窗口上可以对添加的源进行各种操作,比如移动、拉伸、裁切、复制。

下面主要分析一下这些操作的处理逻辑。

获取鼠标位置

获取当前鼠标位置信息

vec2 OBSBasicPreview::GetMouseEventPos(QMouseEvent *event)
{
	OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
	float pixelRatio = main->devicePixelRatioF();	//获取当前系统缩放系数
	float scale = pixelRatio / main->previewScale;
	vec2 pos;
	vec2_set(&pos,
		 (float(event->x()) - main->previewX / pixelRatio) * scale,
		 (float(event->y()) - main->previewY / pixelRatio) * scale);

	return pos;
}

绘制选中框

鼠标单击预览窗口添加的 source会绘制红色的选中框。在obs的渲染线程处理相关的绘制操作,具体参考下面的函数调用堆栈。

>	obs64.exe!DrawSquareAtPos(float x, float y)1567	C++
 	obs64.exe!OBSBasicPreview::DrawSelectedItem(obs_scene * scene, obs_scene_item * item, void * param)1841	C++
 	obs.dll!obs_scene_enum_items(obs_scene * scene, bool(*)(obs_scene *, obs_scene_item *, void *) callback, void * param)1939	C
 	obs64.exe!OBSBasicPreview::DrawSceneEditing()1957	C++	// 绘制红色的编辑框
 	obs64.exe!OBSBasic::RenderMain(void * data, unsigned int cx, unsigned int cy)4205	C++
 	obs.dll!render_display(obs_display * display)242	C
 	obs.dll!render_displays()99	C
 	obs.dll!obs_graphics_thread_loop(obs_graphics_context * context)1058	C
 	obs.dll!obs_graphics_thread(void * param)1130	C
 	w32-pthreads.dll!ptw32_threadStart(void * vthreadParms)225	C

裁剪源

鼠标单击选中源后按下alt并缩放源,可以裁切源的渲染大小。

 	obs64.exe!OBSBasicPreview::CropItem(const vec2 & pos)1276	C++
>	obs64.exe!OBSBasicPreview::mouseMoveEvent(QMouseEvent * event)1509	C++
 	[外部代码]	
 	obs64.exe!OBSApp::notify(QObject * receiver, QEvent * e)1621	C++
 	[外部代码]	
 	obs64.exe!OBSApp::notify(QObject * receiver, QEvent * e)1621	C++
 	[外部代码]	
 	obs64.exe!run_program(std::basic_fstream<char,std::char_traits<char>> & logFile, int argc, char * * argv)2214	C++
 	obs64.exe!main(int argc, char * * argv)2910	C++
 	obs64.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal)97	C++

拉伸源

通过选中源,拉伸改变源的渲染大小。

>	obs64.exe!OBSBasicPreview::StretchItem(const vec2 & pos)1391	C++
 	obs64.exe!OBSBasicPreview::mouseMoveEvent(QMouseEvent * event)1511	C++
 	[外部代码]	
 	obs64.exe!OBSApp::notify(QObject * receiver, QEvent * e)1621	C++
 	[外部代码]	
 	obs64.exe!OBSApp::notify(QObject * receiver, QEvent * e)1621	C++
 	[外部代码]	
 	obs64.exe!run_program(std::basic_fstream<char,std::char_traits<char>> & logFile, int argc, char * * argv)2214	C++
 	obs64.exe!main(int argc, char * * argv)2910	C++
 	obs64.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal)97	C++

移动源

鼠标选中源之后可以移动源的位置,处理逻辑参考下面的调用堆栈

>	obs64.exe!move_items(obs_scene * scene, obs_scene_item * item, void * param)913	C++
 	obs.dll!obs_scene_enum_items(obs_scene * scene, bool(*)(obs_scene *, obs_scene_item *, void *) callback, void * param)1939	C
 	obs64.exe!OBSBasicPreview::MoveItems(const vec2 & pos)951	C++
 	obs64.exe!OBSBasicPreview::mouseMoveEvent(QMouseEvent * event)1518	C++
 	[外部代码]	
 	obs64.exe!OBSApp::notify(QObject * receiver, QEvent * e)1621	C++
 	[外部代码]	
 	obs64.exe!OBSApp::notify(QObject * receiver, QEvent * e)1621	C++
 	[外部代码]	
 	obs64.exe!run_program(std::basic_fstream<char,std::char_traits<char>> & logFile, int argc, char * * argv)2214	C++
 	obs64.exe!main(int argc, char * * argv)2910	C++
 	obs64.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal)97	C++

关键处理函数 move_items

static bool move_items(obs_scene_t *scene, obs_sceneitem_t *item, void *param)
{
	if (obs_sceneitem_locked(item))
		return true;

	bool selected = obs_sceneitem_selected(item);
	vec2 *offset = reinterpret_cast<vec2 *>(param);

	if (obs_sceneitem_is_group(item) && !selected) {
		matrix4 transform;
		vec3 new_offset;
		vec3_set(&new_offset, offset->x, offset->y, 0.0f);

		obs_sceneitem_get_draw_transform(item, &transform);
		vec4_set(&transform.t, 0.0f, 0.0f, 0.0f, 1.0f);
		matrix4_inv(&transform, &transform);
		vec3_transform(&new_offset, &new_offset, &transform);
		obs_sceneitem_group_enum_items(item, move_items, &new_offset);
	}

	if (selected) {
		vec2 pos;
		obs_sceneitem_get_pos(item, &pos);		// 获取当前 item位置
		vec2_add(&pos, &pos, offset);			// 计算偏移后的 pos
		obs_sceneitem_set_pos(item, &pos);		// 更新 item位置
	}

	UNUSED_PARAMETER(scene);
	return true;
}

总结

以上都是个人工作当中对obs-studio开源项目的理解,难免有错误的地方,如果有欢迎指出。

若有帮助幸甚。


你可能感兴趣的:(obs-studio入门到放弃,音视频)