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开源项目的理解,难免有错误的地方,如果有欢迎指出。
若有帮助幸甚。