scene_video_render
2024-10-18
5
0
场景的渲染,其实就是对其下的所有对象引用计数加1,然后调用其对象的渲染函数,最后再引用计数减1.
static void scene_video_render(void *data, gs_effect_t *effect)
{
DARRAY(struct obs_scene_item *) remove_items;
struct obs_scene *scene = data;
struct obs_scene_item *item;
da_init(remove_items);
video_lock(scene);
if (!scene->is_group) {
update_transforms_and_prune_sources(scene, &remove_items.da,NULL);
}
gs_blend_state_push();
gs_reset_blend_state();
item = scene->first_item;
while (item) {
if (item->user_visible || transition_active(item->hide_transition)) {
render_item(item);
}
item = item->next;
}
gs_blend_state_pop();
video_unlock(scene);
for (size_t i = 0; i < remove_items.num; i++)
{
obs_sceneitem_release(remove_items.array[i]);
}
da_free(remove_items);
UNUSED_PARAMETER(effect);
}
所以渲染的过程其实就是各对象的渲染过程。
static inline void render_item(struct obs_scene_item *item)
{
GS_DEBUG_MARKER_BEGIN_FORMAT(GS_DEBUG_COLOR_ITEM, "Item: %s", obs_source_get_name(item->source));
if (item->item_render) {
uint32_t width = obs_source_get_width(item->source);
uint32_t height = obs_source_get_height(item->source);
if (!width || !height) {
goto cleanup;
}
uint32_t cx = calc_cx(item, width);
uint32_t cy = calc_cy(item, height);
if (cx && cy && gs_texrender_begin(item->item_render, cx, cy))
{
float cx_scale = (float)width / (float)cx;
float cy_scale = (float)height / (float)cy;
struct vec4 clear_color;
vec4_zero(&clear_color);
gs_clear(GS_CLEAR_COLOR, &clear_color, 0.0f, 0);
gs_ortho(0.0f, (float)width, 0.0f, (float)height, -100.0f, 100.0f);
gs_matrix_scale3f(cx_scale, cy_scale, 1.0f);
gs_matrix_translate3f(-(float)item->crop.left, -(float)item->crop.top, 0.0f);
if (item->user_visible && transition_active(item->show_transition))
{
const int cx =obs_source_get_width(item->source);
const int cy =obs_source_get_height(item->source);
obs_transition_set_size(item->show_transition,cx, cy);
obs_source_video_render(item->show_transition);
} else if (!item->user_visible &&transition_active(item->hide_transition))
{
const int cx =obs_source_get_width(item->source);
const int cy =obs_source_get_height(item->source);
obs_transition_set_size(item->hide_transition,cx, cy);
obs_source_video_render(item->hide_transition);
} else {
obs_source_set_texcoords_centered(item->source,true);
obs_source_video_render(item->source);
obs_source_set_texcoords_centered(item->source,false);
}
gs_texrender_end(item->item_render);
}
}
const bool previous = gs_set_linear_srgb(true);
gs_matrix_push();
gs_matrix_mul(&item->draw_transform);
if (item->item_render){
render_item_texture(item);
}
else if (item->user_visible && transition_active(item->show_transition)) {
const int cx = obs_source_get_width(item->source);
const int cy = obs_source_get_height(item->source);
obs_transition_set_size(item->show_transition, cx, cy);
obs_source_video_render(item->show_transition);
} else if (!item->user_visible &&transition_active(item->hide_transition)) {
const int cx = obs_source_get_width(item->source);
const int cy = obs_source_get_height(item->source);
obs_transition_set_size(item->hide_transition, cx, cy);
obs_source_video_render(item->hide_transition);
} else {
const bool centered =are_texcoords_centered(&item->draw_transform);
obs_source_set_texcoords_centered(item->source, centered);
obs_source_video_render(item->source);
obs_source_set_texcoords_centered(item->source, false);
}
gs_matrix_pop();
gs_set_linear_srgb(previous);
cleanup:
GS_DEBUG_MARKER_END();
}