return (llabs(cx-tx) < CONTROL_W/2 && llabs(cy-ty) < CONTROL_H/2);
}
+
int CWindowCanvas::do_mask(int &redraw, int &rerender,
int button_press, int cursor_motion, int draw)
{
float canvas_x = (x0 - half_track_w) * projector_z + projector_x;
float canvas_y = (y0 - half_track_h) * projector_z + projector_y;
// Test first point
- if(gui->shift_down()) {
+ if(gui->ctrl_down()) {
float control_x = (x1 - half_track_w) * projector_z + projector_x;
float control_y = (y1 - half_track_h) * projector_z + projector_y;
float distance = line_dist(control_x,control_y, mask_cursor_x,mask_cursor_y);
}
}
else {
- if(!gui->ctrl_down()) {
+ if(!gui->shift_down()) {
if(test_bbox(cursor_x, cursor_y, canvas_x, canvas_y)) {
selected_point = i;
}
canvas_x = (x3 - half_track_w) * projector_z + projector_x;
canvas_y = (y3 - half_track_h) * projector_z + projector_y;
- if(gui->shift_down()) {
+ if(gui->ctrl_down()) {
float control_x = (x2 - half_track_w) * projector_z + projector_x;
float control_y = (y2 - half_track_h) * projector_z + projector_y;
float distance = line_dist(control_x,control_y, mask_cursor_x,mask_cursor_y);
}
}
else if(i < points.size() - 1) {
- if(!gui->ctrl_down()) {
+ if(!gui->shift_down()) {
if(test_bbox(cursor_x, cursor_y, canvas_x, canvas_y)) {
selected_point = (i < points.size() - 1 ? i + 1 : 0);
}
gui->current_operation = mwindow->edl->session->cwindow_operation;
}
else // No existing point or control point was selected so create a new one
- if(!gui->shift_down() && !gui->alt_down()) {
+ if(!gui->ctrl_down() && !gui->alt_down()) {
mwindow->undo->update_undo_before(_("mask point"), 0);
// Create the template
MaskPoint *point = new MaskPoint;
over_point = 1;
}
- if(!over_point && gui->shift_down()) {
+ if(!over_point && gui->ctrl_down()) {
canvas_x = (x1 - half_track_w) * projector_z + projector_x;
canvas_y = (y1 - half_track_h) * projector_z + projector_y;
output_to_canvas(mwindow->edl, 0, canvas_x, canvas_y);
return result;
}
-
int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw)
{
int result = 0;
}
-
-
-
-
CWindowEyedropGUI::CWindowEyedropGUI(MWindow *mwindow, CWindowTool *thread)
: CWindowToolGUI(mwindow,
thread,
}
-
-
-
-
CWindowCameraGUI::CWindowCameraGUI(MWindow *mwindow, CWindowTool *thread)
: CWindowToolGUI(mwindow,
thread,
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
CWindowProjectorGUI::CWindowProjectorGUI(MWindow *mwindow, CWindowTool *thread)
: CWindowToolGUI(mwindow,
thread,
}
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
CWindowProjectorLeft::CWindowProjectorLeft(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
: BC_Button(x, y, mwindow->theme->get_image_set("left_justify"))
{
}
-
-
-
-
-
-
CWindowMaskMode::CWindowMaskMode(MWindow *mwindow,
CWindowToolGUI *gui, int x, int y, const char *text)
: BC_PopupMenu(x, y, 220, text, 1)
}
+CWindowDisableOpenGLMasking::CWindowDisableOpenGLMasking(CWindowToolGUI *gui, int x, int y)
+ : BC_CheckBox(x, y, 1, _("Disable OpenGL masking"))
+{
+ this->gui = gui;
+}
+
+int CWindowDisableOpenGLMasking::handle_event()
+{
+ Track *track;
+ MaskAutos *autos;
+ MaskAuto *keyframe;
+ SubMask *mask;
+ MaskPoint *point;
+ ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 1);
+
+ if (keyframe) {
+ keyframe->disable_opengl_masking = get_value();
+ gui->update_preview();
+ }
+ return 1;
+}
+
+
+
thread,
_(PROGRAM_NAME ": Mask"),
330,
- 280)
+ 310)
{
this->mwindow = mwindow;
this->thread = thread;
x = 10;
y += this->y->get_h() + margin;
- add_subwindow(title = new BC_Title(x, y, _("Press Ctrl to move a point")));
+ add_subwindow(title = new BC_Title(x, y, _("Press Shift to move an end point")));
y += title->get_h() + margin;
- add_subwindow(title = new BC_Title(x, y, _("Press Alt to translate the mask")));
+ add_subwindow(title = new BC_Title(x, y, _("Press Ctrl to move a control point")));
y += title->get_h() + margin;
- add_subwindow(title = new BC_Title(x, y, _("Press Shift to edit bezier curve")));
-
+ add_subwindow(title = new BC_Title(x, y, _("Press Alt to translate the mask")));
y += 30;
-// add_subwindow(title = new BC_Title(x, y, _("Apply mask before plugins:")));
- add_subwindow(this->apply_before_plugins = new CWindowMaskBeforePlugins(this,
- 10,
- y));
-// this->apply_before_plugins->create_objects();
+ add_subwindow(this->apply_before_plugins = new CWindowMaskBeforePlugins(this, 10, y));
+ y += this->apply_before_plugins->get_h() + margin;
+ add_subwindow(this->disable_opengl_masking = new CWindowDisableOpenGLMasking(this, 10, y));
update();
unlock_window();
feather->update((int64_t)autos->get_feather(position_i, PLAY_FORWARD));
value->update((int64_t)autos->get_value(position_i, PLAY_FORWARD));
apply_before_plugins->update((int64_t)keyframe->apply_before_plugins);
+ disable_opengl_masking->update((int64_t)keyframe->disable_opengl_masking);
}
}
CWindowToolGUI *gui;
};
-
-
+class CWindowDisableOpenGLMasking : public BC_CheckBox
+{
+public:
+ CWindowDisableOpenGLMasking(CWindowToolGUI *gui, int x, int y);
+ int handle_event();
+ CWindowToolGUI *gui;
+};
class CWindowMaskGUI : public CWindowToolGUI
{
CWindowMaskNumber *number;
CWindowMaskValue *value;
CWindowMaskBeforePlugins *apply_before_plugins;
+ CWindowDisableOpenGLMasking *disable_opengl_masking;
};
feather = 0;
value = 100;
apply_before_plugins = 0;
+ disable_opengl_masking = 0;
// We define a fixed number of submasks so that interpolation for each
// submask matches.
mode != src->mode ||
feather != src->feather ||
masks.size() != src->masks.size() ||
- apply_before_plugins != src->apply_before_plugins) return 0;
+ apply_before_plugins != src->apply_before_plugins ||
+ disable_opengl_masking != src->disable_opengl_masking) return 0;
for(int i = 0; i < masks.size(); i++)
if(!(*masks.values[i] == *src->masks.values[i])) return 0;
feather = src->feather;
value = src->value;
apply_before_plugins = src->apply_before_plugins;
+ disable_opengl_masking = src->disable_opengl_masking;
masks.remove_all_objects();
for(int i = 0; i < src->masks.size(); i++)
this->feather = mask_auto1->feather;
this->value = mask_auto1->value;
this->apply_before_plugins = mask_auto1->apply_before_plugins;
+ this->disable_opengl_masking = mask_auto1->disable_opengl_masking;
this->position = position;
masks.remove_all_objects();
feather = file->tag.get_property("FEATHER", feather);
value = file->tag.get_property("VALUE", value);
apply_before_plugins = file->tag.get_property("APPLY_BEFORE_PLUGINS", apply_before_plugins);
+ disable_opengl_masking = file->tag.get_property("DISABLE_OPENGL_MASKING", disable_opengl_masking);
for(int i = 0; i < masks.size(); i++)
{
delete masks.values[i];
file->tag.set_property("VALUE", value);
file->tag.set_property("FEATHER", feather);
file->tag.set_property("APPLY_BEFORE_PLUGINS", apply_before_plugins);
+ file->tag.set_property("DISABLE_OPENGL_MASKING", disable_opengl_masking);
if(default_auto)
file->tag.set_property("POSITION", 0);
// 0 - 100
int value;
int apply_before_plugins;
+ int disable_opengl_masking;
};
{
this->mwindow = mwindow;
this->mbuttons = mbuttons;
- set_tooltip(_("FFMpeg early probe"));
+ set_tooltip( mwindow->preferences->ffmpeg_early_probe ?
+ _("Try FFMpeg first") : _("Try FFMpeg last"));
}
FFMpegToggle::~FFMpegToggle()
int FFMpegToggle::handle_event()
{
mwindow->preferences->ffmpeg_early_probe = get_value();
+ set_tooltip( mwindow->preferences->ffmpeg_early_probe ?
+ _("Try FFMpeg first") : _("Try FFMpeg last"));
mwindow->show_warning(&mwindow->preferences->warn_indexes,
_("Changing the base codecs may require rebuilding indexes."));
return 1;
using_defaults = 1;
KeyFrame temp_keyframe;
-
save_data(&temp_keyframe);
- FILE *fd = fopen(path, "w");
- if(fd)
- {
- fprintf(fd, "%d\n%d\n", window_x, window_y);
- if(!fwrite(temp_keyframe.get_data(), strlen(temp_keyframe.get_data()), 1, fd))
- {
+
+ const char *data = temp_keyframe.get_data();
+ int len = strlen(data);
+ FILE *fp = fopen(path, "w");
+
+ if( fp ) {
+ fprintf(fp, "%d\n%d\n", window_x, window_y);
+ if( len > 0 && !fwrite(data, len, 1, fp) ) {
fprintf(stderr, "PluginClient::save_defaults_xml %d \"%s\" %d bytes: %s\n",
- __LINE__,
- path,
- (int)strlen(temp_keyframe.get_data()),
- strerror(errno));
+ __LINE__, path, len, strerror(errno));
}
-
- fclose(fd);
+ fclose(fp);
}
+
using_defaults = 0;
}
shbtn_prefs.remove_all_objects();
int shbtns_total = defaults->get("SHBTNS_TOTAL", -1);
if( shbtns_total < 0 ) {
- shbtn_prefs.append(new ShBtnPref("manual", "firefox file:///$CINELERRA_PATH/manual.pdf", 0));
- shbtn_prefs.append(new ShBtnPref("online help", "firefox http://cinelerra.org/help.php/", 0));
+// shbtn_prefs.append(new ShBtnPref("manual", "firefox file:///$CINELERRA_PATH/manual.pdf", 0));
+ shbtn_prefs.append(new ShBtnPref("online help", "firefox https://cinelerra-cv.org/docs/cinelerra_cv_manual_en.html", 0));
shbtns_total = 0;
}
for( int i=0; i<shbtns_total; ++i ) {
mwindow->reset_android_remote();
mwindow->gui->ffmpeg_toggle->update(mwindow->preferences->ffmpeg_early_probe);
+ mwindow->gui->ffmpeg_toggle->set_tooltip( mwindow->preferences->ffmpeg_early_probe ?
+ _("Try FFMpeg first") : _("Try FFMpeg last") );
mwindow->gui->mainshbtns->load(mwindow->preferences);
double tc_position =
mwindow->edl->session->get_frame_offset() / mwindow->edl->session->frame_rate;
*/
#include "assets.h"
+#include "auto.h"
#include "bccapture.h"
#include "bcsignals.h"
#include "canvas.h"
#include "bccmodels.h"
#include "edl.h"
#include "edlsession.h"
+#include "maskautos.h"
+#include "maskauto.h"
#include "mwindow.h"
#include "playback3d.h"
#include "playbackconfig.h"
this->output->mwindow->playback_3d->do_fade(this->output, output_temp, fade);
}
-void VDeviceX11::do_mask(VFrame *output_temp, int64_t start_position_project,
- MaskAutos *keyframe_set, MaskAuto *keyframe,
- MaskAuto *default_auto)
+bool VDeviceX11::can_mask(int64_t start_position_project, MaskAutos *keyframe_set)
+{
+ Auto *current = 0;
+ MaskAuto *keyframe = (MaskAuto*)keyframe_set->
+ get_prev_auto(start_position_project, PLAY_FORWARD, current);
+ return keyframe->disable_opengl_masking ? 0 : 1;
+}
+
+void VDeviceX11::do_mask(VFrame *output_temp,
+ int64_t start_position_project, MaskAutos *keyframe_set,
+ MaskAuto *keyframe, MaskAuto *default_auto)
{
this->output->mwindow->playback_3d->do_mask(output,
output_temp, start_position_project,
void do_fade(VFrame *output_temp, float fade);
// Hardware version of MaskEngine
- void do_mask(VFrame *output_temp,
- int64_t start_position_project,
- MaskAutos *keyframe_set,
- MaskAuto *keyframe,
- MaskAuto *default_auto);
+ bool can_mask(int64_t start_position_project, MaskAutos *keyframe_set);
+ void do_mask(VFrame *output,
+ int64_t start_position_project, MaskAutos *keyframe_set,
+ MaskAuto *keyframe, MaskAuto *default_auto);
void convert_cmodel(VFrame *output, int dst_cmodel);
// The idea is to composite directly in the frame buffer if OpenGL.
return;
}
- if(use_opengl)
- {
+ if(use_opengl) {
+ if( !((VDeviceX11*)((VirtualVConsole*)vconsole)->get_vdriver())->can_mask(
+ start_position_project, keyframe_set) )
+ use_opengl = 0;
+
+ }
+ if(use_opengl) {
((VDeviceX11*)((VirtualVConsole*)vconsole)->get_vdriver())->do_mask(
- output_temp, start_position_project,
- keyframe_set, keyframe, keyframe);
+ output_temp, start_position_project, keyframe_set,
+ keyframe, keyframe);
}
- else
- {
+ else {
// Revert to software
masker->do_mask(output_temp, start_position_project,
- keyframe_set, keyframe, keyframe);
+ keyframe_set, keyframe, keyframe);
}
}
#include "vedit.h"
#include "vframe.h"
#include "videodevice.h"
+#include "virtualvconsole.h"
#include "vmodule.h"
#include "vrender.h"
#include "vplugin.h"
use_opengl);
}
- int64_t mask_position = !renderengine ? start_position :
- renderengine->vrender->current_position;
Auto *current = 0;
MaskAutos *keyframe_set =
(MaskAutos*)track->automation->autos[AUTOMATION_MASK];
- MaskAuto *keyframe =
+ int64_t mask_position = !renderengine ? start_position :
+ renderengine->vrender->current_position;
+ MaskAuto *keyframe =
(MaskAuto*)keyframe_set->get_prev_auto(mask_position, direction, current);
+
if( keyframe->apply_before_plugins ) {
- if( !masker ) {
- int cpus = renderengine ?
- renderengine->preferences->processors :
- plugin_array->mwindow->preferences->processors;
- masker = new MaskEngine(cpus);
+ VDeviceX11 *x11_device = 0;
+ if(use_opengl && renderengine && renderengine->video) {
+ x11_device = (VDeviceX11*)renderengine->video->get_output_base();
+ if( !x11_device->can_mask(mask_position, keyframe_set) )
+ use_opengl = 0;
+ }
+ if( use_opengl && x11_device ) {
+ x11_device->do_mask(output, mask_position, keyframe_set,
+ keyframe, keyframe);
+ }
+ else {
+ if( !masker ) {
+ int cpus = renderengine ?
+ renderengine->preferences->processors :
+ plugin_array->mwindow->preferences->processors;
+ masker = new MaskEngine(cpus);
+ }
+ masker->do_mask(output, mask_position, keyframe_set, keyframe, keyframe);
}
- masker->do_mask(output, mask_position, keyframe_set, keyframe, keyframe);
}
return result;
}
+void BC_Texture::draw_texture(
+ float in_x1, float in_y1, float in_x2, float in_y2,
+ float out_x1, float out_y1, float out_x2, float out_y2)
+{
+#ifdef HAVE_GL
+ glBegin(GL_QUADS);
+ glNormal3f(0, 0, 1.0);
+ glTexCoord2f(in_x1, in_y1); glVertex3f(out_x1, out_y1, 0);
+ glTexCoord2f(in_x2, in_y1); glVertex3f(out_x2, out_y1, 0);
+ glTexCoord2f(in_x2, in_y2); glVertex3f(out_x2, out_y2, 0);
+ glTexCoord2f(in_x1, in_y2); glVertex3f(out_x1, out_y2, 0);
+ glEnd();
+#endif
+}
+
void BC_Texture::bind(int texture_unit)
{
#ifdef HAVE_GL
#endif
}
+void write_ppm(uint8_t *tp, int w, int h, const char *fmt, ...);
+
+void BC_Texture::write_tex(const char *fn)
+{
+ int prev_id = -1;
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &prev_id);
+ glActiveTexture(this->texture_id);
+ int w = get_texture_w(), h = get_texture_h();
+ uint8_t img[w*h*3];
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, img);
+ write_ppm(img, w, h, "%s", fn);
+ glActiveTexture(prev_id);
+}
+
+
int get_texture_h();
int get_texture_components();
int get_window_id();
+ void draw_texture(
+ float in_x1, float in_y1, float in_x2, float in_y2,
+ float out_x1, float out_y1, float out_x2, float out_y2);
+ void write_tex(const char *fn);
private:
void clear_objects();
#endif
}
-void VFrame::draw_texture(float in_x1,
- float in_y1,
- float in_x2,
- float in_y2,
- float out_x1,
- float out_y1,
- float out_x2,
- float out_y2,
- int flip_y)
+void VFrame::draw_texture(
+ float in_x1, float in_y1, float in_x2, float in_y2,
+ float out_x1, float out_y1, float out_x2, float out_y2,
+ int flip_y)
{
#ifdef HAVE_GL
- glBegin(GL_QUADS);
- glNormal3f(0, 0, 1.0);
-
- glTexCoord2f(in_x1 / get_texture_w(), in_y1 / get_texture_h());
- glVertex3f(out_x1, flip_y ? -out_y1 : -out_y2, 0);
-
- glTexCoord2f(in_x2 / get_texture_w(), in_y1 / get_texture_h());
- glVertex3f(out_x2, flip_y ? -out_y1 : -out_y2, 0);
-
- glTexCoord2f(in_x2 / get_texture_w(), in_y2 / get_texture_h());
- glVertex3f(out_x2, flip_y ? -out_y2 : -out_y1, 0);
-
- glTexCoord2f(in_x1 / get_texture_w(), in_y2 / get_texture_h());
- glVertex3f(out_x1, flip_y ? -out_y2 : -out_y1, 0);
-
-
- glEnd();
-
+ in_x1 /= get_texture_w(); in_y1 /= get_texture_h();
+ in_x2 /= get_texture_w(); in_y2 /= get_texture_h();
+ float ot_y1 = flip_y ? -out_y1 : -out_y2;
+ float ot_y2 = flip_y ? -out_y2 : -out_y1;
+ texture->draw_texture(
+ in_x1,in_y1, in_x2,in_y2,
+ out_x1,ot_y1, out_x2, ot_y2);
#endif
}
void VFrame::draw_texture(int flip_y)
{
- draw_texture(0,
- 0,
- get_w(),
- get_h(),
- 0,
- 0,
- get_w(),
- get_h(),
- flip_y);
+ draw_texture(0,0, get_w(),get_h(),
+ 0,0, get_w(),get_h(), flip_y);
}