From 5820b5f022aeec75ec03f7dd0121aa8a3d7f7590 Mon Sep 17 00:00:00 2001 From: Good Guy Date: Sat, 26 Mar 2016 14:04:35 -0600 Subject: [PATCH] merge: fixes/rework for fader, single frame ffmpeg, dissolve, silence --- cinelerra-5.1/bld_scripts/bld_dynamic.sh | 2 +- cinelerra-5.1/bld_scripts/bld_static.sh | 2 +- cinelerra-5.1/cinelerra/assetedit.C | 86 ++++------- cinelerra-5.1/cinelerra/assetedit.h | 19 +-- cinelerra-5.1/cinelerra/cachebase.C | 2 +- cinelerra-5.1/cinelerra/channelinfo.C | 2 +- cinelerra-5.1/cinelerra/dbwindow.C | 2 +- cinelerra-5.1/cinelerra/edl.C | 16 ++- cinelerra-5.1/cinelerra/exportedl.C | 2 +- cinelerra-5.1/cinelerra/file.C | 18 +-- cinelerra-5.1/cinelerra/filebase.C | 2 - cinelerra-5.1/cinelerra/filebase.h | 2 - cinelerra-5.1/cinelerra/fileffmpeg.C | 8 +- cinelerra-5.1/cinelerra/framecache.C | 36 ++--- cinelerra-5.1/cinelerra/mainmenu.C | 16 +-- cinelerra-5.1/cinelerra/overlayframe.C | 19 ++- cinelerra-5.1/cinelerra/playback3d.C | 25 +--- cinelerra-5.1/cinelerra/preferencesthread.C | 2 +- cinelerra-5.1/cinelerra/render.C | 2 +- cinelerra-5.1/cinelerra/swindow.C | 2 +- cinelerra-5.1/cinelerra/virtualvnode.C | 2 +- cinelerra-5.1/cinelerra/vrender.C | 21 +-- cinelerra-5.1/msg.txt | 1 + cinelerra-5.1/plugins/dissolve/dissolve.C | 149 ++++++++------------ 24 files changed, 150 insertions(+), 288 deletions(-) diff --git a/cinelerra-5.1/bld_scripts/bld_dynamic.sh b/cinelerra-5.1/bld_scripts/bld_dynamic.sh index 80438ea3..fdf54679 100755 --- a/cinelerra-5.1/bld_scripts/bld_dynamic.sh +++ b/cinelerra-5.1/bld_scripts/bld_dynamic.sh @@ -39,5 +39,5 @@ make >> log 2>&1 $@ make install >> log 2>&1 echo "finished: scanning log for ***" -grep -a "\*\*\*" log +grep -ai "\*\*\*.*error" log diff --git a/cinelerra-5.1/bld_scripts/bld_static.sh b/cinelerra-5.1/bld_scripts/bld_static.sh index c6157f77..e41df88c 100755 --- a/cinelerra-5.1/bld_scripts/bld_static.sh +++ b/cinelerra-5.1/bld_scripts/bld_static.sh @@ -39,5 +39,5 @@ make >> log 2>&1 $@ make install >> log 2>&1 echo "finished: scanning log for ***" -grep -a "\*\*\*" log +grep -ai "\*\*\*.*error" log diff --git a/cinelerra-5.1/cinelerra/assetedit.C b/cinelerra-5.1/cinelerra/assetedit.C index 9d3e6869..cb633437 100644 --- a/cinelerra-5.1/cinelerra/assetedit.C +++ b/cinelerra-5.1/cinelerra/assetedit.C @@ -108,6 +108,17 @@ void AssetEdit::edit_asset(Indexable *indexable) BC_DialogThread::start(); } +void AssetEdit::handle_done_event(int result) +{ + if( !result ) { + changed_params->tcstart = ceil(indexable->get_frame_rate() * + (atoi(window->tc_hours_textbox->get_text()) * 3600 + + atoi(window->tc_minutes_textbox->get_text()) * 60 + + atoi(window->tc_seconds_textbox->get_text()))) + + atoi(window->tc_rest_textbox->get_text()); + } +} + void AssetEdit::handle_close_event(int result) { if(!result) @@ -609,39 +620,24 @@ void AssetEditWindow::create_objects() x = x2; // Calculate values to enter into textboxes - char tc[12]; - - Units::totext(tc, - asset->tcstart / asset->frame_rate, - TIME_HMSF, - asset->sample_rate, - asset->frame_rate); - - char *tc_hours = tc; - char *tc_minutes = strchr(tc, ':') + 1; - *(tc_minutes - 1) = 0; - char *tc_seconds = strchr(tc_minutes, ':') + 1; - *(tc_seconds - 1) = 0; - char *tc_rest = strchr(tc_seconds, ':') + 1; - *(tc_rest - 1) = 0; - - add_subwindow(new AssetEditTCStartTextBox(this, atoi(tc_hours), x, y, - (int) (asset->frame_rate * 60 * 60))); - x += 30; - add_subwindow(new BC_Title(x, y, ":")); - x += 10; - add_subwindow(new AssetEditTCStartTextBox(this, atoi(tc_minutes), x, y, - (int) (asset->frame_rate * 60))); - x += 30; - add_subwindow(new BC_Title(x, y, ":")); - x += 10; - add_subwindow(new AssetEditTCStartTextBox(this, atoi(tc_seconds), x, y, - (int) (asset->frame_rate))); - x += 30; - add_subwindow(new BC_Title(x, y, ":")); - x += 10; - add_subwindow(new AssetEditTCStartTextBox(this, atoi(tc_rest), x, y, 1)); - + char text[32], *tc = text; + Units::totext(tc, asset->tcstart / asset->frame_rate, + TIME_HMSF, asset->sample_rate, asset->frame_rate); + + const char *tc_hours = tc, *tc_minutes, *tc_seconds, *tc_rest; + tc = strchr(tc, ':'); *tc++ = 0; tc_minutes = tc; + tc = strchr(tc, ':'); *tc++ = 0; tc_seconds = tc; + tc = strchr(tc, ':'); *tc++ = 0; tc_rest = tc; + + int padw = BC_Title::calculate_w(this, ":", MEDIUMFONT); + int fldw = BC_Title::calculate_w(this, "00", MEDIUMFONT) + 5; + add_subwindow(tc_hours_textbox = new BC_TextBox(x, y, fldw, 1, tc_hours)); + add_subwindow(new BC_Title(x += tc_hours_textbox->get_w(), y, ":")); + add_subwindow(tc_minutes_textbox = new BC_TextBox(x += padw, y, fldw, 1, tc_minutes)); + add_subwindow(new BC_Title(x += tc_minutes_textbox->get_w(), y, ":")); + add_subwindow(tc_seconds_textbox = new BC_TextBox(x += padw, y , fldw, 1, tc_seconds)); + add_subwindow(new BC_Title(x += tc_seconds_textbox->get_w(), y, ":")); + add_subwindow(tc_rest_textbox = new BC_TextBox(x += 10, y, fldw, 1, tc_rest)); y += 30; } @@ -1090,7 +1086,7 @@ void DetailAssetThread::run() AssetEditReelName::AssetEditReelName(AssetEditWindow *fwindow, int x, int y) - : BC_TextBox(x, y, 300, 1, + : BC_TextBox(x, y, 220, 1, ((Asset *)fwindow->asset_edit->indexable)->reel_name, 1, MEDIUMFONT, 1) { @@ -1127,25 +1123,3 @@ int AssetEditReelNumber::handle_event() - - -AssetEditTCStartTextBox::AssetEditTCStartTextBox(AssetEditWindow *fwindow, int value, int x, int y, int multiplier) - : BC_TextBox(x, y, 30, 1, value) -{ - this->fwindow = fwindow; - this->multiplier = multiplier; - previous = value; -} -AssetEditTCStartTextBox::~AssetEditTCStartTextBox() -{ -} -int AssetEditTCStartTextBox::handle_event() -{ - Asset *asset = fwindow->asset_edit->changed_params; - asset->tcstart -= previous * multiplier; - asset->tcstart += atoi(get_text()) * multiplier; - previous = atoi(get_text()); - return 1; -} - - diff --git a/cinelerra-5.1/cinelerra/assetedit.h b/cinelerra-5.1/cinelerra/assetedit.h index 98cbcc0c..bc5503c9 100644 --- a/cinelerra-5.1/cinelerra/assetedit.h +++ b/cinelerra-5.1/cinelerra/assetedit.h @@ -35,7 +35,6 @@ #include "resizetrackthread.inc" -class AssetEditTCStartTextBox; class AssetEditReelNumber; class AssetEditReelName; class AssetEditByteOrderHILO; @@ -56,6 +55,7 @@ public: void edit_asset(Indexable *indexable); int set_asset(Indexable *indexable); + void handle_done_event(int result); void handle_close_event(int result); BC_Window* new_gui(); @@ -84,6 +84,8 @@ public: AssetEditPath *path_button; AssetEditByteOrderHILO *hilo; AssetEditByteOrderLOHI *lohi; + BC_TextBox *tc_hours_textbox, *tc_minutes_textbox; + BC_TextBox *tc_seconds_textbox, *tc_rest_textbox; BitsPopup *bitspopup; int allow_edits; MWindow *mwindow; @@ -92,6 +94,7 @@ public: BC_Title *win_height; DetailAssetThread *detail_thread; void show_info_detail(); + }; @@ -295,20 +298,6 @@ public: AssetEditWindow *fwindow; }; -class AssetEditTCStartTextBox : public BC_TextBox -{ -public: - AssetEditTCStartTextBox(AssetEditWindow *fwindow, int value, int x, int y, int multiplier); - ~AssetEditTCStartTextBox(); - int handle_event(); - - AssetEditWindow *fwindow; -// Multiplier is the # of frames for whatever unit of time this is. -// fps dependent, and unit dependent - int multiplier; - int previous; -}; - class DetailAssetWindow : public BC_Window { MWindow *mwindow; diff --git a/cinelerra-5.1/cinelerra/cachebase.C b/cinelerra-5.1/cinelerra/cachebase.C index 267ff515..8e02543a 100644 --- a/cinelerra-5.1/cinelerra/cachebase.C +++ b/cinelerra-5.1/cinelerra/cachebase.C @@ -120,7 +120,7 @@ int CacheBase::delete_oldest() if( current->age < oldest->age ) oldest = current; } - if( oldest ) { + if( oldest && oldest->position >= 0 ) { del_item(oldest); result = 1; } diff --git a/cinelerra-5.1/cinelerra/channelinfo.C b/cinelerra-5.1/cinelerra/channelinfo.C index 03d8d842..140f3d30 100644 --- a/cinelerra-5.1/cinelerra/channelinfo.C +++ b/cinelerra-5.1/cinelerra/channelinfo.C @@ -1787,7 +1787,7 @@ void ChannelInfo::delete_batch() } ChannelScan::ChannelScan(MWindow *mwindow) - : BC_MenuItem(_("Scan"), _("Shift-S"), 'S') + : BC_MenuItem(_("Scan..."), _("Shift-S"), 'S') { set_shift(); this->mwindow = mwindow; diff --git a/cinelerra-5.1/cinelerra/dbwindow.C b/cinelerra-5.1/cinelerra/dbwindow.C index 2a6395cf..c19b581e 100644 --- a/cinelerra-5.1/cinelerra/dbwindow.C +++ b/cinelerra-5.1/cinelerra/dbwindow.C @@ -199,7 +199,7 @@ keypress_event() DbWindowScan:: DbWindowScan(MWindow *mwindow) - : BC_MenuItem(_("Media DB"), _("Shift-M"), 'M') + : BC_MenuItem(_("Media DB..."), _("Shift-M"), 'M') { set_shift(); this->mwindow = mwindow; diff --git a/cinelerra-5.1/cinelerra/edl.C b/cinelerra-5.1/cinelerra/edl.C index d1d904aa..e167e48a 100644 --- a/cinelerra-5.1/cinelerra/edl.C +++ b/cinelerra-5.1/cinelerra/edl.C @@ -35,6 +35,7 @@ #include "filexml.h" #include "guicast.h" #include "indexstate.h" +#include "interlacemodes.h" #include "labels.h" #include "localsession.h" #include "mutex.h" @@ -1448,20 +1449,23 @@ if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__); if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__); // Edit is not a nested EDL + Asset *asset = (*playable_edit)->asset; // Edit is silence - if(!(*playable_edit)->asset) return 1; + if(!asset) return 1; if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__); - // Asset and output device must have the same dimensions - if((*playable_edit)->asset->width != session->output_w || - (*playable_edit)->asset->height != session->output_h) + if( asset->width != session->output_w || + asset->height != session->output_h ) return 1; if(debug) printf("EDL::get_use_vconsole %d\n", __LINE__); - - +// Asset and output device must have same resulting de-interlacing method + if( ilaceautofixmethod2(session->interlace_mode, + asset->interlace_autofixoption, asset->interlace_mode, + asset->interlace_fixmethod) != BC_ILACE_FIXMETHOD_NONE ) + return 1; // If we get here the frame is going to be directly copied. Whether it is // decompressed in hardware depends on the colormodel. diff --git a/cinelerra-5.1/cinelerra/exportedl.C b/cinelerra-5.1/cinelerra/exportedl.C index 21e02bfe..04e22ebd 100644 --- a/cinelerra-5.1/cinelerra/exportedl.C +++ b/cinelerra-5.1/cinelerra/exportedl.C @@ -252,7 +252,7 @@ int ExportEDLAsset::save_defaults() ExportEDLItem::ExportEDLItem(MWindow *mwindow) - : BC_MenuItem(_("Export EDL..."), "Shift+E", 'E') + : BC_MenuItem(_("Export EDL..."), "Shift-E", 'E') { this->mwindow = mwindow; set_shift(1); diff --git a/cinelerra-5.1/cinelerra/file.C b/cinelerra-5.1/cinelerra/file.C index 103c9a4d..f5932e3e 100644 --- a/cinelerra-5.1/cinelerra/file.C +++ b/cinelerra-5.1/cinelerra/file.C @@ -1171,13 +1171,11 @@ int File::read_frame(VFrame *frame, int is_thread) if(debug) PRINT_TRACE int supported_colormodel = colormodel_supported(frame->get_color_model()); int advance_position = 1; - + int cache_active = use_cache || asset->video_length < 0 ? 1 : 0; + int64_t cache_position = asset->video_length >= 0 ? current_frame : -1; // Test cache - if(use_cache && - frame_cache->get_frame(frame, - current_frame, - current_layer, - asset->frame_rate)) + if( cache_active && frame_cache->get_frame(frame, cache_position, + current_layer, asset->frame_rate) ) { // Can't advance position if cache used. //printf("File::read_frame %d\n", __LINE__); @@ -1245,11 +1243,9 @@ int File::read_frame(VFrame *frame, int is_thread) //for(int i = 0; i < 100 * 1000; i++) ((float*)frame->get_rows()[0])[i] = 1.0; } -//printf("File::read_frame %d use_cache=%d\n", __LINE__, use_cache); - if(use_cache) - frame_cache->put_frame(frame, - current_frame, current_layer, - asset->frame_rate, 1, 0); + if( cache_active && advance_position && frame->get_status() > 0 ) + frame_cache->put_frame(frame, cache_position, + current_layer, asset->frame_rate, 1, 0); //printf("File::read_frame %d\n", __LINE__); if(advance_position) current_frame++; diff --git a/cinelerra-5.1/cinelerra/filebase.C b/cinelerra-5.1/cinelerra/filebase.C index b8a66316..5629f6c2 100644 --- a/cinelerra-5.1/cinelerra/filebase.C +++ b/cinelerra-5.1/cinelerra/filebase.C @@ -37,7 +37,6 @@ FileBase::FileBase(Asset *asset, File *file) this->asset = asset; internal_byte_order = get_byte_order(); reset_parameters(); - overlayer = new OverlayFrame; } FileBase::~FileBase() @@ -46,7 +45,6 @@ FileBase::~FileBase() if(row_pointers_in) delete [] row_pointers_in; if(row_pointers_out) delete [] row_pointers_out; if(float_buffer) delete [] float_buffer; - delete overlayer; } int FileBase::close_file() diff --git a/cinelerra-5.1/cinelerra/filebase.h b/cinelerra-5.1/cinelerra/filebase.h index a4b14dc9..db9e5b06 100644 --- a/cinelerra-5.1/cinelerra/filebase.h +++ b/cinelerra-5.1/cinelerra/filebase.h @@ -221,8 +221,6 @@ private: int delete_ulaw_tables(); float *ulawtofloat_table, *ulawtofloat_ptr; unsigned char *floattoulaw_table, *floattoulaw_ptr; - - OverlayFrame *overlayer; }; #endif diff --git a/cinelerra-5.1/cinelerra/fileffmpeg.C b/cinelerra-5.1/cinelerra/fileffmpeg.C index f2a0c43d..e311b25d 100644 --- a/cinelerra-5.1/cinelerra/fileffmpeg.C +++ b/cinelerra-5.1/cinelerra/fileffmpeg.C @@ -183,6 +183,8 @@ int FileFFMPEG::select_video_stream(Asset *asset, int vstream) asset->width = ff->ff_video_width(vstream); asset->height = ff->ff_video_height(vstream); asset->video_length = ff->ff_video_frames(vstream); + if( (asset->video_length = ff->ff_video_frames(vstream)) < 2 ) + asset->video_length = asset->video_length < 0 ? 0 : -1; asset->frame_rate = ff->ff_frame_rate(vstream); return 0; } @@ -220,7 +222,9 @@ int FileFFMPEG::open_file(int rd, int wr) asset->actual_height = ff->ff_video_height(0); if( !asset->width ) asset->width = asset->actual_width; if( !asset->height ) asset->height = asset->actual_height; - if( !asset->video_length ) asset->video_length = ff->ff_video_frames(0); + if( !asset->video_length && + (asset->video_length = ff->ff_video_frames(0)) < 2 ) + asset->video_length = asset->video_length < 0 ? 0 : -1; if( !asset->frame_rate ) asset->frame_rate = ff->ff_frame_rate(0); } IndexState *index_state = asset->index_state; @@ -283,7 +287,7 @@ int FileFFMPEG::read_frame(VFrame *frame) { if( !ff ) return -1; int layer = file->current_layer; - int64_t pos = file->current_frame; + int64_t pos = asset->video_length >= 0 ? file->current_frame : 0; int ret = ff->decode(layer, pos, frame); frame->set_status(ret); if( ret >= 0 ) return 0; diff --git a/cinelerra-5.1/cinelerra/framecache.C b/cinelerra-5.1/cinelerra/framecache.C index a5f6deb2..afb149f0 100644 --- a/cinelerra-5.1/cinelerra/framecache.C +++ b/cinelerra-5.1/cinelerra/framecache.C @@ -29,6 +29,7 @@ #include "vframe.h" +#include #include #include #include @@ -173,12 +174,8 @@ VFrame* FrameCache::get_frame_ptr(int64_t position, // Puts frame in cache if enough space exists and the frame doesn't already // exist. -void FrameCache::put_frame(VFrame *frame, - int64_t position, - int layer, - double frame_rate, - int use_copy, - Indexable *indexable) +void FrameCache::put_frame(VFrame *frame, int64_t position, + int layer, double frame_rate, int use_copy, Indexable *indexable) { lock->lock("FrameCache::put_frame"); FrameCacheItem *item = 0; @@ -187,13 +184,7 @@ void FrameCache::put_frame(VFrame *frame, //printf("FrameCache::put_frame %d position=%jd\n", __LINE__, position); - if(frame_exists(frame, - position, - layer, - frame_rate, - &item, - source_id)) - { + if(frame_exists(frame, position, layer, frame_rate, &item, source_id)) { item->age = get_age(); lock->unlock(); return; @@ -202,14 +193,7 @@ void FrameCache::put_frame(VFrame *frame, item = new FrameCacheItem; - if(use_copy) - { - item->data = new VFrame(*frame); - } - else - { - item->data = frame; - } + item->data = use_copy ? new VFrame(*frame) : frame; // Copy metadata item->position = position; @@ -219,7 +203,7 @@ void FrameCache::put_frame(VFrame *frame, if(indexable) item->path = cstrdup(indexable->path); - item->age = get_age(); + item->age = position < 0 ? INT_MAX : get_age(); //printf("FrameCache::put_frame %d position=%jd\n", __LINE__, position); put_item(item); @@ -229,12 +213,8 @@ void FrameCache::put_frame(VFrame *frame, -int FrameCache::frame_exists(VFrame *format, - int64_t position, - int layer, - double frame_rate, - FrameCacheItem **item_return, - int source_id) +int FrameCache::frame_exists(VFrame *format, int64_t position, + int layer, double frame_rate, FrameCacheItem **item_return, int source_id) { FrameCacheItem *item = (FrameCacheItem*)get_item(position); // printf("FrameCache::frame_exists %d item=%p item->position=%jd position=%jd\n", diff --git a/cinelerra-5.1/cinelerra/mainmenu.C b/cinelerra-5.1/cinelerra/mainmenu.C index b02812ac..b04800bb 100644 --- a/cinelerra-5.1/cinelerra/mainmenu.C +++ b/cinelerra-5.1/cinelerra/mainmenu.C @@ -251,7 +251,7 @@ void MainMenu::create_objects() windowmenu->add_item(new BC_MenuItem("-")); windowmenu->add_item(split_x = new SplitX(mwindow)); windowmenu->add_item(split_y = new SplitY(mwindow)); - windowmenu->add_item(new TileWindows(mwindow,_("Default positions"),-1,_("Ctrl+P"),'p')); + windowmenu->add_item(new TileWindows(mwindow,_("Default positions"),-1,_("Ctrl-P"),'p')); windowmenu->add_item(new TileWindows(mwindow,_("Tile left"),0)); windowmenu->add_item(new TileWindows(mwindow,_("Tile right"),1)); } @@ -627,7 +627,7 @@ int Undo::update_caption(const char *new_caption) } -Redo::Redo(MWindow *mwindow) : BC_MenuItem(_("Redo"), _("Shift+Z"), 'Z') +Redo::Redo(MWindow *mwindow) : BC_MenuItem(_("Redo"), _("Shift-Z"), 'Z') { set_shift(1); this->mwindow = mwindow; @@ -891,7 +891,7 @@ int Clear::handle_event() } PasteSilence::PasteSilence(MWindow *mwindow) - : BC_MenuItem(_("Paste silence"), _("Shift+Space"), ' ') + : BC_MenuItem(_("Paste silence"), _("Shift-Space"), ' ') { this->mwindow = mwindow; set_shift(); @@ -1146,7 +1146,7 @@ int DeleteTrack::handle_event() } MoveTracksUp::MoveTracksUp(MWindow *mwindow) - : BC_MenuItem(_("Move tracks up"), _("Shift+Up"), UP) + : BC_MenuItem(_("Move tracks up"), _("Shift-Up"), UP) { set_shift(); this->mwindow = mwindow; } @@ -1158,7 +1158,7 @@ int MoveTracksUp::handle_event() } MoveTracksDown::MoveTracksDown(MWindow *mwindow) - : BC_MenuItem(_("Move tracks down"), _("Shift+Down"), DOWN) + : BC_MenuItem(_("Move tracks down"), _("Shift-Down"), DOWN) { set_shift(); this->mwindow = mwindow; } @@ -1190,7 +1190,7 @@ int ConcatenateTracks::handle_event() LoopPlayback::LoopPlayback(MWindow *mwindow) - : BC_MenuItem(_("Loop Playback"), _("Shift+L"), 'L') + : BC_MenuItem(_("Loop Playback"), _("Shift-L"), 'L') { this->mwindow = mwindow; set_checked(mwindow->edl->local_session->loop_playback); @@ -1459,7 +1459,7 @@ int TileWindows::handle_event() } SplitX::SplitX(MWindow *mwindow) - : BC_MenuItem(_("Split X pane"), _("Ctrl+1"), '1') + : BC_MenuItem(_("Split X pane"), _("Ctrl-1"), '1') { this->mwindow = mwindow; set_ctrl(1); @@ -1472,7 +1472,7 @@ int SplitX::handle_event() } SplitY::SplitY(MWindow *mwindow) - : BC_MenuItem(_("Split Y pane"), _("Ctrl+2"), '2') + : BC_MenuItem(_("Split Y pane"), _("Ctrl-2"), '2') { this->mwindow = mwindow; set_ctrl(1); diff --git a/cinelerra-5.1/cinelerra/overlayframe.C b/cinelerra-5.1/cinelerra/overlayframe.C index 4de38e36..098bf9db 100644 --- a/cinelerra-5.1/cinelerra/overlayframe.C +++ b/cinelerra-5.1/cinelerra/overlayframe.C @@ -485,7 +485,7 @@ ZTYP(float); ZTYP(double); #define ALPHA3_BLEND(FN, typ, inp, out, mx, ofs, rnd) \ typ inp0 = (typ)inp[0], inp1 = (typ)inp[1] - ofs; \ - typ inp2 = (typ)inp[2] - ofs, inp3 = fade * mx + rnd; \ + typ inp2 = (typ)inp[2] - ofs, inp3 = mx; \ typ out0 = (typ)out[0], out1 = (typ)out[1] - ofs; \ typ out2 = (typ)out[2] - ofs, out3 = mx; \ r = COLOR_##FN(mx, inp0, inp3, out0, out3); \ @@ -500,7 +500,7 @@ ZTYP(float); ZTYP(double); #define ALPHA4_BLEND(FN, typ, inp, out, mx, ofs, rnd) \ typ inp0 = (typ)inp[0], inp1 = (typ)inp[1] - ofs; \ - typ inp2 = (typ)inp[2] - ofs, inp3 = (typ)inp[3] * fade + rnd; \ + typ inp2 = (typ)inp[2] - ofs, inp3 = inp[3]; \ typ out0 = (typ)out[0], out1 = (typ)out[1] - ofs; \ typ out2 = (typ)out[2] - ofs, out3 = out[3]; \ r = COLOR_##FN(mx, inp0, inp3, out0, out3); \ @@ -544,7 +544,7 @@ ZTYP(float); ZTYP(double); out[3] = aclip(a, mx) #define XBLEND(FN, temp_type, type, max, components, chroma_offset, round) { \ - temp_type opcty = alpha * max + round, trnsp = max - opcty; \ + temp_type opcty = fade * max + round, trnsp = max - opcty; \ type** output_rows = (type**)output->get_rows(); \ type** input_rows = (type**)input->get_rows(); \ ix *= components; ox *= components; \ @@ -608,8 +608,7 @@ void DirectUnit::process_package(LoadPackage *package) VFrame *output = engine->output; VFrame *input = engine->input; int mode = engine->mode; - float fade = engine->alpha; - float alpha = + float fade = BC_CModels::has_alpha(input->get_color_model()) && mode == TRANSFER_REPLACE ? 1.f : engine->alpha; @@ -690,7 +689,7 @@ LoadPackage* DirectEngine::new_package() /* Nearest Neighbor scale / translate / blend ********************/ #define XBLEND_3NN(FN, temp_type, type, max, components, chroma_offset, round) { \ - temp_type opcty = alpha * max + round, trnsp = max - opcty; \ + temp_type opcty = fade * max + round, trnsp = max - opcty; \ type** output_rows = (type**)output->get_rows(); \ type** input_rows = (type**)input->get_rows(); \ ox *= components; \ @@ -753,8 +752,7 @@ void NNUnit::process_package(LoadPackage *package) VFrame *output = engine->output; VFrame *input = engine->input; int mode = engine->mode; - float fade = engine->alpha; - float alpha = + float fade = BC_CModels::has_alpha(input->get_color_model()) && mode == TRANSFER_REPLACE ? 1.f : engine->alpha; @@ -909,7 +907,7 @@ LoadPackage* NNEngine::new_package() #define XSAMPLE(FN, temp_type, type, max, components, chroma_offset, round) { \ float temp[oh*components]; \ - temp_type opcty = alpha * max + round, trnsp = max - opcty; \ + temp_type opcty = fade * max + round, trnsp = max - opcty; \ type **output_rows = (type**)voutput->get_rows() + o1i; \ type **input_rows = (type**)vinput->get_rows(); \ \ @@ -1027,8 +1025,7 @@ void SampleUnit::process_package(LoadPackage *package) VFrame *voutput = engine->output; VFrame *vinput = engine->input; int mode = engine->mode; - float fade = engine->alpha; - float alpha = + float fade = BC_CModels::has_alpha(vinput->get_color_model()) && mode == TRANSFER_REPLACE ? 1.f : engine->alpha; diff --git a/cinelerra-5.1/cinelerra/playback3d.C b/cinelerra-5.1/cinelerra/playback3d.C index f733105f..a6a721ba 100644 --- a/cinelerra-5.1/cinelerra/playback3d.C +++ b/cinelerra-5.1/cinelerra/playback3d.C @@ -149,9 +149,8 @@ static const char *blend_normal_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = canvas * (1.0 - gl_FragColor.a) + gl_FragColor * gl_FragColor.a;\n" + " vec4 result = mix(canvas, gl_FragColor, gl_FragColor.a);\n" " gl_FragColor = mix(canvas, result, alpha);\n" "}\n"; @@ -161,7 +160,6 @@ static const char *blend_add_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" " vec4 result = canvas + gl_FragColor;\n" " result = clamp(result, 0.0, 1.0);\n" @@ -174,7 +172,6 @@ static const char *blend_subtract_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" " vec4 result = gl_FragColor - canvas;\n" " result = clamp(result, 0.0, 1.0);\n" @@ -187,7 +184,6 @@ static const char *blend_multiply_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" " vec4 result = canvas * gl_FragColor;\n" " gl_FragColor = mix(canvas, result, alpha);\n" @@ -199,7 +195,6 @@ static const char *blend_divide_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\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" @@ -214,7 +209,6 @@ static const char *blend_divide_frag = static const char *blend_replace_frag = "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" "}\n"; // MAX @@ -223,7 +217,6 @@ static const char *blend_max_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\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" @@ -236,7 +229,6 @@ static const char *blend_min_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\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" @@ -249,7 +241,6 @@ static const char *blend_average_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\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" @@ -262,7 +253,6 @@ static const char *blend_darken_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" " vec4 result = vec4(canvas.rgb * (1.0 - gl_FragColor.a) +" " gl_FragColor.rgb * (1.0 - canvas.a) +" @@ -278,7 +268,6 @@ static const char *blend_lighten_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" " vec4 result = vec4(canvas.rgb * (1.0 - gl_FragColor.a) +" " gl_FragColor.rgb * (1.0 - canvas.a) +" @@ -294,7 +283,6 @@ static const char *blend_dst_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" -// " gl_FragColor.a *= alpha;\n" // " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" // " vec4 result = canvas;\n" // " gl_FragColor = mix(result, canvas, alpha);\n" @@ -307,7 +295,6 @@ static const char *blend_dst_atop_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" " vec4 result = vec4(canvas.rgb * gl_FragColor.a + " "(1.0 - canvas.a) * gl_FragColor.rgb, gl_FragColor.a);\n" @@ -320,7 +307,6 @@ static const char *blend_dst_in_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" " vec4 result = canvas * gl_FragColor.a;\n" " gl_FragColor = mix(canvas, result, alpha);\n" @@ -332,7 +318,6 @@ static const char *blend_dst_out_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" " vec4 result = canvas * (1.0 - gl_FragColor.a);\n" " gl_FragColor = mix(canvas, result, alpha);\n" @@ -344,7 +329,6 @@ static const char *blend_dst_over_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" " vec4 result = vec4(canvas.rgb + (1.0 - canvas.a) * gl_FragColor.rgb, " " gl_FragColor.a + canvas.a - gl_FragColor.a * canvas.a);\n" @@ -357,7 +341,6 @@ static const char *blend_src_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" " vec4 result = gl_FragColor;\n" " gl_FragColor = mix(canvas, result, alpha);\n" @@ -369,7 +352,6 @@ static const char *blend_src_atop_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" " vec4 result = vec4(gl_FragColor.rgb * canvas.a + " "canvas.rgb * (1.0 - gl_FragColor.a), canvas.a);\n" @@ -382,7 +364,6 @@ static const char *blend_src_in_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" " vec4 result = gl_FragColor * canvas.a;\n" " gl_FragColor = mix(canvas, result, alpha);\n" @@ -394,7 +375,6 @@ static const char *blend_src_out_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" " vec4 result = gl_FragColor * (1.0 - canvas.a);\n" " gl_FragColor = mix(canvas, result, alpha);\n" @@ -406,7 +386,6 @@ static const char *blend_src_over_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" " vec4 result = vec4(gl_FragColor.rgb + (1.0 - gl_FragColor.a) * canvas.rgb, " "gl_FragColor.a + canvas.a - gl_FragColor.a * canvas.a);\n" @@ -419,7 +398,6 @@ static const char *blend_or_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\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" @@ -432,7 +410,6 @@ static const char *blend_xor_frag = "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" " vec4 result = vec4(gl_FragColor.rgb * (1.0 - canvas.a) + " "(1.0 - gl_FragColor.a) * canvas.rgb, " diff --git a/cinelerra-5.1/cinelerra/preferencesthread.C b/cinelerra-5.1/cinelerra/preferencesthread.C index b27342e0..2ee2e2cb 100644 --- a/cinelerra-5.1/cinelerra/preferencesthread.C +++ b/cinelerra-5.1/cinelerra/preferencesthread.C @@ -66,7 +66,7 @@ PreferencesMenuitem::PreferencesMenuitem(MWindow *mwindow) - : BC_MenuItem(_("Preferences..."), _("Shift+P"), 'P') + : BC_MenuItem(_("Preferences..."), _("Shift-P"), 'P') { this->mwindow = mwindow; diff --git a/cinelerra-5.1/cinelerra/render.C b/cinelerra-5.1/cinelerra/render.C index a1160a64..0098afff 100644 --- a/cinelerra-5.1/cinelerra/render.C +++ b/cinelerra-5.1/cinelerra/render.C @@ -82,7 +82,7 @@ RenderItem::RenderItem(MWindow *mwindow) - : BC_MenuItem(_("Render..."), _("Shift+R"), 'R') + : BC_MenuItem(_("Render..."), _("Shift-R"), 'R') { this->mwindow = mwindow; set_shift(1); diff --git a/cinelerra-5.1/cinelerra/swindow.C b/cinelerra-5.1/cinelerra/swindow.C index 0c818825..65799c4b 100644 --- a/cinelerra-5.1/cinelerra/swindow.C +++ b/cinelerra-5.1/cinelerra/swindow.C @@ -951,7 +951,7 @@ int SWindow::update_selection() SubttlSWin::SubttlSWin(MWindow *mwindow) - : BC_MenuItem(_("SubTitle"), _("Alt-y"), 'y') + : BC_MenuItem(_("SubTitle..."), _("Alt-y"), 'y') { set_alt(); this->mwindow = mwindow; diff --git a/cinelerra-5.1/cinelerra/virtualvnode.C b/cinelerra-5.1/cinelerra/virtualvnode.C index 141a2a0c..1fb48461 100644 --- a/cinelerra-5.1/cinelerra/virtualvnode.C +++ b/cinelerra-5.1/cinelerra/virtualvnode.C @@ -414,7 +414,7 @@ int VirtualVNode::render_projector(VFrame *input, VFrame *output, // can do dissolves, although a blend equation is still required for 3 component // colormodels since fractional translation requires blending. -// If this is the first playable video track and the mode_keyframe is "src_over" +// If this is the first playable video track and the mode_keyframe is "src" if(mode == TRANSFER_NORMAL && vconsole->current_exit_node == vconsole->total_exit_nodes - 1) mode = TRANSFER_SRC; diff --git a/cinelerra-5.1/cinelerra/vrender.C b/cinelerra-5.1/cinelerra/vrender.C index 4c301162..0b424c64 100644 --- a/cinelerra-5.1/cinelerra/vrender.C +++ b/cinelerra-5.1/cinelerra/vrender.C @@ -29,7 +29,6 @@ #include "edl.h" #include "edlsession.h" #include "file.h" -#include "interlacemodes.h" #include "localsession.h" #include "mainsession.h" #include "mwindow.h" @@ -144,28 +143,13 @@ int VRender::process_buffer(int64_t input_position, use_vconsole = get_use_vconsole(&playable_edit, input_position, use_brender); if(debug) printf("VRender::process_buffer %d use_vconsole=%d\n", __LINE__, use_vconsole); - if( playable_edit ) { -// Asset and output device must have same resulting de-interlacing method - Indexable *source = playable_edit->get_source(); - if( source->is_asset ) { - Asset *asset = (Asset *)source; - if( ilaceautofixmethod2(renderengine->edl->session->interlace_mode, - asset->interlace_autofixoption, asset->interlace_mode, - asset->interlace_fixmethod) != BC_ILACE_FIXMETHOD_NONE ) - return 1; - } - } - // Negotiate color model colormodel = get_colormodel(playable_edit, use_vconsole, use_brender); if(debug) printf("VRender::process_buffer %d\n", __LINE__); - - // Get output buffer from device - if(renderengine->command->realtime && - !renderengine->is_nested) + if(renderengine->command->realtime && !renderengine->is_nested) { renderengine->video->new_output_buffer(&video_out, colormodel); } @@ -260,8 +244,7 @@ int VRender::get_use_vconsole(VEdit **playable_edit, // Descend into EDL nest return renderengine->get_edl()->get_use_vconsole(playable_edit, - position, - renderengine->command->get_direction(), + position, renderengine->command->get_direction(), vconsole->playable_tracks); } diff --git a/cinelerra-5.1/msg.txt b/cinelerra-5.1/msg.txt index f1a0ab3e..ca4de10a 100644 --- a/cinelerra-5.1/msg.txt +++ b/cinelerra-5.1/msg.txt @@ -4,3 +4,4 @@ Testers are welcome to report and supply examples; join at cinelerra-cv.org If logged in as root, can capture crashes and email /tmp/cin*.dmp file Volunteer to help with language translations which will help you Helpful videos: http://beccatoria.dreamwidth.org/144288.html#cutid2 +Also see: http://g-raffa.eu/Cinelerra/HOWTO/basics.html diff --git a/cinelerra-5.1/plugins/dissolve/dissolve.C b/cinelerra-5.1/plugins/dissolve/dissolve.C index d264f6cf..c0dbb750 100644 --- a/cinelerra-5.1/plugins/dissolve/dissolve.C +++ b/cinelerra-5.1/plugins/dissolve/dissolve.C @@ -69,78 +69,10 @@ int DissolveMain::process_realtime(VFrame *incoming, VFrame *outgoing) // Use software if(!overlayer) overlayer = new OverlayFrame(get_project_smp() + 1); - -// There is a problem when dissolving from a big picture to a small picture. -// In order to make it dissolve correctly, we have to manually decrese alpha of big picture. - switch (outgoing->get_color_model()) - { - case BC_RGBA8888: - case BC_YUVA8888: - { - uint8_t** data_rows = (uint8_t **)outgoing->get_rows(); - int w = outgoing->get_w(); - int h = outgoing->get_h(); - for(int i = 0; i < h; i++) - { - uint8_t* alpha_chan = data_rows[i] + 3; - for(int j = 0; j < w; j++) - { - *alpha_chan = (uint8_t) (*alpha_chan * (1-fade)); - alpha_chan+=4; - } - } - break; - } - case BC_YUVA16161616: - { - uint16_t** data_rows = (uint16_t **)outgoing->get_rows(); - int w = outgoing->get_w(); - int h = outgoing->get_h(); - for(int i = 0; i < h; i++) - { - uint16_t* alpha_chan = data_rows[i] + 3; // 3 since this is uint16_t - for(int j = 0; j < w; j++) - { - *alpha_chan = (uint16_t)(*alpha_chan * (1-fade)); - alpha_chan += 8; - } - } - break; - } - case BC_RGBA_FLOAT: - { - float** data_rows = (float **)outgoing->get_rows(); - int w = outgoing->get_w(); - int h = outgoing->get_h(); - for(int i = 0; i < h; i++) - { - float* alpha_chan = data_rows[i] + 3; // 3 since this is floats - for(int j = 0; j < w; j++) - { - *alpha_chan = *alpha_chan * (1-fade); - alpha_chan += sizeof(float); - } - } - break; - } - default: - break; - } - - - overlayer->overlay(outgoing, - incoming, - 0, - 0, - incoming->get_w(), - incoming->get_h(), - 0, - 0, - incoming->get_w(), - incoming->get_h(), - fade, - TRANSFER_NORMAL, - NEAREST_NEIGHBOR); + overlayer->overlay(outgoing, incoming, + 0, 0, incoming->get_w(), incoming->get_h(), + 0, 0, incoming->get_w(), incoming->get_h(), + fade, TRANSFER_SRC, NEAREST_NEIGHBOR); return 0; } @@ -148,35 +80,64 @@ int DissolveMain::process_realtime(VFrame *incoming, VFrame *outgoing) int DissolveMain::handle_opengl() { #ifdef HAVE_GL + static const char *blend_dissolve = + "uniform float fade;\n" + "uniform sampler2D src_tex;\n" + "uniform sampler2D dst_tex;\n" + "uniform vec2 dst_tex_dimensions;\n" + "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" + " result_color = mix(dst_color, src_color, fade);\n" + " result_color.rgb += chroma_offset;\n" + " gl_FragColor = result_color;\n" + "}\n"; // Read images from RAM - get_input()->to_texture(); - get_output()->to_texture(); + VFrame *src = get_input(); + src->to_texture(); + VFrame *dst = get_output(); + dst->to_texture(); + dst->enable_opengl(); + dst->init_screen(); + src->bind_texture(0); + dst->bind_texture(1); + + const char *shader_stack[] = { 0, 0, 0 }; + int current_shader = 0; + shader_stack[current_shader++] = blend_dissolve; + + unsigned int shader_id = VFrame::make_shader(0, + shader_stack[0], shader_stack[1], shader_stack[2], 0); + + glUseProgram(shader_id); + glUniform1f(glGetUniformLocation(shader_id, "fade"), fade); + 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()); -// Create output pbuffer - get_output()->enable_opengl(); - - VFrame::init_screen(get_output()->get_w(), get_output()->get_h()); - -// Enable output texture - get_output()->bind_texture(0); -// Draw output texture glDisable(GL_BLEND); - glColor4f(1, 1, 1, 1); - get_output()->draw_texture(); - -// Draw input texture - get_input()->bind_texture(0); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(1, 1, 1, fade); - get_input()->draw_texture(); - + src->draw_texture(); + glUseProgram(0); glDisable(GL_BLEND); - get_output()->set_opengl_state(VFrame::SCREEN); - + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + glDisable(GL_TEXTURE_2D); + dst->set_opengl_state(VFrame::SCREEN); #endif return 0; } -- 2.26.2