Revamp rendering system to allow custom rendering

Originally, the rendering system was designed to only display sources
and such, but I realized there would be a flaw; if you wanted to render
the main viewport in a custom way, or maybe even the entire application
as a graphics-based front end, you wouldn't have been able to do that.

Displays have now been separated in to viewports and displays.  A
viewport is used to store and draw sources, a display is used to handle
draw callbacks.  You can even use displays without using viewports to
draw custom render displays containing graphics calls if you wish, but
usually they would be used in combination with source viewports at
least.

This requires a tiny bit more work to create simple source displays, but
in the end its worth it for the added flexibility and options it brings.
This commit is contained in:
jp9000 2014-02-13 08:58:31 -07:00
parent 88519f0889
commit 515f44be8e
11 changed files with 533 additions and 218 deletions

View File

@ -142,6 +142,7 @@ set(libobs_libobs_SOURCES
obs-data.c
obs-module.c
obs-display.c
obs-viewport.c
obs-scene.c
obs-video.c)
set(libobs_libobs_HEADERS

View File

@ -15,64 +15,156 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#include "graphics/vec4.h"
#include "obs.h"
#include "obs-internal.h"
bool obs_display_init(struct obs_display *display,
struct gs_init_data *graphics_data)
{
pthread_mutex_init_value(&display->draw_callbacks_mutex);
if (graphics_data) {
display->swap = gs_create_swapchain(graphics_data);
if (!display->swap) {
blog(LOG_ERROR, "obs_display_init: Failed to "
"create swap chain");
return false;
}
display->cx = graphics_data->cx;
display->cy = graphics_data->cy;
}
if (pthread_mutex_init(&display->draw_callbacks_mutex, NULL) != 0) {
blog(LOG_ERROR, "obs_display_init: Failed to create mutex");
return false;
}
return true;
}
obs_display_t obs_display_create(struct gs_init_data *graphics_data)
{
struct obs_display *display = bzalloc(sizeof(struct obs_display));
if (graphics_data) {
display->swap = gs_create_swapchain(graphics_data);
if (!display->swap) {
if (!obs_display_init(display, graphics_data)) {
obs_display_destroy(display);
return NULL;
}
display = NULL;
}
return display;
}
void obs_display_free(obs_display_t display)
{
pthread_mutex_destroy(&display->draw_callbacks_mutex);
da_free(display->draw_callbacks);
if (display->swap) {
swapchain_destroy(display->swap);
display->swap = NULL;
}
}
void obs_display_destroy(obs_display_t display)
{
if (display) {
size_t i;
pthread_mutex_lock(&obs->data.displays_mutex);
da_erase_item(obs->data.displays, &display);
pthread_mutex_unlock(&obs->data.displays_mutex);
for (i = 0; i < MAX_CHANNELS; i++)
obs_source_release(display->channels[i]);
swapchain_destroy(display->swap);
obs_display_free(display);
bfree(display);
}
}
obs_source_t obs_display_getsource(obs_display_t display, uint32_t channel)
void obs_display_resize(obs_display_t display, uint32_t cx, uint32_t cy)
{
obs_source_t source;
assert(channel < MAX_CHANNELS);
if (!display) return;
source = display->channels[channel];
if (source)
obs_source_addref(source);
pthread_mutex_lock(&display->draw_callbacks_mutex);
return source;
display->cx = cx;
display->cy = cy;
display->size_changed = true;
pthread_mutex_unlock(&display->draw_callbacks_mutex);
}
void obs_display_setsource(obs_display_t display, uint32_t channel,
obs_source_t source)
void obs_display_add_draw_callback(obs_display_t display,
void (*draw)(void *param, uint32_t cx, uint32_t cy),
void *param)
{
struct obs_source *prev_source;
assert(channel < MAX_CHANNELS);
if (!display) return;
prev_source = display->channels[channel];
display->channels[channel] = source;
struct draw_callback data = {draw, param};
if (source)
obs_source_addref(source);
if (prev_source)
obs_source_release(prev_source);
pthread_mutex_lock(&display->draw_callbacks_mutex);
da_push_back(display->draw_callbacks, &data);
pthread_mutex_unlock(&display->draw_callbacks_mutex);
}
void obs_display_remove_draw_callback(obs_display_t display,
void (*draw)(void *param, uint32_t cx, uint32_t cy),
void *param)
{
if (!display) return;
struct draw_callback data = {draw, param};
pthread_mutex_lock(&display->draw_callbacks_mutex);
da_erase_item(display->draw_callbacks, &data);
pthread_mutex_unlock(&display->draw_callbacks_mutex);
}
static inline void render_display_begin(struct obs_display *display)
{
struct vec4 clear_color;
gs_load_swapchain(display ? display->swap : NULL);
if (display->size_changed) {
gs_resize(display->cx, display->cy);
display->size_changed = false;
}
gs_beginscene();
vec4_set(&clear_color, 0.3f, 0.0f, 0.0f, 1.0f);
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH | GS_CLEAR_STENCIL,
&clear_color, 1.0f, 0);
gs_enable_depthtest(false);
/* gs_enable_blending(false); */
gs_setcullmode(GS_NEITHER);
gs_ortho(0.0f, (float)obs->video.base_width,
0.0f, (float)obs->video.base_height, -100.0f, 100.0f);
gs_setviewport(0, 0, display->cx, display->cy);
}
static inline void render_display_end(struct obs_display *display)
{
gs_endscene();
gs_present();
}
void render_display(struct obs_display *display)
{
if (!display) 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(display);
}

View File

@ -35,8 +35,13 @@
#define NUM_TEXTURES 2
struct draw_callback {
void (*draw)(void *param, uint32_t cx, uint32_t cy);
void *param;
};
/* ------------------------------------------------------------------------- */
/* core */
/* modules */
struct obs_module {
char *name;
@ -46,6 +51,34 @@ struct obs_module {
extern void free_module(struct obs_module *mod);
/* ------------------------------------------------------------------------- */
/* viewports */
struct obs_viewport {
pthread_mutex_t channels_mutex;
obs_source_t channels[MAX_CHANNELS];
};
extern bool obs_viewport_init(struct obs_viewport *viewport);
extern void obs_viewport_free(struct obs_viewport *viewport);
/* ------------------------------------------------------------------------- */
/* displays */
struct obs_display {
bool size_changed;
uint32_t cx, cy;
swapchain_t swap;
pthread_mutex_t draw_callbacks_mutex;
DARRAY(struct draw_callback) draw_callbacks;
};
extern bool obs_display_init(struct obs_display *display,
struct gs_init_data *graphics_data);
extern void obs_display_free(struct obs_display *display);
/* ------------------------------------------------------------------------- */
/* core */
@ -68,6 +101,8 @@ struct obs_core_video {
uint32_t base_width;
uint32_t base_height;
struct obs_display main_display;
};
struct obs_core_audio {
@ -84,12 +119,13 @@ struct obs_core_data {
DARRAY(struct obs_output*) outputs;
DARRAY(struct obs_encoder*) encoders;
obs_source_t channels[MAX_CHANNELS];
pthread_mutex_t sources_mutex;
pthread_mutex_t displays_mutex;
pthread_mutex_t outputs_mutex;
pthread_mutex_t encoders_mutex;
struct obs_viewport main_viewport;
volatile bool valid;
};
@ -119,17 +155,6 @@ extern struct obs_core *obs;
extern void *obs_video_thread(void *param);
/* ------------------------------------------------------------------------- */
/* displays */
struct obs_display {
swapchain_t swap; /* can be NULL if just sound */
obs_source_t channels[MAX_CHANNELS];
/* TODO: sound output target */
};
/* ------------------------------------------------------------------------- */
/* sources */
@ -206,7 +231,7 @@ struct obs_output {
/* ------------------------------------------------------------------------- */
/* encoders */
struct obs_encoder_callback {
struct encoder_callback {
void (*new_packet)(void *param, struct encoder_packet *packet);
void *param;
};
@ -218,5 +243,5 @@ struct obs_encoder {
obs_data_t settings;
pthread_mutex_t data_callbacks_mutex;
DARRAY(struct obs_encoder_callback) data_callbacks;
DARRAY(struct encoder_callback) data_callbacks;
};

View File

@ -1,5 +1,5 @@
/******************************************************************************
Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
Copyright (C) 2013-2014 by Hugh Bailey <obs.jim@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -37,57 +37,8 @@ static void tick_sources(uint64_t cur_time, uint64_t *last_time)
*last_time = cur_time;
}
static inline void render_display_begin(struct obs_display *display)
{
struct vec4 clear_color;
uint32_t width, height;
gs_load_swapchain(display ? display->swap : NULL);
gs_getsize(&width, &height);
gs_beginscene();
vec4_set(&clear_color, 0.3f, 0.0f, 0.0f, 1.0f);
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH | GS_CLEAR_STENCIL,
&clear_color, 1.0f, 0);
gs_enable_depthtest(false);
/* gs_enable_blending(false); */
gs_setcullmode(GS_NEITHER);
gs_ortho(0.0f, (float)obs->video.base_width,
0.0f, (float)obs->video.base_height, -100.0f, 100.0f);
gs_setviewport(0, 0, width, height);
}
static inline void render_display_end(struct obs_display *display)
{
gs_endscene();
gs_present();
}
static void render_display(struct obs_display *display)
{
render_display_begin(display);
for (size_t i = 0; i < MAX_CHANNELS; i++) {
struct obs_source **p_source;
p_source = (display) ? display->channels+i :
obs->data.channels+i;
if (*p_source) {
if ((*p_source)->removed) {
obs_source_release(*p_source);
*p_source = NULL;
} else {
obs_source_video_render(*p_source);
}
}
}
render_display_end(display);
}
/* in obs-display.c */
extern void render_display(struct obs_display *display);
static inline void render_displays(void)
{
@ -105,7 +56,7 @@ static inline void render_displays(void)
pthread_mutex_unlock(&obs->data.displays_mutex);
/* render main display */
render_display(NULL);
render_display(&obs->video.main_display);
gs_leavecontext();
}
@ -119,17 +70,6 @@ static inline void set_render_size(uint32_t width, uint32_t height)
gs_setviewport(0, 0, width, height);
}
static inline void render_channels(void)
{
struct obs_core_data *data = &obs->data;
for (size_t i = 0; i < MAX_CHANNELS; i++) {
struct obs_source *source = data->channels[i];
if (source)
obs_source_video_render(source);
}
}
static inline void unmap_last_surface(struct obs_core_video *video)
{
if (video->mapped_surface) {
@ -148,7 +88,7 @@ static inline void render_main_texture(struct obs_core_video *video,
gs_clear(GS_CLEAR_COLOR, &clear_color, 1.0f, 0);
set_render_size(video->base_width, video->base_height);
render_channels();
obs_viewport_render(&obs->data.main_viewport);
video->textures_rendered[cur_texture] = true;
}

126
libobs/obs-viewport.c Normal file
View File

@ -0,0 +1,126 @@
/******************************************************************************
Copyright (C) 2014 by Hugh Bailey <obs.jim@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#include "obs.h"
#include "obs-internal.h"
bool obs_viewport_init(struct obs_viewport *viewport)
{
pthread_mutex_init_value(&viewport->channels_mutex);
if (pthread_mutex_init(&viewport->channels_mutex, NULL) != 0) {
blog(LOG_ERROR, "obs_viewport_init: Failed to create mutex");
return false;
}
return true;
}
obs_viewport_t obs_viewport_create(void)
{
struct obs_viewport *viewport = bzalloc(sizeof(struct obs_viewport));
if (!obs_viewport_init(viewport)) {
bfree(viewport);
viewport = NULL;
}
return viewport;
}
void obs_viewport_free(struct obs_viewport *viewport)
{
for (size_t i = 0; i < MAX_CHANNELS; i++)
obs_source_release(viewport->channels[i]);
memset(viewport->channels, 0, sizeof(viewport->channels));
pthread_mutex_destroy(&viewport->channels_mutex);
}
void obs_viewport_destroy(obs_viewport_t viewport)
{
if (viewport) {
obs_viewport_free(viewport);
bfree(viewport);
}
}
obs_source_t obs_viewport_getsource(obs_viewport_t viewport, uint32_t channel)
{
obs_source_t source;
assert(channel < MAX_CHANNELS);
if (!viewport) return NULL;
if (channel >= MAX_CHANNELS) return NULL;
pthread_mutex_lock(&viewport->channels_mutex);
source = viewport->channels[channel];
if (source)
obs_source_addref(source);
pthread_mutex_unlock(&viewport->channels_mutex);
return source;
}
void obs_viewport_setsource(obs_viewport_t viewport, uint32_t channel,
obs_source_t source)
{
struct obs_source *prev_source;
assert(channel < MAX_CHANNELS);
if (!viewport) return;
if (channel >= MAX_CHANNELS) return;
pthread_mutex_lock(&viewport->channels_mutex);
prev_source = viewport->channels[channel];
viewport->channels[channel] = source;
if (source)
obs_source_addref(source);
if (prev_source)
obs_source_release(prev_source);
pthread_mutex_unlock(&viewport->channels_mutex);
}
void obs_viewport_render(obs_viewport_t viewport)
{
if (!viewport) return;
pthread_mutex_lock(&viewport->channels_mutex);
for (size_t i = 0; i < MAX_CHANNELS; i++) {
struct obs_source *source;
source = viewport->channels[i];
if (source) {
if (source->removed) {
obs_source_release(source);
viewport->channels[i] = NULL;
} else {
obs_source_video_render(source);
}
}
}
pthread_mutex_unlock(&viewport->channels_mutex);
}

View File

@ -1,5 +1,5 @@
/******************************************************************************
Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
Copyright (C) 2013-2014 by Hugh Bailey <obs.jim@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -140,6 +140,12 @@ static bool obs_init_video(struct obs_video_info *ovi)
return false;
}
if (!obs_display_init(&video->main_display, NULL))
return false;
video->main_display.cx = ovi->window_width;
video->main_display.cy = ovi->window_height;
errorcode = pthread_create(&video->video_thread, NULL,
obs_video_thread, obs);
if (errorcode != 0)
@ -149,25 +155,33 @@ static bool obs_init_video(struct obs_video_info *ovi)
return true;
}
static void obs_free_video()
static void stop_video(void)
{
struct obs_core_video *video = &obs->video;
if (video->video) {
void *thread_retval;
if (video->video) {
video_output_stop(video->video);
if (video->thread_initialized) {
pthread_join(video->video_thread, &thread_retval);
video->thread_initialized = false;
}
}
}
static void obs_free_video(void)
{
struct obs_core_video *video = &obs->video;
if (video->video) {
obs_display_free(&video->main_display);
video_output_close(video->video);
video->video = NULL;
}
}
static void obs_free_graphics()
static void obs_free_graphics(void)
{
struct obs_core_video *video = &obs->video;
size_t i;
@ -248,6 +262,8 @@ static bool obs_init_data(void)
goto fail;
if (pthread_mutex_init(&data->encoders_mutex, &attr) != 0)
goto fail;
if (!obs_viewport_init(&data->main_viewport))
goto fail;
data->valid = true;
@ -263,8 +279,7 @@ static void obs_free_data(void)
data->valid = false;
for (i = 0; i < MAX_CHANNELS; i++)
obs_set_output_source(i, NULL);
obs_viewport_free(&data->main_viewport);
while (data->outputs.num)
obs_output_destroy(data->outputs.array[0]);
@ -303,7 +318,7 @@ static bool obs_init(void)
return obs_init_handlers();
}
bool obs_startup()
bool obs_startup(void)
{
bool success;
@ -334,6 +349,8 @@ void obs_shutdown(void)
da_free(obs->modal_ui_callbacks);
da_free(obs->modeless_ui_callbacks);
stop_video();
obs_free_data();
obs_free_video();
obs_free_graphics();
@ -349,6 +366,11 @@ void obs_shutdown(void)
obs = NULL;
}
bool obs_initialized(void)
{
return obs != NULL;
}
bool obs_reset_video(struct obs_video_info *ovi)
{
struct obs_core_video *video = &obs->video;
@ -535,21 +557,23 @@ bool obs_add_source(obs_source_t source)
obs_source_t obs_get_output_source(uint32_t channel)
{
struct obs_source *source;
assert(channel < MAX_CHANNELS);
source = obs->data.channels[channel];
obs_source_addref(source);
return source;
return obs_viewport_getsource(&obs->data.main_viewport, channel);
}
void obs_set_output_source(uint32_t channel, obs_source_t source)
{
struct obs_source *prev_source;
struct calldata params = {0};
assert(channel < MAX_CHANNELS);
prev_source = obs->data.channels[channel];
if (!obs) return;
if (channel >= MAX_CHANNELS) return;
struct obs_source *prev_source;
struct obs_viewport *viewport = &obs->data.main_viewport;
struct calldata params = {0};
pthread_mutex_lock(&viewport->channels_mutex);
prev_source = viewport->channels[channel];
calldata_setuint32(&params, "channel", channel);
calldata_setptr(&params, "prev_source", prev_source);
@ -558,14 +582,14 @@ void obs_set_output_source(uint32_t channel, obs_source_t source)
calldata_getptr(&params, "source", &source);
calldata_free(&params);
obs->data.channels[channel] = source;
viewport->channels[channel] = source;
if (source != prev_source) {
if (source)
obs_source_addref(source);
if (prev_source)
obs_source_release(prev_source);
}
pthread_mutex_unlock(&viewport->channels_mutex);
}
void obs_enum_outputs(bool (*enum_proc)(void*, obs_output_t), void *param)
@ -630,15 +654,48 @@ obs_source_t obs_get_source_by_name(const char *name)
effect_t obs_get_default_effect(void)
{
if (!obs) return NULL;
return obs->video.default_effect;
}
signal_handler_t obs_signalhandler(void)
{
if (!obs) return NULL;
return obs->signals;
}
proc_handler_t obs_prochandler(void)
{
if (!obs) return NULL;
return obs->procs;
}
void obs_add_draw_callback(
void (*draw)(void *param, uint32_t cx, uint32_t cy),
void *param)
{
if (!obs) return;
obs_display_add_draw_callback(&obs->video.main_display, draw, param);
}
void obs_remove_draw_callback(
void (*draw)(void *param, uint32_t cx, uint32_t cy),
void *param)
{
if (!obs) return;
obs_display_remove_draw_callback(&obs->video.main_display, draw, param);
}
void obs_resize(uint32_t cx, uint32_t cy)
{
if (!obs || !obs->video.video || !obs->video.graphics) return;
obs_display_resize(&obs->video.main_display, cx, cy);
}
void obs_render_main_viewport(void)
{
if (!obs) return;
obs_viewport_render(&obs->data.main_viewport);
}

View File

@ -33,6 +33,7 @@
/* opaque types */
struct obs_display;
struct obs_viewport;
struct obs_source;
struct obs_scene;
struct obs_scene_item;
@ -41,6 +42,7 @@ struct obs_encoder;
struct obs_service;
typedef struct obs_display *obs_display_t;
typedef struct obs_viewport *obs_viewport_t;
typedef struct obs_source *obs_source_t;
typedef struct obs_scene *obs_scene_t;
typedef struct obs_scene_item *obs_sceneitem_t;
@ -189,6 +191,9 @@ EXPORT bool obs_startup(void);
/** Releases all data associated with OBS and terminates the OBS context */
EXPORT void obs_shutdown(void);
/** @return true if the main OBS context has been initialized */
EXPORT bool obs_initialized(void);
/**
* Sets base video ouput base resolution/fps/format
*
@ -250,10 +255,13 @@ EXPORT bool obs_enum_transition_types(size_t idx, const char **id);
*/
EXPORT bool obs_enum_output_types(size_t idx, const char **id);
/** Gets the graphics context for this OBS context */
/** Gets the main graphics context for this OBS context */
EXPORT graphics_t obs_graphics(void);
/** Gets the main audio output handler for this OBS context */
EXPORT audio_t obs_audio(void);
/** Gets the main video output handler for this OBS context */
EXPORT video_t obs_video(void);
/**
@ -317,25 +325,83 @@ EXPORT signal_handler_t obs_signalhandler(void);
/** Returns the primary obs procedure handler */
EXPORT proc_handler_t obs_prochandler(void);
/** Adds a draw callback to the main render context */
EXPORT void obs_add_draw_callback(
void (*draw)(void *param, uint32_t cx, uint32_t cy),
void *param);
/** Removes a draw callback to the main render context */
EXPORT void obs_remove_draw_callback(
void (*draw)(void *param, uint32_t cx, uint32_t cy),
void *param);
/** Changes the size of the main viewport */
EXPORT void obs_resize(uint32_t cx, uint32_t cy);
/** Renders the main viewport */
EXPORT void obs_render_main_viewport(void);
/* ------------------------------------------------------------------------- */
/* Viewport context */
/**
* Creates a viewport context.
*
* A viewport can be used for things like separate previews, or drawing
* sources separately.
*/
EXPORT obs_viewport_t obs_viewport_create(void);
/** Destroys this viewport context */
EXPORT void obs_viewport_destroy(obs_viewport_t viewport);
/** Sets the source to be used for this viewport context. */
EXPORT void obs_viewport_setsource(obs_viewport_t viewport, uint32_t channel,
obs_source_t source);
/** Gets the source currently in use for this viewport context */
EXPORT obs_source_t obs_viewport_getsource(obs_viewport_t viewport,
uint32_t channel);
/** Renders the sources of this viewport context */
EXPORT void obs_viewport_render(obs_viewport_t viewport);
/* ------------------------------------------------------------------------- */
/* Display context */
/**
* Creates an extra display context.
* Adds a new window display linked to the main render pipeline. This creates
* a new swap chain which updates every frame.
*
* An extra display can be used for things like separate previews,
* viewing sources independently, and other things. Creates a new swap chain
* linked to a specific window to display a source.
* @param graphics_data The swap chain initialization data.
* @return The new display context, or NULL if failed.
*/
EXPORT obs_display_t obs_display_create(struct gs_init_data *graphics_data);
/** Destroys a display context */
EXPORT void obs_display_destroy(obs_display_t display);
/** Sets the source to be used for a display context. */
EXPORT void obs_display_setsource(obs_display_t display, uint32_t channel,
obs_source_t source);
EXPORT obs_source_t obs_display_getsource(obs_display_t display,
uint32_t channel);
/** Changes the size of this display */
EXPORT void obs_display_resize(obs_display_t display, uint32_t cx, uint32_t cy);
/**
* Adds a draw callback for this display context
*
* @param display The display context.
* @param draw The draw callback which is called each time a frame
* updates.
* @param param The user data to be associated with this draw callback.
*/
EXPORT void obs_display_add_draw_callback(obs_display_t display,
void (*draw)(void *param, uint32_t cx, uint32_t cy),
void *param);
/** Removes a draw callback for this display context */
EXPORT void obs_display_remove_draw_callback(obs_display_t display,
void (*draw)(void *param, uint32_t cx, uint32_t cy),
void *param);
/* ------------------------------------------------------------------------- */

View File

@ -1,5 +1,5 @@
/******************************************************************************
Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
Copyright (C) 2013-2014 by Hugh Bailey <obs.jim@gmail.com>
Copyright (C) 2014 by Zachary Lund <admin@computerquip.com>
This program is free software: you can redistribute it and/or modify
@ -55,6 +55,8 @@ void OBSBasic::OBSInit()
if (!InitAudio())
throw "Failed to initialize audio";
obs_add_draw_callback(OBSBasic::RenderMain, this);
signal_handler_connect(obs_signalhandler(), "source-add",
OBSBasic::SourceAdded, this);
signal_handler_connect(obs_signalhandler(), "source-remove",
@ -262,6 +264,11 @@ void OBSBasic::ChannelChanged(void *data, calldata_t params)
Q_ARG(OBSSource, OBSSource(source)));
}
void OBSBasic::RenderMain(void *data, uint32_t cx, uint32_t cy)
{
obs_render_main_viewport();
}
/* Main class functions */
bool OBSBasic::InitGraphics()
@ -331,12 +338,8 @@ void OBSBasic::ResizePreview(uint32_t cx, uint32_t cy)
ui->preview->setGeometry(x, y, cx, cy);
graphics_t graphics = obs_graphics();
if (graphics && isVisible()) {
gs_entercontext(graphics);
gs_resize(cx, cy);
gs_leavecontext();
}
if (isVisible())
obs_resize(cx, cy);
}
void OBSBasic::closeEvent(QCloseEvent *event)

View File

@ -1,5 +1,5 @@
/******************************************************************************
Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
Copyright (C) 2013-2014 by Hugh Bailey <obs.jim@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -52,6 +52,7 @@ private:
static void SourceAdded(void *data, calldata_t params);
static void SourceRemoved(void *data, calldata_t params);
static void ChannelChanged(void *data, calldata_t params);
static void RenderMain(void *data, uint32_t cx, uint32_t cy);
void ResizePreview(uint32_t cx, uint32_t cy);

View File

@ -102,6 +102,7 @@
<ClCompile Include="..\..\..\libobs\obs-scene.c" />
<ClCompile Include="..\..\..\libobs\obs-source.c" />
<ClCompile Include="..\..\..\libobs\obs-video.c" />
<ClCompile Include="..\..\..\libobs\obs-viewport.c" />
<ClCompile Include="..\..\..\libobs\obs-windows.c" />
<ClCompile Include="..\..\..\libobs\obs.c" />
<ClCompile Include="..\..\..\libobs\util\base.c" />

View File

@ -344,5 +344,8 @@
<ClCompile Include="..\..\..\libobs\obs-properties.c">
<Filter>libobs\Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\libobs\obs-viewport.c">
<Filter>libobs\Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>