int ChromaKeyHSV::handle_opengl() { #ifdef HAVE_GL // For macro ChromaKeyHSV *plugin = this; OUTER_VARIABLES static const char *yuv_shader = "const vec3 black = vec3(0.0, 0.5, 0.5);\n" "\n" "vec4 yuv_to_rgb(vec4 color)\n" "{\n" YUV_TO_RGB_FRAG("color") " return color;\n" "}\n" "\n" "vec4 rgb_to_yuv(vec4 color)\n" "{\n" RGB_TO_YUV_FRAG("color") " return color;\n" "}\n"; static const char *rgb_shader = "const vec3 black = vec3(0.0, 0.0, 0.0);\n" "\n" "vec4 yuv_to_rgb(vec4 color)\n" "{\n" " return color;\n" "}\n" "vec4 rgb_to_yuv(vec4 color)\n" "{\n" " return color;\n" "}\n"; static const char *hsv_shader = "vec4 rgb_to_hsv(vec4 color)\n" "{\n" RGB_TO_HSV_FRAG("color") " return color;\n" "}\n" "\n" "vec4 hsv_to_rgb(vec4 color)\n" "{\n" HSV_TO_RGB_FRAG("color") " return color;\n" "}\n" "\n"; static const char *show_rgbmask_shader = "vec4 show_mask(vec4 color, vec4 color2)\n" "{\n" " return vec4(1.0, 1.0, 1.0, min(color.a, color2.a));" "}\n"; static const char *show_yuvmask_shader = "vec4 show_mask(vec4 color, vec4 color2)\n" "{\n" " return vec4(1.0, 0.5, 0.5, min(color.a, color2.a));" "}\n"; static const char *nomask_shader = "vec4 show_mask(vec4 color, vec4 color2)\n" "{\n" " return vec4(color.rgb, min(color.a, color2.a));" "}\n"; extern unsigned char _binary_chromakey_sl_start[]; static const char *shader = (char*)_binary_chromakey_sl_start; get_output()->to_texture(); get_output()->enable_opengl(); get_output()->init_screen(); const char* shader_stack[] = { 0, 0, 0, 0, 0 }; switch(get_output()->get_color_model()) { case BC_YUV888: case BC_YUVA8888: shader_stack[0] = yuv_shader; shader_stack[1] = hsv_shader; if(config.show_mask) shader_stack[2] = show_yuvmask_shader; else shader_stack[2] = nomask_shader; shader_stack[3] = shader; break; default: shader_stack[0] = rgb_shader; shader_stack[1] = hsv_shader; if(config.show_mask) shader_stack[2] = show_rgbmask_shader; else shader_stack[2] = nomask_shader; shader_stack[3] = shader; break; } unsigned int frag = VFrame::make_shader(0, shader_stack[0], shader_stack[1], shader_stack[2], shader_stack[3], 0); if(frag) { glUseProgram(frag); glUniform1i(glGetUniformLocation(frag, "tex"), 0); glUniform1f(glGetUniformLocation(frag, "red"), red); glUniform1f(glGetUniformLocation(frag, "green"), green); glUniform1f(glGetUniformLocation(frag, "blue"), blue); glUniform1f(glGetUniformLocation(frag, "in_slope"), in_slope); glUniform1f(glGetUniformLocation(frag, "out_slope"), out_slope); glUniform1f(glGetUniformLocation(frag, "tolerance"), tolerance); glUniform1f(glGetUniformLocation(frag, "tolerance_in"), tolerance_in); glUniform1f(glGetUniformLocation(frag, "tolerance_out"), tolerance_out); glUniform1f(glGetUniformLocation(frag, "sat"), sat); glUniform1f(glGetUniformLocation(frag, "min_s"), min_s); glUniform1f(glGetUniformLocation(frag, "min_s_in"), min_s_in); glUniform1f(glGetUniformLocation(frag, "min_s_out"), min_s_out); glUniform1f(glGetUniformLocation(frag, "min_v"), min_v); glUniform1f(glGetUniformLocation(frag, "min_v_in"), min_v_in); glUniform1f(glGetUniformLocation(frag, "min_v_out"), min_v_out); glUniform1f(glGetUniformLocation(frag, "max_v"), max_v); glUniform1f(glGetUniformLocation(frag, "max_v_in"), max_v_in); glUniform1f(glGetUniformLocation(frag, "max_v_out"), max_v_out); glUniform1f(glGetUniformLocation(frag, "spill_threshold"), spill_threshold); glUniform1f(glGetUniformLocation(frag, "spill_amount"), spill_amount); glUniform1f(glGetUniformLocation(frag, "alpha_offset"), alpha_offset); glUniform1f(glGetUniformLocation(frag, "hue_key"), hue_key); glUniform1f(glGetUniformLocation(frag, "saturation_key"), saturation_key); glUniform1f(glGetUniformLocation(frag, "value_key"), value_key); } get_output()->bind_texture(0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); if(BC_CModels::components(get_output()->get_color_model()) == 3) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); get_output()->clear_pbuffer(); } get_output()->draw_texture(); glUseProgram(0); get_output()->set_opengl_state(VFrame::SCREEN); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glDisable(GL_BLEND); #endif return 0; }
int HueEffect::handle_opengl() { #ifdef HAVE_GL const char *yuv_saturation_frag = "uniform sampler2D tex;\n" "uniform float s_offset;\n" "uniform float v_offset;\n" "void main()\n" "{\n" " vec4 pixel = texture2D(tex, gl_TexCoord[0].st);\n" " pixel.r *= v_offset;\n" " pixel.gb -= vec2(0.5, 0.5);\n" " pixel.g *= s_offset;\n" " pixel.b *= s_offset;\n" " pixel.gb += vec2(0.5, 0.5);\n" " gl_FragColor = pixel;\n" "}\n"; const char *yuv_frag = "uniform sampler2D tex;\n" "uniform float h_offset;\n" "uniform float s_offset;\n" "uniform float v_offset;\n" "void main()\n" "{\n" " vec4 pixel = texture2D(tex, gl_TexCoord[0].st);\n" YUV_TO_RGB_FRAG("pixel") RGB_TO_HSV_FRAG("pixel") " pixel.r += h_offset;\n" " pixel.g *= s_offset;\n" " pixel.b *= v_offset;\n" " if(pixel.r >= 360.0) pixel.r -= 360.0;\n" " if(pixel.r < 0.0) pixel.r += 360.0;\n" HSV_TO_RGB_FRAG("pixel") RGB_TO_YUV_FRAG("pixel") " gl_FragColor = pixel;\n" "}\n"; const char *rgb_frag = "uniform sampler2D tex;\n" "uniform float h_offset;\n" "uniform float s_offset;\n" "uniform float v_offset;\n" "void main()\n" "{\n" " vec4 pixel = texture2D(tex, gl_TexCoord[0].st);\n" RGB_TO_HSV_FRAG("pixel") " pixel.r += h_offset;\n" " pixel.g *= s_offset;\n" " pixel.b *= v_offset;\n" " if(pixel.r >= 360.0) pixel.r -= 360.0;\n" " if(pixel.r < 0.0) pixel.r += 360.0;\n" HSV_TO_RGB_FRAG("pixel") " gl_FragColor = pixel;\n" "}\n"; get_output()->to_texture(); get_output()->enable_opengl(); unsigned int frag_shader = 0; switch(get_output()->get_color_model()) { case BC_YUV888: case BC_YUVA8888: // This is a lousy approximation but good enough for the masker. if(EQUIV(config.hue, 0)) frag_shader = VFrame::make_shader(0, yuv_saturation_frag, 0); else frag_shader = VFrame::make_shader(0, yuv_frag, 0); break; default: frag_shader = VFrame::make_shader(0, rgb_frag, 0); break; } if(frag_shader > 0) { glUseProgram(frag_shader); glUniform1i(glGetUniformLocation(frag_shader, "tex"), 0); glUniform1f(glGetUniformLocation(frag_shader, "h_offset"), config.hue); glUniform1f(glGetUniformLocation(frag_shader, "s_offset"), ((float)config.saturation - MINSATURATION) / MAXSATURATION); glUniform1f(glGetUniformLocation(frag_shader, "v_offset"), ((float)config.value - MINVALUE) / MAXVALUE); } get_output()->init_screen(); get_output()->bind_texture(0); get_output()->draw_texture(); glUseProgram(0); get_output()->set_opengl_state(VFrame::SCREEN); #endif return 0; }