cd "$path/$dir/$bld"
rm -rf "$proj"
-git clone --depth 1 "git://git.cinelerra-cv.org/goodguy/cinelerra.git" "$proj"
-#rsh host tar -C /mnt0/cinelerra5 -cf - cinelerra | tar -xf -
-#mv cinelerra cinelerra5
+git clone "git://git.cinelerra-cv.org/goodguy/cinelerra.git" "$proj"
+#rsh host tar -C /mnt0 -cf - cinelerra5 | tar -xf -
if [ $? -ne 0 ]; then
echo "git clone $proj failed"
exit 1
fi
cd "$proj/$base"
-if [ "$dir" = "ubuntu" ]; then
- echo "CFLAGS += -DPNG_SKIP_SETJMP_CHECK=1" >> global_config
-fi
-if [ "$dir" = "centos" ]; then
- echo "EXTRA_LIBS += -lnuma" >> global_config
- echo "CFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS" >> global_config
-fi
-if [ "$dir" = "suse" ]; then
- echo "EXTRA_LIBS += -lnuma" >> global_config
-fi
+case "$dir" in
+ "ubuntu" | "mint" | "ub14" | "ub15")
+ echo "CFLAGS += -DPNG_SKIP_SETJMP_CHECK=1" >> global_config ;;
+ "centos")
+ echo "CFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS" >> global_config
+ echo "EXTRA_LIBS += -lnuma" >> global_config ;;
+ "suse" | "leap")
+ echo "EXTRA_LIBS += -lnuma" >> global_config ;;
+ "fedora")
+ echo "EXTRA_LIBS += -lnuma" >> global_config ;;
+esac
STATIC_LIBRARIES=0 ./configure >& log
make >> log 2>&1 $@
yum -y install /tmp/$yasm
rm -f /tmp/$yasm
;;
-"suse")
+"fedora")
+ dnf -y install nasm yasm libavc1394-devel libusb-devel flac-devel \
+ libjpeg-devel libdv-devel libdvdnav-devel libdvdread-devel \
+ libtheora-devel libiec61883-devel esound-devel uuid-devel \
+ giflib-devel ncurses-devel ilmbase-devel fftw-devel OpenEXR-devel \
+ libsndfile-devel libXft-devel libXinerama-devel libXv-devel \
+ xorg-x11-fonts-misc xorg-x11-fonts-cyrillic xorg-x11-fonts-Type1 \
+ xorg-x11-fonts-ISO8859-1-100dpi xorg-x11-fonts-ISO8859-1-75dpi \
+ libpng-devel bzip2-devel zlib-devel kernel-headers libavc1394 \
+ festival-devel libdc1394-devel libiec61883-devel esound-devel \
+ flac-devel libsndfile-devel libtheora-devel linux-firmware \
+ ivtv-firmware libvorbis-devel texinfo xz-devel lzma-devel cmake
+ ;;
+"suse" | "leap")
zypper -n install nasm gcc gcc-c++ zlib-devel texinfo libpng16-devel \
freeglut-devel libXv-devel alsa-devel libbz2-devel ncurses-devel \
libXinerama-devel freetype-devel libXft-devel giflib-devel ctags \
ln -s libtermcap.so.2 /usr/lib64/libtermcap.so
fi
;;
-"ubuntu")
- apt-get -y install apt-file sox nasm yasm g++ build-essential libz-dev texinfo \
- libpng-dev freeglut3-dev libxv-dev libasound2-dev libbz2-dev \
+"ubuntu" | "mint" | "ub14" | "ub15")
+ apt-get -y install apt-file sox nasm yasm g++ build-essential libz-dev \
+ texinfo libpng-dev freeglut3-dev libxv-dev libasound2-dev libbz2-dev \
libncurses5-dev libxinerama-dev libfreetype6-dev libxft-dev libgif-dev \
libtiff5-dev exuberant-ctags ttf-bitstream-vera xfonts-75dpi xfonts-100dpi \
fonts-dejavu libopenexr-dev libavc1394-dev festival-dev fftw3-dev \
cd "$path/$dir/$bld"
rm -rf "$proj"
-git clone --depth 1 "git://git.cinelerra-cv.org/goodguy/cinelerra.git" "$proj"
-#rsh host tar -C /mnt0/cinelerra5 -cf - cinelerra | tar -xf -
-#mv cinelerra cinelerra5
+git clone "git://git.cinelerra-cv.org/goodguy/cinelerra.git" "$proj"
+#rsh host tar -C /mnt0 -cf - cinelerra5 | tar -xf -
if [ $? -ne 0 ]; then
echo "git clone $proj failed"
exit 1
fi
cd "$proj/$base"
-if [ "$dir" = "ubuntu" ]; then
- echo "CFLAGS += -DPNG_SKIP_SETJMP_CHECK=1" >> global_config
-fi
-if [ "$dir" = "centos" ]; then
- echo "EXTRA_LIBS += -lnuma" >> global_config
- echo "CFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS" >> global_config
-fi
-if [ "$dir" = "suse" ]; then
- echo "EXTRA_LIBS += -lnuma" >> global_config
-fi
+case "$dir" in
+ "ubuntu" | "mint" | "ub14" | "ub15")
+ echo "CFLAGS += -DPNG_SKIP_SETJMP_CHECK=1" >> global_config ;;
+ "centos")
+ echo "CFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS" >> global_config
+ echo "EXTRA_LIBS += -lnuma" >> global_config ;;
+ "suse" | "leap")
+ echo "EXTRA_LIBS += -lnuma" >> global_config ;;
+ "fedora")
+ echo "EXTRA_LIBS += -lnuma" >> global_config ;;
+esac
STATIC_LIBRARIES=1 ./configure >& log
make >> log 2>&1 $@
}
}
// cut edit
- Edit *next_edit = track->edits->split_edit(edit, cut_start);
+ Edit *next_edit = edit->edits->split_edit(cut_start);
int64_t cut_length = cut_end - cut_start;
next_edit->length -= cut_length;
next_edit->startsource += cut_length;
}
-static inline bool test_bbox(int cx, int cy, int tx, int ty)
-{
- return (llabs(cx-tx) < (CONTROL_W/2) && llabs(cy-ty) < (CONTROL_H/2));
-}
-
static inline double line_dist(float cx,float cy, float tx,float ty)
{
- int dx = tx-cx, dy = ty-cy;
+ double dx = tx-cx, dy = ty-cy;
return sqrt(dx*dx + dy*dy);
}
+static inline bool test_bbox(int cx, int cy, int tx, int ty)
+{
+// printf("test_bbox %d,%d - %d,%d = %f\n",cx,cy,tx,ty,line_dist(cx,cy,tx,ty));
+ 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)
// Get position of cursor relative to mask
- float cursor_x = get_cursor_x();
- float cursor_y = get_cursor_y();
- canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
+ float cursor_x = get_cursor_x(), cursor_y = get_cursor_y();
+ float mask_cursor_x = cursor_x, mask_cursor_y = cursor_y;
+ canvas_to_output(mwindow->edl, 0, mask_cursor_x, mask_cursor_y);
projector_x += mwindow->edl->session->output_w / 2;
projector_y += mwindow->edl->session->output_h / 2;
-
- float mask_cursor_x = (cursor_x - projector_x) / projector_z + half_track_w;
- float mask_cursor_y = (cursor_y - projector_y) / projector_z + half_track_h;
+ mask_cursor_x = (mask_cursor_x - projector_x) / projector_z + half_track_w;
+ mask_cursor_y = (mask_cursor_y - projector_y) / projector_z + half_track_h;
// Fix cursor origin
if(button_press) {
y = (y - half_track_h) * projector_z + projector_y;
// Test new point addition
if(button_press) {
- float line_distance = line_dist(x,y, cursor_x,cursor_y);
+ float line_distance = line_dist(x,y, mask_cursor_x,mask_cursor_y);
//printf("CWindowCanvas::do_mask 1 x=%f cursor_x=%f y=%f cursor_y=%f %f %f %d, %d\n",
// x, cursor_x, y, cursor_y, line_distance, shortest_line_distance, shortest_point1, shortest_point2);
if(gui->shift_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, cursor_x,cursor_y);
+ float distance = line_dist(control_x,control_y, mask_cursor_x,mask_cursor_y);
if(distance < selected_control_point_distance) {
selected_point = i;
if(gui->shift_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, cursor_x,cursor_y);
+ float distance = line_dist(control_x,control_y, mask_cursor_x,mask_cursor_y);
//printf("CWindowCanvas::do_mask %d %f %f\n", i, distance, selected_control_point_distance);
if(distance < selected_control_point_distance) {
//printf("CWindowCanvas::do_mask %d %d\n", shortest_point1, shortest_point2);
// Append to end of list
- if(labs(shortest_point1 - shortest_point2) > 1) {
+ if( shortest_point1 == shortest_point2 ||
+ labs(shortest_point1 - shortest_point2) > 1) {
#ifdef USE_KEYFRAME_SPANNING
MaskPoint *new_point = new MaskPoint;
MaskPoint *new_point = new MaskPoint;
points.append(new_point);
*new_point = *point;
+ gui->affected_point = points.size() - 1;
#else
for(MaskAuto *current = (MaskAuto*)mask_autos->default_auto; current; ) {
SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
else
current = (MaskAuto*)NEXT;
}
-#endif
-
-//printf("CWindowCanvas::do_mask 2\n");
-// Create a second point if none existed before
-#ifdef USE_KEYFRAME_SPANNING
- if(points.size() < 2) {
-
- MaskPoint *new_point = new MaskPoint;
- points.append(new_point);
- *new_point = *point;
- }
-
gui->affected_point = points.size() - 1;
-#else
- if(mask->points.size() < 2) {
-
- for(MaskAuto *current = (MaskAuto*)mask_autos->default_auto; current; ) {
- SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
- MaskPoint *new_point = new MaskPoint;
- submask->points.append(new_point);
- *new_point = *point;
- if(current == (MaskAuto*)mask_autos->default_auto)
- current = (MaskAuto*)mask_autos->first;
- else
- current = (MaskAuto*)NEXT;
- }
- }
-
- gui->affected_point = mask->points.size() - 1;
#endif
//printf("CWindowCanvas::do_mask 3 %d\n", mask->points.size());
//printf("CWindowCanvas::do_mask %d %d\n", __LINE__, gui->affected_point);
SubMask *mask = gui->mask_keyframe->get_submask(mwindow->edl->session->cwindow_mask);
- if(gui->affected_point < mask->points.size() &&
+ if( gui->affected_point >= 0 && gui->affected_point < mask->points.size() &&
gui->current_operation != CWINDOW_NONE) {
// mwindow->undo->update_undo_before(_("mask point"), this);
#ifdef USE_KEYFRAME_SPANNING
Track *track;
MaskPoint *point;
SubMask *mask;
+ int total_points = 0;
// Get existing keyframe
((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 0);
submask->points.remove_object(
submask->points.values[submask->points.total - 1]);
}
+ total_points = submask->points.total;
+
// Commit change to span of keyframes
((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->update_parameter(&temp_keyframe);
#else
{
SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
-
-
for(int i = mwindow->cwindow->gui->affected_point;
i < submask->points.total - 1;
i++)
submask->points.remove_object(
submask->points.values[submask->points.total - 1]);
}
-
+ total_points = submask->points.total;
if(current == (MaskAuto*)autos->default_auto)
current = (MaskAuto*)autos->first;
current = (MaskAuto*)NEXT;
}
#endif
+ if( mwindow->cwindow->gui->affected_point >= total_points )
+ mwindow->cwindow->gui->affected_point =
+ total_points > 0 ? total_points-1 : 0;
gui->update();
gui->update_preview();
}
+CWindowMaskAffectedPoint::CWindowMaskAffectedPoint(MWindow *mwindow,
+ CWindowToolGUI *gui, int x, int y)
+ : BC_TumbleTextBox(gui,
+ (int64_t)mwindow->cwindow->gui->affected_point,
+ (int64_t)0, INT64_MAX, x, y, 100)
+{
+ this->mwindow = mwindow;
+ this->gui = gui;
+}
+
+CWindowMaskAffectedPoint::~CWindowMaskAffectedPoint()
+{
+}
+
+int CWindowMaskAffectedPoint::handle_event()
+{
+ int total_points = 0;
+ int affected_point = atol(get_text());
+ Track *track = mwindow->cwindow->calculate_affected_track();
+ if(track) {
+ MaskAutos *autos = (MaskAutos*)track->automation->autos[AUTOMATION_MASK];
+ MaskAuto *keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(autos, 0);
+ if( keyframe ) {
+ SubMask *mask = keyframe->get_submask(mwindow->edl->session->cwindow_mask);
+ total_points = mask->points.size();
+ }
+ }
+ int active_point = affected_point;
+ if( affected_point >= total_points )
+ affected_point = total_points - 1;
+ else if( affected_point < 0 )
+ affected_point = 0;
+ if( active_point != affected_point )
+ update((int64_t)affected_point);
+ mwindow->cwindow->gui->affected_point = affected_point;
+ gui->update();
+ gui->update_preview();
+ return 1;
+}
+
+
{
this->mwindow = mwindow;
this->thread = thread;
+ number = 0;
+ active_point = 0;
+ feather = 0;
}
CWindowMaskGUI::~CWindowMaskGUI()
{
lock_window("CWindowMaskGUI::~CWindowMaskGUI");
delete number;
+ delete active_point;
delete feather;
unlock_window();
}
add_subwindow(value = new CWindowMaskValue(mwindow, this, x + title->get_w() + margin, y));
y += value->get_h() + margin;
add_subwindow(delete_point = new CWindowMaskDelete(mwindow, this, x, y));
+ int x1 = x + delete_point->get_w() + 2*margin;
+ add_subwindow(title = new BC_Title(x1, y, _("Point:")));
+ x1 += title->get_w() + margin;
+ active_point = new CWindowMaskAffectedPoint(mwindow, this, x1, y);
+ active_point->create_objects();
y += delete_point->get_h() + margin;
add_subwindow(title = new BC_Title(x, y, _("Mask number:")));
number = new CWindowMaskNumber(mwindow,
apply_before_plugins->update((int64_t)keyframe->apply_before_plugins);
}
}
-//printf("CWindowMaskGUI::update 1\n");
+//printf("CWindowMaskGUI::update 1\n");
+ active_point->update((int64_t)mwindow->cwindow->gui->affected_point);
number->update((int64_t)mwindow->edl->session->cwindow_mask);
//printf("CWindowMaskGUI::update 1\n");
CWindowToolGUI *gui;
};
+
+class CWindowMaskAffectedPoint : public BC_TumbleTextBox
+{
+public:
+ CWindowMaskAffectedPoint(MWindow *mwindow, CWindowToolGUI *gui, int x, int y);
+ ~CWindowMaskAffectedPoint();
+ int handle_event();
+ MWindow *mwindow;
+ CWindowToolGUI *gui;
+};
+
+
class CWindowMaskFeather : public BC_TumbleTextBox
{
public:
CWindowMaskMode *mode;
CWindowMaskFeather *feather;
CWindowMaskDelete *delete_point;
+ CWindowMaskAffectedPoint *active_point;
// Not necessary if all keyframes have same points
// CWindowMaskCycleNext *next_point;
// CWindowMaskCyclePrev *prev_point;
return new_edit;
}
-
Edit* Edits::split_edit(int64_t position)
{
// Get edit containing position
Edit *edit = editof(position, PLAY_FORWARD, 0);
-// No edit found, make one - except when we are at zero position!
- if(!edit && position != 0) {
- if (length() == position) {
- edit = last; // we do not need any edit to extend past the last one
- }
- else if (!last || length() < position) {
-
- // Even when track is completely empty or split is beyond last edit, return correct edit
- Edit *empty = create_edit();
- if (last)
- empty->startproject = length(); // end of last edit
- else
- empty->startproject = 0; // empty track
- empty->length = position - empty->startproject;
- insert_after(last, empty);
- edit = empty;
- }
- else {
- // now we are now surely in situation where we have
- // a) broken edit list or b) negative position... report error!
- printf("ERROR!\n");
- printf("Trying to insert edit at position, but failed: %ji\n", position);
- printf("Dump is here:\n");
- track->dump(stdout);
- return 0;
- }
- }
if(!edit) return 0;
- return split_edit(edit, position);
-}
-
-Edit* Edits::split_edit(Edit *edit, int64_t position)
-{
// Split would have created a 0 length
// if(edit->startproject == position) return edit;
// Create anyway so the return value comes before position
Edit *new_edit = create_edit();
insert_after(edit, new_edit);
- if (edit) // if we have actually split the edit, do the funky stuff!
- {
- new_edit->copy_from(edit);
- new_edit->length = new_edit->startproject + new_edit->length - position;
- edit->length = position - edit->startproject;
- new_edit->startsource += edit->length;
-
+ new_edit->copy_from(edit);
+ new_edit->length = new_edit->startproject + new_edit->length - position;
+ edit->length = position - edit->startproject;
+ new_edit->startproject = position;
+ new_edit->startsource += edit->length;
// Decide what to do with the transition
- if(edit->length && edit->transition)
- {
- delete new_edit->transition;
- new_edit->transition = 0;
- }
+ if(edit->length && edit->transition) {
+ delete new_edit->transition;
+ new_edit->transition = 0;
+ }
- if(edit->transition && edit->transition->length > edit->length)
- edit->transition->length = edit->length;
- if(new_edit->transition && new_edit->transition->length > new_edit->length)
- new_edit->transition->length = new_edit->length;
- } else
- new_edit->length = 0;
- new_edit->startproject = position;
+ if(edit->transition && edit->transition->length > edit->length)
+ edit->transition->length = edit->length;
+ if(new_edit->transition && new_edit->transition->length > new_edit->length)
+ new_edit->transition->length = new_edit->length;
return new_edit;
}
result = 0;
// delete 0 length edits
- for(current = first; !result && current; ) {
+ for( current = first; !result && current; ) {
Edit* next = current->next;
- if(current->length == 0) {
- // Be smart with transitions!
- if (next && current->transition && !next->transition) {
+ if( current->length == 0 ) {
+ if( next && current->transition && !next->transition) {
next->transition = current->transition;
next->transition->edit = next;
current->transition = 0;
// current->channel, next_edit->channel, current->asset, next_edit->asset,
// current->nested_edl, next_edit->nested_edl);
-
// both edits are silence & not a plugin
-// source channels are identical
-// assets are identical
+// source channels are identical, assets are identical
if( (current->silence() && next_edit->silence() && !current->is_plugin) ||
(current->startsource + current->length == next_edit->startsource &&
current->channel == next_edit->channel &&
current->length += next_edit->length;
remove(next_edit);
result = 1;
- continue;
+ break;
}
current = current->next;
while( !file->read_tag() ) {
//printf("Edits::load 1 %s\n", file->tag.get_title());
- if(!strcmp(file->tag.get_title(), "EDIT"))
- {
+ if(!strcmp(file->tag.get_title(), "EDIT")) {
load_edit(file, startproject, track_offset);
}
else if(!strcmp(file->tag.get_title(), "/EDITS"))
{
Edit* current = append_new_edit();
current->load_properties(file, startproject);
+
startproject += current->length;
while( !file->read_tag() ) {
- if(file->tag.title_is("NESTED_EDL"))
- {
+ if(file->tag.title_is("NESTED_EDL")) {
char path[BCTEXTLEN];
path[0] = 0;
file->tag.get_property("SRC", path);
//printf("Edits::load_edit %d path=%s\n", __LINE__, path);
- if(path[0] != 0)
- {
+ if(path[0] != 0) {
current->nested_edl = edl->nested_edls->get(path);
}
// printf("Edits::load_edit %d nested_edl->path=%s\n",
// __LINE__,
// current->nested_edl->path);
}
- else if(file->tag.title_is("FILE"))
- {
+ else if(file->tag.title_is("FILE")) {
char filename[BCTEXTLEN];
filename[0] = 0;
file->tag.get_property("SRC", filename);
// Extend path
- if(filename[0] != 0)
- {
+ if(filename[0] != 0) {
char directory[BCTEXTLEN], edl_directory[BCTEXTLEN];
FileSystem fs;
fs.set_current_dir("");
fs.extract_dir(directory, filename);
- if(!strlen(directory))
- {
+ if(!strlen(directory)) {
fs.extract_dir(edl_directory, file->filename);
fs.join_names(directory, edl_directory, filename);
strcpy(filename, directory);
}
current->asset = edl->assets->get_asset(filename);
}
- else
- {
+ else {
current->asset = 0;
}
//printf("Edits::load_edit 5\n");
}
- else if(file->tag.title_is("TRANSITION"))
- {
+ else if(file->tag.title_is("TRANSITION")) {
current->transition = new Transition(edl, current, "",
track->to_units(edl->session->default_transition_length, 1));
current->transition->load_xml(file);
Edit *current = 0;
if(use_nudge && track) position += track->nudge;
- if(direction == PLAY_FORWARD)
- {
- for(current = last; current; current = PREVIOUS)
- {
+ if(direction == PLAY_FORWARD) {
+ for(current = last; current; current = PREVIOUS) {
if(current->startproject <= position && current->startproject + current->length > position)
return current;
}
}
else
- if(direction == PLAY_REVERSE)
- {
- for(current = first; current; current = NEXT)
- {
+ if(direction == PLAY_REVERSE) {
+ for(current = first; current; current = NEXT) {
if(current->startproject < position && current->startproject + current->length >= position)
return current;
}
if(track && use_nudge) position += track->nudge;
// Get the current edit
- for(current = first; current; current = NEXT)
- {
+ for(current = first; current; current = NEXT) {
if(current->startproject <= position &&
current->startproject + current->length > position)
break;
// Get the edit's asset
// TODO: descend into nested EDLs
- if(current)
- {
+ if(current) {
if(!current->asset)
current = 0;
}
Edit* edit2 = editof(end, PLAY_FORWARD, 0);
Edit* current_edit;
+ if(end == start) return; // nothing selected
if(!edit1 && !edit2) return; // nothing selected
- if(!edit2)
- { // edit2 beyond end of track
+ if(!edit2) { // edit2 beyond end of track
edit2 = last;
end = this->length();
}
edit2->startproject += end - edit2->startproject;
// delete
- for(current_edit = edit1->next; current_edit && current_edit != edit2;)
- {
+ for(current_edit = edit1->next; current_edit && current_edit != edit2;) {
Edit* next = current_edit->next;
remove(current_edit);
current_edit = next;
}
// shift
- for(current_edit = edit2; current_edit; current_edit = current_edit->next)
- {
+ for(current_edit = edit2; current_edit; current_edit = current_edit->next) {
current_edit->startproject -= end - start;
}
}
- else
- {
+ else {
// in same edit. paste_edit depends on this
// create a new edit
current_edit = split_edit(start);
-
- current_edit->length -= end - start;
- current_edit->startsource += end - start;
-
+ if( current_edit ) {
+ current_edit->length -= end - start;
+ current_edit->startsource += end - start;
// shift
- for(current_edit = current_edit->next;
- current_edit;
- current_edit = current_edit->next)
- {
- current_edit->startproject -= end - start;
+ while( (current_edit=current_edit->next) != 0 ) {
+ current_edit->startproject -= end - start;
+ }
}
}
// Used by edit handle and plugin handle movement but plugin handle movement
// can only effect other plugins.
-void Edits::clear_recursive(int64_t start,
- int64_t end,
- int edit_edits,
- int edit_labels,
- int edit_plugins,
- int edit_autos,
+void Edits::clear_recursive(int64_t start, int64_t end,
+ int edit_edits, int edit_labels, int edit_plugins, int edit_autos,
Edits *trim_edits)
{
//printf("Edits::clear_recursive 1\n");
- track->clear(start,
- end,
- edit_edits,
- edit_labels,
- edit_plugins,
- edit_autos,
- 0,
+ track->clear(start, end,
+ edit_edits, edit_labels, edit_plugins, edit_autos, 0,
trim_edits);
}
-int Edits::clear_handle(double start,
- double end,
- int edit_plugins,
- int edit_autos,
- double &distance)
+int Edits::clear_handle(double start, double end,
+ int edit_plugins, int edit_autos, double &distance)
{
Edit *current_edit;
distance = 0.0; // if nothing is found, distance is 0!
for(current_edit = first;
current_edit && current_edit->next;
- current_edit = current_edit->next)
- {
+ current_edit = current_edit->next) {
- if(current_edit->asset &&
- current_edit->next->asset)
- {
+ if(current_edit->asset && current_edit->next->asset) {
if(current_edit->asset->equivalent(*current_edit->next->asset,
- 0,
- 0))
- {
+ 0, 0)) {
// Got two consecutive edits in same source
if(edl->equivalent(track->from_units(current_edit->next->startproject),
- start))
- {
+ start)) {
// handle selected
int length = -current_edit->length;
current_edit->length = current_edit->next->startsource - current_edit->startsource;
return 0;
}
-int Edits::modify_handles(double oldposition,
- double newposition,
- int currentend,
- int edit_mode,
- int edit_edits,
- int edit_labels,
- int edit_plugins,
- int edit_autos,
+int Edits::modify_handles(double oldposition, double newposition, int currentend,
+ int edit_mode, int edit_edits, int edit_labels, int edit_plugins, int edit_autos,
Edits *trim_edits)
{
int result = 0;
Edit *current_edit;
//printf("Edits::modify_handles 1 %d %f %f\n", currentend, newposition, oldposition);
- if(currentend == 0)
- {
+ if(currentend == 0) {
// left handle
- for(current_edit = first; current_edit && !result;)
- {
+ for(current_edit = first; current_edit && !result;) {
if(edl->equivalent(track->from_units(current_edit->startproject),
- oldposition))
- {
+ oldposition)) {
// edit matches selection
//printf("Edits::modify_handles 3 %f %f\n", newposition, oldposition);
oldposition = track->from_units(current_edit->startproject);
result = 1;
- if(newposition >= oldposition)
- {
+ if(newposition >= oldposition) {
//printf("Edits::modify_handle 1 %s %f %f\n", track->title, oldposition, newposition);
// shift start of edit in
current_edit->shift_start_in(edit_mode,
if(!result) current_edit = current_edit->next;
}
}
- else
- {
+ else {
// right handle selected
- for(current_edit = first; current_edit && !result;)
- {
+ for(current_edit = first; current_edit && !result;) {
if(edl->equivalent(track->from_units(current_edit->startproject) +
- track->from_units(current_edit->length), oldposition))
- {
+ track->from_units(current_edit->length), oldposition)) {
oldposition = track->from_units(current_edit->startproject) +
track->from_units(current_edit->length);
result = 1;
//printf("Edits::modify_handle 3\n");
- if(newposition <= oldposition)
- {
+ if(newposition <= oldposition) {
// shift end of edit in
//printf("Edits::modify_handle 4\n");
current_edit->shift_end_in(edit_mode,
void Edits::paste_silence(int64_t start, int64_t end)
{
- // paste silence does not do anything if
- // a) paste silence is on empty track
- // b) paste silence is after last edit
- // in both cases editof returns NULL
Edit *new_edit = editof(start, PLAY_FORWARD, 0);
if (!new_edit) return;
- if (!new_edit->asset)
- { // in this case we extend already existing edit
- new_edit->length += end - start;
- } else
- { // we are in fact creating a new edit
+ if( !new_edit->silence() ) {
new_edit = insert_new_edit(start);
new_edit->length = end - start;
}
- for(Edit *current = new_edit->next; current; current = NEXT)
- {
+ else
+ new_edit->length += end - start;
+
+ for(Edit *current = new_edit->next; current; current = NEXT) {
current->startproject += end - start;
}
+
return;
}
{
Edit *new_edit = insert_new_edit(start);
new_edit->length = end - start;
- for(Edit *current = new_edit->next; current; current = NEXT)
- {
+ for(Edit *current = new_edit->next; current; current = NEXT) {
current->startproject += end - start;
}
return new_edit;
}
-
+
Edit* Edits::shift(int64_t position, int64_t difference)
{
Edit *new_edit = split_edit(position);
- for(Edit *current = first;
- current;
- current = NEXT)
- {
- if(current->startproject >= position)
- {
+ for(Edit *current = first; current; current = NEXT) {
+ if(current->startproject >= position) {
current->shift(difference);
}
}
int64_t sample,
int track_number);
// Split edit containing position.
- Edit* split_edit(int64_t position);
// Return the second edit in the split.
- Edit* split_edit(Edit *edit, int64_t position);
+ Edit* split_edit(int64_t position);
// Create a blank edit in the native data format
int clear_handle(double start,
double end,
#ifndef EDLSESSION_H
#define EDLSESSION_H
+#include "asset.inc"
#include "autoconf.inc"
#include "bcwindowbase.inc"
#include "bchash.inc"
#define OVERSAMPLE 8
-#if 1
-// Bresenham's
-void MaskUnit::draw_line_clamped(VFrame *frame,
- int x1,int y1, int x2,int y2, unsigned char k)
-{
- int w = frame->get_w(), h = frame->get_h();
- unsigned char **rows = (unsigned char**)frame->get_rows();
- int dx = x2-x1, dy = y2-y1;
-//printf("MaskUnit::draw_line_clamped(%d,%d -> %d,%d, 0x%02x\n", x1,y1, x2,y2, k);
-
- int ax = 2*abs(dx), ay = 2*abs(dy);
-
- if( ax > ay ) { /* x dominant */
- if( dx == 0 ) return;
- if( x1 > x2 ) {
- int xx = x2; x2 = x1; x1 = xx;
- int yy = y2; y2 = y1; y1 = yy;
- }
- if( x1 >= w || x2 < 0 ) return;
- if( dx < 0 ) { dx = -dx; dy = -dy; }
- int x = x1, y = y1, d = dx;
- int sy = dy < 0 ? -1 : 1;
- if( x1 < 0 ) {
- double py = -(double)dy/dx * x1 + y1 + 0.5;
- x = 0; y = py;
- d = (py - y) * ay;
- }
-
- for( int y0=-1;;) {
- if( x >= w ) return;
- if( y != y0 && y >= 0 && y < h ) {
- y0 = y;
- unsigned char *bp = rows[y] + x;
- *bp = *bp == k ? 0 : k;
- }
- if( x == x2 ) return;
- if( d < 0 ) { d += ax; y += sy; }
- d -= ay; ++x;
- }
- }
- else { /* y dominant */
- if( dy == 0 ) return;
- if( y1 > y2 ) {
- int xx = x2; x2 = x1; x1 = xx;
- int yy = y2; y2 = y1; y1 = yy;
- }
- if( y1 >= h || y2 < 0 ) return;
- if( dy < 0 ) { dx = -dx; dy = -dy; }
- int x = x1, y = y1, d = dy;
- int sx = dx < 0 ? -1 : 1;
- if( y1 < 0 ) {
- double px = -(double)dx/dy * y1 + x1 + 0.5;
- x = px; y = 0;
- d = (px - x) * ax;
- }
-
- for(;;) {
- if( y >= h ) return;
- if( x >= 0 && x < w ) {
- unsigned char *bp = rows[y] + x;
- *bp = *bp == k ? 0 : k;
- }
- if( y == y2 ) return;
- if( d < 0 ) { d += ay; x += sx; }
- d -= ax; ++y;
- }
- }
-}
-
-#else
-
void MaskUnit::draw_line_clamped(VFrame *frame,
int x1, int y1, int x2, int y2, unsigned char k)
{
}
}
-#endif
-
void MaskUnit::blur_strip(double *val_p,
double *val_m,
double *dst,
"void main() {\n"
" vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
" vec4 result = gl_FragColor / canvas;\n"
- " if(!canvas.r) result.r = 1.0;\n"
- " if(!canvas.g) result.g = 1.0;\n"
- " if(!canvas.b) result.b = 1.0;\n"
- " if(!canvas.a) result.a = 1.0;\n"
+ " if(canvas.r == 0.) result.r = 1.0;\n"
+ " if(canvas.g == 0.) result.g = 1.0;\n"
+ " if(canvas.b == 0.) result.b = 1.0;\n"
+ " if(canvas.a == 0.) result.a = 1.0;\n"
" result = clamp(result, 0.0, 1.0);\n"
" gl_FragColor = mix(canvas, result, alpha);\n"
"}\n";
"void main() {\n"
" vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
" vec4 result = max(canvas, gl_FragColor);\n"
- " result = clamp(result, 0.0, 1.0);\n"
" gl_FragColor = mix(canvas, result, alpha);\n"
"}\n";
"void main() {\n"
" vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
" vec4 result = min(canvas, gl_FragColor);\n"
- " result = clamp(result, 0.0, 1.0);\n"
" gl_FragColor = mix(canvas, result, alpha);\n"
"}\n";
"void main() {\n"
" vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
" vec4 result = (canvas + gl_FragColor) * 0.5;\n"
- " result = clamp(result, 0.0, 1.0);\n"
" gl_FragColor = mix(canvas, result, alpha);\n"
"}\n";
"void main() {\n"
" vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
" vec4 result = canvas + gl_FragColor - canvas * gl_FragColor;\n"
- " result = clamp(result, 0.0, 1.0);\n"
" gl_FragColor = mix(canvas, result, alpha);\n"
"}\n";
// command->frame->get_h(),
// BC_RGB888,
// -1);
-// command->frame->to_ram();
+// command->frame->screen_to_ram();
//
// window->clear_box(0,
// 0,
void VWindowEditing::set_position(double position)
{
EDL *edl = vwindow->get_edl();
- if( edl ) return;
+ if( !edl ) return;
if( get_position() != position ) {
position -= edl->session->get_frame_offset() / edl->session->frame_rate;
if( position < 0 ) position = 0;
}
}
- if(popup_down)
+ if( !use_title && status == BUTTON_DN ) {
+ result = 1;
+ }
+ else if(popup_down)
{
// Menu is down so dispatch to popup.
result = menu_popup->dispatch_button_release();
png_cmodel = PNG_COLOR_TYPE_RGB;
break;
+ case BC_RGBA8888:
+ case BC_YUVA8888:
+ png_cmodel = PNG_COLOR_TYPE_RGB_ALPHA;
+ break;
+
case BC_A8:
png_cmodel = PNG_COLOR_TYPE_GRAY;
break;
// Must be called from a synchronous opengl thread after enable_opengl.
void to_texture();
-// Transfer from PBuffer to RAM. Only used after Playback3D::overlay_sync
- void to_ram();
+// Transfer from PBuffer to RAM.
+// used in Playback3D::overlay_sync, plugin Overlay::handle_opengl
+ void screen_to_ram();
// Transfer contents of current pbuffer to texture,
// creating a new texture if necessary.
#endif
}
-void VFrame::to_ram()
-{
-#ifdef HAVE_GL
- switch(opengl_state)
- {
-// Only pbuffer is supported since this is only called after the
-// overlay operation onto the pbuffer.
- case VFrame::SCREEN:
- if(pbuffer)
- {
- enable_opengl();
-//printf("VFrame::to_ram %d %d\n", get_w(), get_h());
- glReadPixels(0,
- 0,
- get_w(),
- get_h(),
- GL_RGB,
- GL_UNSIGNED_BYTE,
- get_rows()[0]);
- flip_vert();
- }
- opengl_state = VFrame::RAM;
- return;
- }
-#endif
-}
-
void VFrame::create_pbuffer()
{
if(pbuffer &&
#ifdef HAVE_GL
// Create texture
BC_Texture::new_texture(&texture,
- get_w(),
- get_h(),
- get_color_model());
+ get_w(), get_h(), get_color_model());
- if(pbuffer)
- {
+ if(pbuffer) {
glEnable(GL_TEXTURE_2D);
// Read canvas into texture, use back texture for DOUBLE_BUFFER
#endif
}
+void VFrame::screen_to_ram()
+{
+#ifdef HAVE_GL
+ enable_opengl();
+ glReadBuffer(GL_BACK);
+ int type = BC_CModels::is_float(color_model) ? GL_FLOAT : GL_UNSIGNED_BYTE;
+ int format = BC_CModels::has_alpha(color_model) ? GL_RGBA : GL_RGB;
+ glReadPixels(0, 0, get_w(), get_h(), format, type, get_rows()[0]);
+ opengl_state = VFrame::RAM;
+#endif
+}
+
void VFrame::draw_texture(float in_x1,
float in_y1,
float in_x2,
#include "bcdisplayinfo.h"
#include "clip.h"
#include "bchash.h"
+#include "edlsession.h"
#include "filexml.h"
#include "guicast.h"
#include "keyframe.h"
VFrame *temp;
int current_layer;
int output_layer;
-// Inclusive layer numbers
- int input_layer1;
- int input_layer2;
+ int input_layer;
};
OverlayConfig::OverlayConfig()
{
load_configuration();
-
- if(!temp) temp = new VFrame(0,
- -1,
- frame[0]->get_w(),
- frame[0]->get_h(),
- frame[0]->get_color_model(),
- -1);
-
- if(!overlayer)
- overlayer = new OverlayFrame(get_project_smp() + 1);
-
- int step;
- VFrame *output;
-
- if(config.direction == OverlayConfig::BOTTOM_FIRST)
- {
- input_layer1 = get_total_buffers() - 1;
- input_layer2 = -1;
- step = -1;
- }
- else
- {
- input_layer1 = 0;
- input_layer2 = get_total_buffers();
- step = 1;
- }
-
- if(config.output_layer == OverlayConfig::TOP)
- {
- output_layer = 0;
- }
- else
- {
- output_layer = get_total_buffers() - 1;
- }
-
-
-
-// Direct copy the first layer
- output = frame[output_layer];
- read_frame(output,
- input_layer1,
- start_position,
- frame_rate,
- get_use_opengl());
-
- if(get_total_buffers() == 1) return 0;
-
-
-
- current_layer = input_layer1;
- if(get_use_opengl())
- run_opengl();
-
- for(int i = input_layer1 + step; i != input_layer2; i += step)
- {
- read_frame(temp,
- i,
- start_position,
- frame_rate,
- get_use_opengl());
-
-// Call the opengl handler once for each layer
- if(get_use_opengl())
- {
- current_layer = i;
- run_opengl();
- }
- else
- {
- overlayer->overlay(output,
- temp,
- 0,
- 0,
- output->get_w(),
- output->get_h(),
- 0,
- 0,
- output->get_w(),
- output->get_h(),
- 1,
- config.mode,
- NEAREST_NEIGHBOR);
+ EDLSession* session = get_edlsession();
+ int interpolation_type = session ? session->interpolation_type : NEAREST_NEIGHBOR;
+
+ int step = config.direction == OverlayConfig::BOTTOM_FIRST ? -1 : 1;
+ int layers = get_total_buffers();
+ input_layer = config.direction == OverlayConfig::BOTTOM_FIRST ? layers-1 : 0;
+ output_layer = config.output_layer == OverlayConfig::TOP ? 0 : layers-1;
+ VFrame *output = frame[output_layer];
+
+ current_layer = input_layer;
+ read_frame(output, current_layer, // Direct copy the first layer
+ start_position, frame_rate, get_use_opengl());
+
+ if( --layers > 0 ) { // need 2 layers to do overlay
+ if( !temp )
+ temp = new VFrame(0, -1, frame[0]->get_w(), frame[0]->get_h(),
+ frame[0]->get_color_model(), -1);
+
+ while( --layers >= 0 ) {
+ current_layer += step;
+ read_frame(temp, current_layer,
+ start_position, frame_rate, get_use_opengl());
+
+ if(get_use_opengl()) {
+ run_opengl();
+ continue;
+ }
+
+ if(!overlayer)
+ overlayer = new OverlayFrame(get_project_smp() + 1);
+
+ overlayer->overlay(output, temp,
+ 0, 0, output->get_w(), output->get_h(),
+ 0, 0, output->get_w(), output->get_h(),
+ 1, config.mode, interpolation_type);
}
}
-
return 0;
}
"uniform vec3 chroma_offset;\n"
"void main()\n"
"{\n"
- " vec4 result_color;\n"
" vec4 dst_color = texture2D(dst_tex, gl_FragCoord.xy / dst_tex_dimensions);\n"
" vec4 src_color = texture2D(src_tex, gl_TexCoord[0].st);\n"
" src_color.rgb -= chroma_offset;\n"
" dst_color.rgb -= chroma_offset;\n";
static const char *put_pixels_frag =
- " result_color.rgb += chroma_offset;\n"
- " result_color.rgb = mix(dst_color.rgb, result_color.rgb, src_color.a);\n"
- " result_color.a = max(src_color.a, dst_color.a);\n"
- " gl_FragColor = result_color;\n"
+ " result.rgb += chroma_offset;\n"
+ " gl_FragColor = result;\n"
"}\n";
- static const char *blend_add_frag =
- " result_color.rgb = dst_color.rgb + src_color.rgb;\n";
-
- static const char *blend_max_frag =
- " result_color.r = max(abs(dst_color.r, src_color.r);\n"
- " result_color.g = max(abs(dst_color.g, src_color.g);\n"
- " result_color.b = max(abs(dst_color.b, src_color.b);\n";
-
- static const char *blend_min_frag =
- " result_color.r = min(abs(dst_color.r, src_color.r);\n"
- " result_color.g = min(abs(dst_color.g, src_color.g);\n"
- " result_color.b = min(abs(dst_color.b, src_color.b);\n";
-
- static const char *blend_subtract_frag =
- " result_color.rgb = dst_color.rgb - src_color.rgb;\n";
-
-
- static const char *blend_multiply_frag =
- " result_color.rgb = dst_color.rgb * src_color.rgb;\n";
-
- static const char *blend_divide_frag =
- " result_color.rgb = dst_color.rgb / src_color.rgb;\n"
- " if(src_color.r == 0.0) result_color.r = 1.0;\n"
- " if(src_color.g == 0.0) result_color.g = 1.0;\n"
- " if(src_color.b == 0.0) result_color.b = 1.0;\n";
+// NORMAL
+static const char *blend_normal_frag =
+ " vec4 result = mix(src_color, src_color, src_color.a);\n";
+
+// ADDITION
+static const char *blend_add_frag =
+ " vec4 result = dst_color + src_color;\n"
+ " result = clamp(result, 0.0, 1.0);\n";
+
+// SUBTRACT
+static const char *blend_subtract_frag =
+ " vec4 result = dst_color - src_color;\n"
+ " result = clamp(result, 0.0, 1.0);\n";
+
+// MULTIPLY
+static const char *blend_multiply_frag =
+ " vec4 result = dst_color * src_color;\n";
+
+// DIVIDE
+static const char *blend_divide_frag =
+ " vec4 result = dst_color / src_color;\n"
+ " if(src_color.r == 0.) result.r = 1.0;\n"
+ " if(src_color.g == 0.) result.g = 1.0;\n"
+ " if(src_color.b == 0.) result.b = 1.0;\n"
+ " if(src_color.a == 0.) result.a = 1.0;\n"
+ " result = clamp(result, 0.0, 1.0);\n";
+
+// MAX
+static const char *blend_max_frag =
+ " vec4 result = max(src_color, dst_color);\n";
+
+// MIN
+static const char *blend_min_frag =
+ " vec4 result = min(src_color, dst_color);\n";
+
+// AVERAGE
+static const char *blend_average_frag =
+ " vec4 result = (src_color + dst_color) * 0.5;\n";
+
+// DARKEN
+static const char *blend_darken_frag =
+ " vec4 result = vec4(src_color.rgb * (1.0 - dst_color.a) +"
+ " dst_color.rgb * (1.0 - src_color.a) +"
+ " min(src_color.rgb, dst_color.rgb), "
+ " src_color.a + dst_color.a - src_color.a * dst_color.a);\n"
+ " result = clamp(result, 0.0, 1.0);\n";
+
+// LIGHTEN
+static const char *blend_lighten_frag =
+ " vec4 result = vec4(src_color.rgb * (1.0 - dst_color.a) +"
+ " dst_color.rgb * (1.0 - src_color.a) +"
+ " max(src_color.rgb, dst_color.rgb), "
+ " src_color.a + dst_color.a - src_color.a * dst_color.a);\n"
+ " result = clamp(result, 0.0, 1.0);\n";
+
+// DST
+static const char *blend_dst_frag =
+ " vec4 result = dst_color;\n";
+
+// DST_ATOP
+static const char *blend_dst_atop_frag =
+ " vec4 result = vec4(src_color.rgb * dst_color.a + "
+ "(1.0 - src_color.a) * dst_color.rgb, dst_color.a);\n";
+
+// DST_IN
+static const char *blend_dst_in_frag =
+ " vec4 result = src_color * dst_color.a;\n";
+
+// DST_OUT
+static const char *blend_dst_out_frag =
+ " vec4 result = src_color * (1.0 - dst_color.a);\n";
+
+// DST_OVER
+static const char *blend_dst_over_frag =
+ " vec4 result = vec4(src_color.rgb + (1.0 - src_color.a) * dst_color.rgb, "
+ " dst_color.a + src_color.a - dst_color.a * src_color.a);\n";
+
+// SRC
+static const char *blend_src_frag =
+ " vec4 result = src_color;\n";
+
+// SRC_ATOP
+static const char *blend_src_atop_frag =
+ " vec4 result = vec4(dst_color.rgb * src_color.a + "
+ "src_color.rgb * (1.0 - dst_color.a), src_color.a);\n";
+
+// SRC_IN
+static const char *blend_src_in_frag =
+ " vec4 result = dst_color * src_color.a;\n";
+
+// SRC_OUT
+static const char *blend_src_out_frag =
+ " vec4 result = dst_color * (1.0 - src_color.a);\n";
+
+// SRC_OVER
+static const char *blend_src_over_frag =
+ " vec4 result = vec4(dst_color.rgb + (1.0 - dst_color.a) * src_color.rgb, "
+ "dst_color.a + src_color.a - dst_color.a * src_color.a);\n";
+
+// OR
+static const char *blend_or_frag =
+ " vec4 result = src_color + dst_color - src_color * dst_color;\n";
+
+// XOR
+static const char *blend_xor_frag =
+ " vec4 result = vec4(dst_color.rgb * (1.0 - src_color.a) + "
+ "(1.0 - dst_color.a) * src_color.rgb, "
+ "dst_color.a + src_color.a - 2.0 * dst_color.a * src_color.a);\n";
+
+static const char * const overlay_shaders[TRANSFER_TYPES] = {
+ blend_normal_frag, // TRANSFER_NORMAL
+ blend_add_frag, // TRANSFER_ADDITION
+ blend_subtract_frag, // TRANSFER_SUBTRACT
+ blend_multiply_frag, // TRANSFER_MULTIPLY
+ blend_divide_frag, // TRANSFER_DIVIDE
+ blend_src_frag, // TRANSFER_REPLACE
+ blend_max_frag, // TRANSFER_MAX
+ blend_min_frag, // TRANSFER_MIN
+ blend_average_frag, // TRANSFER_AVERAGE
+ blend_darken_frag, // TRANSFER_DARKEN
+ blend_lighten_frag, // TRANSFER_LIGHTEN
+ blend_dst_frag, // TRANSFER_DST
+ blend_dst_atop_frag, // TRANSFER_DST_ATOP
+ blend_dst_in_frag, // TRANSFER_DST_IN
+ blend_dst_out_frag, // TRANSFER_DST_OUT
+ blend_dst_over_frag, // TRANSFER_DST_OVER
+ blend_src_frag, // TRANSFER_SRC
+ blend_src_atop_frag, // TRANSFER_SRC_ATOP
+ blend_src_in_frag, // TRANSFER_SRC_IN
+ blend_src_out_frag, // TRANSFER_SRC_OUT
+ blend_src_over_frag, // TRANSFER_SRC_OVER
+ blend_or_frag, // TRANSFER_OR
+ blend_xor_frag // TRANSFER_XOR
+ };
- VFrame *src = temp;
+ glDisable(GL_BLEND);
VFrame *dst = get_output(output_layer);
+ VFrame *src = temp;
- dst->enable_opengl();
- dst->init_screen();
-
- const char *shader_stack[] = { 0, 0, 0 };
- int current_shader = 0;
-
-
-
-
+ switch( config.mode ) {
+ case TRANSFER_REPLACE:
+ case TRANSFER_SRC:
// Direct copy layer
- if(config.mode == TRANSFER_REPLACE)
- {
- src->to_texture();
- src->bind_texture(0);
- dst->enable_opengl();
+ src->to_texture();
+ dst->enable_opengl();
dst->init_screen();
-
-// Multiply alpha
- glDisable(GL_BLEND);
src->draw_texture();
- }
- else
- if(config.mode == TRANSFER_NORMAL)
- {
- dst->enable_opengl();
- dst->init_screen();
-
+ break;
+ case TRANSFER_NORMAL:
// Move destination to screen
- if(dst->get_opengl_state() != VFrame::SCREEN)
- {
+ if( dst->get_opengl_state() != VFrame::SCREEN ) {
dst->to_texture();
- dst->bind_texture(0);
+ dst->enable_opengl();
+ dst->init_screen();
dst->draw_texture();
}
-
- src->to_texture();
- src->bind_texture(0);
- dst->enable_opengl();
+ src->to_texture();
+ dst->enable_opengl();
dst->init_screen();
-
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
src->draw_texture();
- }
- else
- {
-// Read destination back to texture
+ break;
+ default:
+ src->to_texture();
dst->to_texture();
-
- src->enable_opengl();
- src->init_screen();
- src->to_texture();
-
- dst->enable_opengl();
+ dst->enable_opengl();
dst->init_screen();
- src->bind_texture(0);
- dst->bind_texture(1);
-
+ src->bind_texture(0);
+ dst->bind_texture(1);
+ const char *shader_stack[] = { 0, 0, 0 };
+ int current_shader = 0;
shader_stack[current_shader++] = get_pixels_frag;
-
- switch(config.mode)
- {
- case TRANSFER_ADDITION:
- shader_stack[current_shader++] = blend_add_frag;
- break;
- case TRANSFER_SUBTRACT:
- shader_stack[current_shader++] = blend_subtract_frag;
- break;
- case TRANSFER_MULTIPLY:
- shader_stack[current_shader++] = blend_multiply_frag;
- break;
- case TRANSFER_DIVIDE:
- shader_stack[current_shader++] = blend_divide_frag;
- break;
- case TRANSFER_MAX:
- shader_stack[current_shader++] = blend_max_frag;
- break;
- case TRANSFER_MIN:
- shader_stack[current_shader++] = blend_min_frag;
- break;
- }
-
+ shader_stack[current_shader++] = overlay_shaders[config.mode];
shader_stack[current_shader++] = put_pixels_frag;
unsigned int shader_id = 0;
glUseProgram(shader_id);
glUniform1i(glGetUniformLocation(shader_id, "src_tex"), 0);
glUniform1i(glGetUniformLocation(shader_id, "dst_tex"), 1);
- if(BC_CModels::is_yuv(dst->get_color_model()))
- glUniform3f(glGetUniformLocation(shader_id, "chroma_offset"), 0.0, 0.5, 0.5);
- else
- glUniform3f(glGetUniformLocation(shader_id, "chroma_offset"), 0.0, 0.0, 0.0);
glUniform2f(glGetUniformLocation(shader_id, "dst_tex_dimensions"),
- (float)dst->get_texture_w(),
- (float)dst->get_texture_h());
+ (float)dst->get_texture_w(), (float)dst->get_texture_h());
+ float chroma_offset = BC_CModels::is_yuv(dst->get_color_model()) ? 0.5 : 0.0;
+ glUniform3f(glGetUniformLocation(shader_id, "chroma_offset"),
+ 0.0, chroma_offset, chroma_offset);
- glDisable(GL_BLEND);
src->draw_texture();
glUseProgram(0);
+
+ glActiveTexture(GL_TEXTURE1);
+ glDisable(GL_TEXTURE_2D);
+ break;
}
- glDisable(GL_BLEND);
- glActiveTexture(GL_TEXTURE1);
- glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
- dst->set_opengl_state(VFrame::SCREEN);
+// get the data before something else uses the screen
+ dst->screen_to_ram();
#endif
return 0;
}