"} " \r
" ";\r
\r
+ shaders_[core::pixel_format::gray] = shader_program(common_vertex, common_fragment +\r
+\r
+ "void main() "\r
+ "{ "\r
+ " vec4 rgba = vec4(texture2D(plane[0], gl_TexCoord[0].st).rrr, 1.0); "\r
+ " if(has_separate_key) "\r
+ " rgba.a = texture2D(plane[3], gl_TexCoord[0].st).r; "\r
+ " gl_FragColor = rgba * gain; "\r
+ "} ");\r
+\r
shaders_[core::pixel_format::abgr] = shader_program(common_vertex, common_fragment +\r
\r
"void main() "\r
"{ "\r
" vec4 abgr = texture2D(plane[0], gl_TexCoord[0].st); "\r
+ " if(has_separate_key) "\r
+ " abgr.b = texture2D(plane[3], gl_TexCoord[0].st).r; "\r
" gl_FragColor = abgr.argb * gain; "\r
"} ");\r
\r
"void main() " \r
"{ "\r
" vec4 argb = texture2D(plane[0], gl_TexCoord[0].st); "\r
+ " if(has_separate_key) "\r
+ " argb.b = texture2D(plane[3], gl_TexCoord[0].st).r; "\r
" gl_FragColor = argb.grab * gl_Color * gain; "\r
"} ");\r
\r
"void main() "\r
"{ "\r
" vec4 bgra = texture2D(plane[0], gl_TexCoord[0].st); "\r
+ " if(has_separate_key) "\r
+ " bgra.a = texture2D(plane[3], gl_TexCoord[0].st).r; "\r
" gl_FragColor = bgra.rgba * gl_Color * gain; "\r
"} ");\r
\r
"void main() "\r
"{ "\r
" vec4 rgba = texture2D(plane[0], gl_TexCoord[0].st); "\r
+ " if(has_separate_key) "\r
+ " rgba.a = texture2D(plane[3], gl_TexCoord[0].st).r; "\r
" gl_FragColor = rgba.bgra * gl_Color * gain; "\r
"} ");\r
\r
" float cr = texture2D(plane[2], gl_TexCoord[0].st).r; "\r
" float a = 1.0; " \r
" if(has_separate_key) "\r
- " a = texture2D(plane[3], gl_TexCoord[0].st).r+0.2; "\r
+ " a = texture2D(plane[3], gl_TexCoord[0].st).r; "\r
" if(HD) "\r
" gl_FragColor = ycbcra_to_bgra_hd(y, cb, cr, a) * gl_Color * gain;"\r
" else "\r
auto gpu_frame = boost::polymorphic_downcast<gpu_write_frame*>(&frame);\r
auto desc = gpu_frame->get_pixel_format_desc();\r
auto buffers = gpu_frame->get_plane_buffers();\r
- auto is_key_frame = gpu_frame->get_image_transform().get_is_key();\r
\r
auto transform = transform_stack_.top();\r
context_->begin_invoke([=]\r
device_buffers.push_back(texture);\r
}\r
\r
- if(is_key_frame) // Its a key_frame just bind the texture for use during the next frame.\r
+ if(transform.get_is_key()) // Its a key_frame just save buffer for next frame.\r
{\r
if(!device_buffers.empty()) \r
key_ = device_buffers[0]; \r
glTexCoord2d(1.0, 1.0); glVertex2d((f_p[0]+f_s[0])*2.0-1.0, (f_p[1]+f_s[1])*2.0-1.0);\r
glTexCoord2d(0.0, 1.0); glVertex2d( f_p[0] *2.0-1.0, (f_p[1]+f_s[1])*2.0-1.0);\r
glEnd();\r
- GL(glDisable(GL_SCISSOR_TEST));\r
- \r
- key_ = nullptr;\r
+ GL(glDisable(GL_SCISSOR_TEST)); \r
+\r
+ key_ = nullptr; \r
}\r
});\r
}\r
if(other.mode_ != video_mode::invalid)\r
mode_ = other.mode_;\r
gain_ *= other.gain_;\r
- is_key_ = other.is_key_;\r
+ is_key_ |= other.is_key_;\r
fill_translation_[0] += other.fill_translation_[0]*fill_scale_[0];\r
fill_translation_[1] += other.fill_translation_[1]*fill_scale_[1];\r
fill_scale_[0] *= other.fill_scale_[0];\r
\r
image_transform result; \r
result.set_mode(dest.get_mode() != video_mode::invalid ? dest.get_mode() : source.get_mode());\r
- result.set_is_key(dest.get_is_key());\r
+ result.set_is_key(source.get_is_key() | dest.get_is_key());\r
result.set_gain(do_tween(time, source.get_gain(), dest.get_gain(), duration, tweener));\r
result.set_opacity(do_tween(time, source.get_opacity(), dest.get_opacity(), duration, tweener));\r
result.set_fill_translation(do_tween(time, source.get_fill_translation()[0], dest.get_fill_translation()[0], duration, tweener), do_tween(time, source.get_fill_translation()[1], dest.get_fill_translation()[1], duration, tweener));\r
{\r
enum type\r
{\r
+ gray,\r
bgra,\r
rgba,\r
argb,\r
{\r
switch(pix_fmt)\r
{\r
- case PIX_FMT_BGRA: return core::pixel_format::bgra;\r
- case PIX_FMT_ARGB: return core::pixel_format::argb;\r
- case PIX_FMT_RGBA: return core::pixel_format::rgba;\r
- case PIX_FMT_ABGR: return core::pixel_format::abgr;\r
- case PIX_FMT_YUV444P: return core::pixel_format::ycbcr;\r
- case PIX_FMT_YUV422P: return core::pixel_format::ycbcr;\r
- case PIX_FMT_YUV420P: return core::pixel_format::ycbcr;\r
- case PIX_FMT_YUV411P: return core::pixel_format::ycbcr;\r
- case PIX_FMT_YUV410P: return core::pixel_format::ycbcr;\r
- case PIX_FMT_YUVA420P: return core::pixel_format::ycbcra;\r
- default: return core::pixel_format::invalid;\r
+ case PIX_FMT_GRAY8: return core::pixel_format::gray;\r
+ case PIX_FMT_BGRA: return core::pixel_format::bgra;\r
+ case PIX_FMT_ARGB: return core::pixel_format::argb;\r
+ case PIX_FMT_RGBA: return core::pixel_format::rgba;\r
+ case PIX_FMT_ABGR: return core::pixel_format::abgr;\r
+ case PIX_FMT_YUV444P: return core::pixel_format::ycbcr;\r
+ case PIX_FMT_YUV422P: return core::pixel_format::ycbcr;\r
+ case PIX_FMT_YUV420P: return core::pixel_format::ycbcr;\r
+ case PIX_FMT_YUV411P: return core::pixel_format::ycbcr;\r
+ case PIX_FMT_YUV410P: return core::pixel_format::ycbcr;\r
+ case PIX_FMT_YUVA420P: return core::pixel_format::ycbcra;\r
+ default: return core::pixel_format::invalid;\r
}\r
}\r
\r
\r
switch(desc.pix_fmt)\r
{\r
+ case core::pixel_format::gray:\r
+ {\r
+ desc.planes.push_back(core::pixel_format_desc::plane(dummy_pict.linesize[0]/4, height, 1)); \r
+ return desc;\r
+ }\r
case core::pixel_format::bgra:\r
case core::pixel_format::argb:\r
case core::pixel_format::rgba:\r
{ \r
if(_parameters[0] == L"VIDEO")\r
{\r
- if(_parameters[1] == L"OPACITY")\r
+ if(_parameters[1] == L"IS_KEY")\r
+ {\r
+ bool value = lexical_cast_or_default(_parameters.at(2), false);\r
+ auto transform = [=](image_transform transform) -> image_transform\r
+ {\r
+ transform.set_is_key(value);\r
+ return transform; \r
+ };\r
+\r
+ int layer = GetLayerIndex(std::numeric_limits<int>::min());\r
+ if(layer != std::numeric_limits<int>::min()) \r
+ GetChannel()->mixer()->apply_image_transform(GetLayerIndex(), transform, 0);\r
+ else\r
+ GetChannel()->mixer()->apply_image_transform(transform, 0);\r
+ }\r
+ else if(_parameters[1] == L"OPACITY")\r
{\r
int duration = _parameters.size() > 2 ? lexical_cast_or_default(_parameters[3], 0) : 0;\r
std::wstring tween = _parameters.size() > 3 ? _parameters[4] : L"linear";\r