1、qt有个功能可以将控件提升为自定义控件,我在obs的主界面上放置4个OBSDisplay控件,后面可以通过程序来进行创建比较好;
2、搜索obs_display_add_draw_callback来了解这个函数到底在哪些地方被使用了;
3、void OBSQTDisplay::CreateDisplay()没给OBSQTDisplay创建的时候,都会将自己的指针挂到obs->data.first_display下;
4、在obs_video_thread中会调用render_displays对obs->data.first_display链表的display进行绘制;
5、render_display调用的callback->draw就是obs_display_add_draw_callback设置的回调函数;
6、接下来,callback函数是如何定位到该qt控件,并在该控件上面绘制的呢?且看后面分解,我们了解下RenderProgram这个函数是如何处理的
通过CreateProgramDisplay创建的display对象是在program中的;
另外一点,怎么绘制的问题:在Display创建的时候:
QTToGSWindow(winId(), info.window);
display = obs_display_create(&info);
void QTToGSWindow(WId windowId, gs_window &gswindow)
{
gswindow.hwnd = (HWND)windowId;
}
会将窗口句柄信息记录到成员变量OBSDisplay display中;这为后面的绘制提供句柄
注:display的背景色是在display->background_color = 0x4C4C4C;中设置的;
在render_display中,会先调用render_display_begin进行;
要看懂怎么绘制的代码,需要看看这篇文章:http://www.tuicool.com/articles/6N73Mz
用D3D11绘制最后使用device->curSwapChain->swap->Present(0, 0);来进行前后台的缓冲区交换,device_present是在:
void gs_present(void)
{
graphics_t *graphics = thread_graphics;
if (!gs_valid("gs_present"))
return;
graphics->exports.device_present(graphics->device);
}
中被调用的,该函数是在render_display_end中被调用的,render_display_end是在:
void render_display(struct obs_display *display)
{
if (!display || !display->enabled) return;
render_display_begin(display);
pthread_mutex_lock(&display->draw_callbacks_mutex);
for (size_t i = 0; i < display->draw_callbacks.num; i++) {
struct draw_callback *callback;
callback = display->draw_callbacks.array+i;
callback->draw(callback->param, display->cx, display->cy);
}
pthread_mutex_unlock(&display->draw_callbacks_mutex);
render_display_end();
}
中被调用的,也就是最后调用的;
在每个gs_swap_chain创建的时候,都会生成一个DXGI_SWAP_CHAIN_DESC对象;
hr = device->factory->CreateSwapChain(device->device, &swapDesc,
swap.Assign());