X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fplayback3d.C;h=503e57185b1c01d14462e25a02ea50f93c7933f4;hp=aefafc8e3f9c7c61fb5cbe71cc56494fc16a75e0;hb=8e67d840c5a93f77de021102a4f0bfc4e07504f4;hpb=7ead9f7382846e81c2f8efb25780014e5f8834c3 diff --git a/cinelerra-5.1/cinelerra/playback3d.C b/cinelerra-5.1/cinelerra/playback3d.C index aefafc8e..503e5718 100644 --- a/cinelerra-5.1/cinelerra/playback3d.C +++ b/cinelerra-5.1/cinelerra/playback3d.C @@ -38,6 +38,7 @@ #include "pluginclient.h" #include "pluginvclient.h" #include "edlsession.h" +#include "track.h" #include "transportque.inc" #include "vframe.h" @@ -270,39 +271,81 @@ static const char *feather_frag = "#version 430\n" "layout(location=0) out vec4 color;\n" "uniform sampler2D tex;\n" -// apparently, only doubles index properly in shared buffers - "buffer buf { dvec2 points[]; };\n" + "const int MAX = 1024;\n" + "uniform float psf[MAX];\n" + "uniform int n;\n" + "uniform vec2 dxy;\n" + "uniform vec2 twh;\n" + "\n" + "void main() {\n" + " vec2 tc = gl_FragCoord.xy/textureSize(tex,0);\n" + " color = texture(tex, tc);\n" + " float c = color.r, f = c*psf[0];\n" + " for( int i=1; i0. ? 1 : -1;\n" - " float rr = r*r, dr = 1./rr;\n" - " float vv = v>=0 ? 1.-v : 1.+v;\n" - " float fg = rv>=0 ? vv : 1.;\n" - " float bg = rv>=0 ? 1. : vv;\n" - " int len = points.length();\n" - " for( int i=0; i= rr ) continue;\n" - " float d = dd*dr;\n" - " float a = (1.-d)*fg + d*bg;\n" - " if( rv*(color.a-a) > 0 ) color = vec4(a);\n" - " }\n" + " vec2 tc = gl_FragCoord.xy/textureSize(tex,0);\n" + " color = texture2D(tex1, tc);\n" + " float c = texture2D(tex, tc).r;\n" + " float b = r<0 ? 1. : 0.;\n" + " if( c == b ) return;\n" + " float iv = v>=0. ? 1. : -1.;\n" + " float rr = r!=0. ? r : 1.;\n" + " float rv = rr*v>=0. ? 1. : -1.;\n" + " float vv = v>=0. ? 1.-v : 1.+v;\n" + " float fg = rv>0. ? vv : 1.;\n" + " float bg = rv>0. ? 1. : vv;\n" + " float a = c*fg + (1.-c)*bg;\n" + " if( iv*(color.a-a) > 0. ) color = vec4(a);\n" "}\n"; -static const char *alpha_frag = +static const char *multiply_mask4_frag = "uniform sampler2D tex;\n" - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "void main() {\n" \ + "uniform sampler2D tex1;\n" + "void main()\n" + "{\n" " gl_FragColor = texture2D(tex, gl_TexCoord[0].st);\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " gl_FragColor.a = canvas.a;\n" + " gl_FragColor.a *= texture2D(tex1, gl_TexCoord[0].st).r;\n" + "}\n"; + +static const char *multiply_mask3_frag = + "uniform sampler2D tex;\n" + "uniform sampler2D tex1;\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(tex, gl_TexCoord[0].st);\n" + " float a = texture2D(tex1, gl_TexCoord[0].st).r;\n" + " gl_FragColor.rgb *= vec3(a, a, a);\n" + "}\n"; + +static const char *multiply_yuvmask3_frag = + "uniform sampler2D tex;\n" + "uniform sampler2D tex1;\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(tex, gl_TexCoord[0].st);\n" + " float a = texture2D(tex1, gl_TexCoord[0].st).r;\n" + " gl_FragColor.gb -= vec2(0.5, 0.5);\n" + " gl_FragColor.rgb *= vec3(a, a, a);\n" + " gl_FragColor.gb += vec2(0.5, 0.5);\n" "}\n"; static const char *fade_rgba_frag = @@ -368,32 +411,11 @@ void Playback3DCommand::copy_from(BC_SynchronousCommand *command) BC_SynchronousCommand::copy_from(command); } -//#define GL_BUG 1 -#ifdef GL_BUG -static void GLAPIENTRY glDebugCallback(GLenum source, GLenum type, - GLuint id, GLenum severity, GLsizei length, const GLchar* message, - const void* userParam) -{ - fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n", - ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ), - type, severity, message ); -} -#endif - Playback3D::Playback3D(MWindow *mwindow) : BC_Synchronous() { this->mwindow = mwindow; temp_texture = 0; -#ifdef GL_BUG - //Enabling OpenGL debug output - // this does not work - glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE); - glEnable(GL_DEBUG_OUTPUT); - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); - glDebugMessageCallback(glDebugCallback, 0); - glEnable(GL_DEBUG_OUTPUT); -#endif } Playback3D::~Playback3D() @@ -419,10 +441,6 @@ void Playback3D::handle_command(BC_SynchronousCommand *command) write_buffer_sync((Playback3DCommand*)command); break; - case Playback3DCommand::FINISH_OUTPUT: - finish_output_sync((Playback3DCommand*)command); - break; - case Playback3DCommand::CLEAR_OUTPUT: clear_output_sync((Playback3DCommand*)command); break; @@ -490,6 +508,7 @@ void Playback3D::copy_from_sync(Playback3DCommand *command) command->canvas->lock_canvas("Playback3D::copy_from_sync"); if( window ) { window->enable_opengl(); + glFinish(); int w = command->input->get_w(); int h = command->input->get_h(); @@ -658,35 +677,21 @@ void Playback3D::write_buffer_sync(Playback3DCommand *command) BC_WindowBase *window = command->canvas->lock_canvas("Playback3D::write_buffer_sync"); if( window ) { + window->enable_opengl(); // Update hidden cursor window->update_video_cursor(); -// Make sure OpenGL is enabled first. - window->enable_opengl(); - + command->frame->enable_opengl(); + command->frame->init_screen(); //printf("Playback3D::write_buffer_sync 1 %d\n", window->get_id()); - int flip_y = 0, frame_state = command->frame->get_opengl_state(); - switch( frame_state ) { -// Upload texture and composite to screen - case VFrame::RAM: - flip_y = 1; - case VFrame::SCREEN: - command->frame->to_texture(); - window->enable_opengl(); -// Composite texture to screen and swap buffer - case VFrame::TEXTURE: - if( !flip_y ) { - int fh1 = command->frame->get_h()-1; - float in_y1 = fh1 - command->in_y1; - float in_y2 = fh1 - command->in_y2; - command->in_y1 = in_y2; - command->in_y2 = in_y1; - } - draw_output(command, flip_y); - break; - default: - printf("Playback3D::write_buffer_sync unknown state\n"); - break; + int frame_state = command->frame->get_opengl_state(); + if( frame_state != VFrame::TEXTURE ) + command->frame->to_texture(); + if( frame_state != VFrame::RAM ) { + command->in_y1 = command->frame->get_h() - command->in_y1; + command->in_y2 = command->frame->get_h() - command->in_y2; } + window->enable_opengl(); + draw_output(command, 1); command->frame->set_opengl_state(frame_state); } command->canvas->unlock_canvas(); @@ -721,7 +726,7 @@ void Playback3D::draw_output(Playback3DCommand *command, int flip_y) if(!command->is_cleared) { // If we get here, the virtual console was not used. - init_frame(command, 0); + color_frame(command, 0,0,0,0); } // Texture @@ -751,14 +756,8 @@ void Playback3D::draw_output(Playback3DCommand *command, int flip_y) //printf("Playback3D::draw_output 2 %f,%f %f,%f -> %f,%f %f,%f\n", -// command->in_x1, -// command->in_y1, -// command->in_x2, -// command->in_y2, -// command->out_x1, -// command->out_y1, -// command->out_x2, -// command->out_y2); +// command->in_x1, command->in_y1, command->in_x2, command->in_y2, +// command->out_x1, command->out_y1, command->out_x2, command->out_y2); glUseProgram(0); @@ -769,38 +768,16 @@ void Playback3D::draw_output(Playback3DCommand *command, int flip_y) } -void Playback3D::init_frame(Playback3DCommand *command, int is_yuv) +void Playback3D::color_frame(Playback3DCommand *command, + float r, float g, float b, float a) { #ifdef HAVE_GL - float gbuv = is_yuv ? 0.5 : 0.0; - glClearColor(0.0, gbuv, gbuv, 0.0); + glClearColor(r, g, b, a); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #endif } -void Playback3D::finish_output(Canvas *canvas) -{ - Playback3DCommand command; - command.canvas = canvas; - command.command = Playback3DCommand::FINISH_OUTPUT; - send_command(&command); -} - -void Playback3D::finish_output_sync(Playback3DCommand *command) -{ -#ifdef HAVE_GL - BC_WindowBase *window = - command->canvas->lock_canvas("Playback3D::finish_output_sync"); - if( window ) { - command->canvas->get_canvas()->enable_opengl(); - glFinish(); - } - command->canvas->unlock_canvas(); -#endif -} - - void Playback3D::clear_output(Canvas *canvas, VFrame *output) { Playback3DCommand command; @@ -819,14 +796,21 @@ void Playback3D::clear_output_sync(Playback3DCommand *command) // If we get here, the virtual console is being used. command->canvas->get_canvas()->enable_opengl(); int is_yuv = 0; + int color = BLACK, alpha = 0; // Using pbuffer for refresh frame. if( command->frame ) { command->frame->enable_opengl(); + color = command->frame->get_clear_color(); + alpha = command->frame->get_clear_alpha(); int color_model = command->canvas->mwindow->edl->session->color_model; is_yuv = BC_CModels::is_yuv(color_model); } - - init_frame(command, is_yuv); + int a = alpha; + int r = (color>>16) & 0xff; + int g = (color>>8) & 0xff; + int b = (color>>0) & 0xff; + if( is_yuv ) YUV::yuv.rgb_to_yuv_8(r, g, b); + color_frame(command, r/255.f, g/255.f, b/255.f, a/255.f); } command->canvas->unlock_canvas(); #endif @@ -1209,6 +1193,7 @@ public: void bind(int texture_unit); void read_screen(int x, int y, int w, int h); void set_output_texture(); + void unset_output_texture(); GLuint fb, rb; }; @@ -1241,6 +1226,7 @@ void fb_texture::bind(int texture_unit) void fb_texture::read_screen(int x, int y, int w, int h) { + bind(1); glBindFramebuffer(GL_FRAMEBUFFER, 0); glReadBuffer(GL_BACK); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0,0, x,y, w,h); @@ -1248,8 +1234,9 @@ void fb_texture::read_screen(int x, int y, int w, int h) void fb_texture::set_output_texture() { - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, get_texture_id(), 0); - GLenum dbo[1] = { GL_COLOR_ATTACHMENT0, }; // bind layout(location=0) out vec4 color; + GLenum at = GL_COLOR_ATTACHMENT0; + glFramebufferTexture(GL_FRAMEBUFFER, at, get_texture_id(), 0); + GLenum dbo[1] = { at, }; // bind layout(location=0) out vec4 color; glDrawBuffers(1, dbo); int ret = glCheckFramebufferStatus(GL_FRAMEBUFFER); if( ret != GL_FRAMEBUFFER_COMPLETE ) { @@ -1257,22 +1244,40 @@ void fb_texture::set_output_texture() return; } } +void fb_texture::unset_output_texture() +{ + glDrawBuffers(0, 0); + int at = GL_COLOR_ATTACHMENT0; + glFramebufferTexture(GL_FRAMEBUFFER, at, 0, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glDisable(GL_TEXTURE_2D); +} + + +class zglTessData : public ArrayList +{ +public: + zglTessData() { set_array_delete(); } + ~zglTessData() { remove_all_objects(); } +}; static void combineData(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **outData, void *data) { - ArrayList *invented = (ArrayList *)data; + zglTessData *invented = (zglTessData *)data; GLdouble *vertex = new double[6]; invented->append(vertex); vertex[0] = coords[0]; vertex[1] = coords[1]; vertex[2] = coords[2]; for( int i=3; i<6; ++i ) { - vertex[i] = weight[0] * vertex_data[0][i] + - weight[1] * vertex_data[1][i] + - weight[2] * vertex_data[2][i] + - weight[3] * vertex_data[3][i]; + GLdouble v = 0; + for( int k=0; k<4; ++k ) { + if( !weight[k] || !vertex_data[k] ) continue; + v += weight[k] * vertex_data[k][i]; + } + vertex[i] = v; } *outData = vertex; } @@ -1280,7 +1285,7 @@ static void combineData(GLdouble coords[3], // dbug static void zglBegin(GLenum mode) { glBegin(mode); } static void zglEnd() { glEnd(); } -static void zglVertex3dv(const GLdouble *v) { glVertex3dv(v); } +static void zglVertex(const GLdouble *v) { glVertex3dv(v); } #endif @@ -1313,212 +1318,163 @@ void Playback3D::do_mask_sync(Playback3DCommand *command) int w = command->frame->get_w(); int h = command->frame->get_h(); MaskEdges edges; - float faders[SUBMASKS], feathers[SUBMASKS], bg = 1; - MaskPointSet point_set[SUBMASKS]; + float faders[SUBMASKS], feathers[SUBMASKS], cc = 1; + MaskPoints point_set[SUBMASKS]; // Draw every submask as a new polygon int total_submasks = command->keyframe_set->total_submasks( command->start_position_project, PLAY_FORWARD); + int show_mask = command->keyframe_set->track->masks; for(int k = 0; k < total_submasks; k++) { - MaskPointSet &points = point_set[k]; + MaskPoints &points = point_set[k]; command->keyframe_set->get_points(&points, k, command->start_position_project, PLAY_FORWARD); float fader = command->keyframe_set->get_fader( command->start_position_project, k, PLAY_FORWARD); float v = fader/100.; faders[k] = v; - if( v < 0 && (v+=1) < bg ) bg = v; float feather = command->keyframe_set->get_feather( command->start_position_project, k, PLAY_FORWARD); feathers[k] = feather; - } -// clear screen - glDisable(GL_TEXTURE_2D); - glClearColor(bg, bg, bg, bg); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - for(int k = 0; k < total_submasks; k++) { - MaskPointSet &points = point_set[k]; MaskEdge &edge = *edges.append(new MaskEdge()); - int first_point = 0; -// Need to tabulate every vertex in persistent memory because -// gluTessVertex doesn't copy them. - for(int i = 0; i < points.total; i++) { - MaskPoint *point1 = points.values[i]; - MaskPoint *point2 = (i >= points.total - 1) ? - points.values[0] : points.values[i + 1]; - - float x, y; - int segments = 0; - if( point1->control_x2 == 0 && point1->control_y2 == 0 && - point2->control_x1 == 0 && point2->control_y1 == 0 ) - segments = 1; - - float x0 = point1->x, y0 = point1->y; - float x1 = point1->x + point1->control_x2; - float y1 = point1->y + point1->control_y2; - float x2 = point2->x + point2->control_x1; - float y2 = point2->y + point2->control_y1; - float x3 = point2->x, y3 = point2->y; - - // forward differencing bezier curves implementation taken from GPL code at - // http://cvs.sourceforge.net/viewcvs.py/guliverkli/guliverkli/src/subtitles/Rasterizer.cpp?rev=1.3 - - float cx3, cx2, cx1, cx0, cy3, cy2, cy1, cy0; - - // [-1 +3 -3 +1] - // [+3 -6 +3 0] - // [-3 +3 0 0] - // [+1 0 0 0] - - cx3 = - x0 + 3*x1 - 3*x2 + x3; - cx2 = 3*x0 - 6*x1 + 3*x2; - cx1 = -3*x0 + 3*x1; - cx0 = x0; - - cy3 = - y0 + 3*y1 - 3*y2 + y3; - cy2 = 3*y0 - 6*y1 + 3*y2; - cy1 = -3*y0 + 3*y1; - cy0 = y0; - - // This equation is from Graphics Gems I. - // - // The idea is that since we're approximating a cubic curve with lines, - // any error we incur is due to the curvature of the line, which we can - // estimate by calculating the maximum acceleration of the curve. For - // a cubic, the acceleration (second derivative) is a line, meaning that - // the absolute maximum acceleration must occur at either the beginning - // (|c2|) or the end (|c2+c3|). Our bounds here are a little more - // conservative than that, but that's okay. - if (segments == 0) { - float maxaccel1 = fabs(2*cy2) + fabs(6*cy3); - float maxaccel2 = fabs(2*cx2) + fabs(6*cx3); - - float maxaccel = maxaccel1 > maxaccel2 ? maxaccel1 : maxaccel2; - float h = 1.0; - - if(maxaccel > 8.0) h = sqrt((8.0) / maxaccel); - segments = int(1/h); - } + if( !v || !((show_mask>>k) & 1) || !points.size() ) continue; + edge.load(point_set[k], h); + if( v >= 0 ) continue; + float vv = 1 + v; + if( cc > vv ) cc = vv; + } - for(int j = 0; j <= segments; j++) { - float t = (float)j / segments; - x = cx0 + t*(cx1 + t*(cx2 + t*cx3)); - y = cy0 + t*(cy1 + t*(cy2 + t*cy3)); + fb_texture *mask = new fb_texture(w, h, color_model); + mask->set_output_texture(); + glClearColor(cc, cc, cc, cc); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + mask->unset_output_texture(); - if(j > 0 || first_point) { - edge.append(x, y - h); - first_point = 0; - } - } - } - if( edge.size() > 0 ) { -// draw polygon - float fader = faders[k]; - float v = fader < 0 ? 1 : 1-fader; - glColor4f(v, v, v, v); + unsigned int feather_shader = + VFrame::make_shader(0, in_vertex_frag, feather_frag, 0); + unsigned int max_shader = + VFrame::make_shader(0, in_vertex_frag, max_frag, 0); + if( feather_shader && max_shader ) { + fb_texture *in = new fb_texture(w, h, color_model); + fb_texture *out = new fb_texture(w, h, color_model); + float tw = 1./out->get_texture_w(), th = 1./out->get_texture_h(); + float tw1 = (w-1)*tw, th1 = (h-1)*th; + for(int k = 0; k < total_submasks; k++) { + MaskEdge &edge = *edges[k]; + if( edge.size() < 3 ) continue; + float r = feathers[k], v = faders[k]; + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glActiveTexture(GL_TEXTURE0); + glDisable(GL_TEXTURE_2D); + float b = r>=0 ? 0. : 1.; + float f = r>=0 ? 1. : 0.; + glClearColor(b, b, b, b); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glColor4f(f, f, f, f); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); int display_list = glGenLists(1); - glNewList(display_list, GL_COMPILE); #if 0 - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glNewList(display_list, GL_COMPILE); glBegin(GL_POLYGON); MaskCoord *c = &edge[0]; for( int i=edge.size(); --i>=0; ++c ) glVertex2f(c->x, c->y); glEnd(); + glEndList(); + glCallList(display_list); #else + { zglTessData invented; GLUtesselator *tess = gluNewTess(); - gluTessCallback(tess, GLU_TESS_VERTEX,(GLvoid (*)()) &zglVertex3dv); + gluTessProperty(tess, GLU_TESS_TOLERANCE, 0.5); + gluTessCallback(tess, GLU_TESS_VERTEX,(GLvoid (*)()) &zglVertex); gluTessCallback(tess, GLU_TESS_BEGIN,(GLvoid (*)()) &zglBegin); gluTessCallback(tess, GLU_TESS_END,(GLvoid (*)()) &zglEnd); gluTessCallback(tess, GLU_TESS_COMBINE_DATA,(GLvoid (*)()) &combineData); - ArrayList invented; - invented.set_array_delete(); - - gluTessBeginPolygon(tess, &invented); + glNewList(display_list, GL_COMPILE); + gluTessBeginPolygon(tess, &invented); gluTessBeginContour(tess); MaskCoord *c = &edge[0]; for( int i=edge.size(); --i>=0; ++c ) gluTessVertex(tess, (GLdouble *)c, c); gluTessEndContour(tess); - gluTessEndPolygon(tess); - gluDeleteTess(tess); - invented.remove_all_objects(); -#endif + gluTessEndPolygon(tess); glEndList(); glCallList(display_list); + gluDeleteTess(tess); } +#endif glDeleteLists(1, display_list); - } - } - -// in/out textures - fb_texture *in = new fb_texture(w, h, color_model); - in->bind(0); - in->read_screen(0,0, w,h); - fb_texture *out = new fb_texture(w, h, color_model); - - unsigned int frag_shader = - VFrame::make_shader(0, in_vertex_frag, feather_frag, 0); - if( frag_shader > 0 ) { - GLuint points[1]; - glGenBuffers(1, points); - for(int k = 0; k < total_submasks; k++) { - MaskEdge &edge = *edges[k]; - if( !edge.size() ) continue; - if( !faders[k] ) continue; - if( !feathers[k] ) continue; - MaskSpots spots; - for( int i=0; iread_screen(0,0, w,h); +//in->write_tex("/tmp/in0.ppm"); + if( r ) { + double sig2 = -log(255.0)/(r*r); + int n = abs((int)r) + 1; + if( n > 1024 ) n = 1024; // MAX + float psf[n]; // point spot fn + for( int i=0; ibind(0); + out->set_output_texture(); + out->draw_texture(0,0, w,h, 0,0, w,h); + out->unset_output_texture(); +//out->write_tex("/tmp/out1.ppm"); + fb_texture *t = in; in = out; out = t; + glUniform2f(glGetUniformLocation(feather_shader, "dxy"), 0., th); + in->bind(0); + out->set_output_texture(); + out->draw_texture(0,0, w,h, 0,0, w,h); + out->unset_output_texture(); +//out->write_tex("/tmp/out2.ppm"); + glUseProgram(0); + t = in; in = out; out = t; } - int sz = spots.size() * sizeof(MaskSpot); - glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, points[0], 0, sz); - glBufferData(GL_SHADER_STORAGE_BUFFER, sz, &spots[0], GL_DYNAMIC_COPY); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); - glUseProgram(frag_shader); - float r = feathers[k], v = faders[k]; - glUniform1f(glGetUniformLocation(frag_shader, "r"), r); - glUniform1f(glGetUniformLocation(frag_shader, "v"), v); + + glUseProgram(max_shader); in->bind(0); - glUniform1i(glGetUniformLocation(frag_shader, "tex"), 0); - out->set_output_texture(); +//in->write_tex("/tmp/in1.ppm"); +//mask->write_tex("/tmp/mask1.ppm"); + mask->bind(1); + glUniform1i(glGetUniformLocation(max_shader, "tex"), 0); + glUniform1i(glGetUniformLocation(max_shader, "tex1"), 1); + glUniform1f(glGetUniformLocation(max_shader, "r"), r); + glUniform1f(glGetUniformLocation(max_shader, "v"), v); glViewport(0,0, w,h); + out->set_output_texture(); out->draw_texture(0,0, w,h, 0,0, w,h); + out->unset_output_texture(); glUseProgram(0); - fb_texture *t = in; in = out; out = t; + fb_texture *t = mask; mask = out; out = t; +//mask->write_tex("/tmp/mask2.ppm"); } - glDeleteBuffers(1, points); + delete in; + delete out; } - glDrawBuffers(0, 0); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - unsigned int shader = VFrame::make_shader(0, alpha_frag, 0); + const char *alpha_shader = BC_CModels::has_alpha(color_model) ? + multiply_mask4_frag : + !BC_CModels::is_yuv(color_model) ? + multiply_mask3_frag : + multiply_yuvmask3_frag; + unsigned int shader = VFrame::make_shader(0, alpha_shader, 0); glUseProgram(shader); if( shader > 0 ) { command->frame->bind_texture(0); - in->BC_Texture::bind(1); + mask->BC_Texture::bind(1); glUniform1i(glGetUniformLocation(shader, "tex"), 0); - glUniform1i(glGetUniformLocation(shader, "tex2"), 1); - glUniform2f(glGetUniformLocation(shader, "tex2_dimensions"), - (float)in->get_texture_w(), - (float)in->get_texture_h()); -// if( BC_CModels::components(color_model ) == 4) { -// glEnable(GL_BLEND); -// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -// } + glUniform1i(glGetUniformLocation(shader, "tex1"), 1); } command->frame->draw_texture(); command->frame->set_opengl_state(VFrame::SCREEN); glUseProgram(0); - delete in; - delete out; -// Default drawable - glDisable(GL_TEXTURE_2D); + delete mask; glColor4f(1, 1, 1, 1); glActiveTexture(GL_TEXTURE0); + glDisable(GL_TEXTURE_2D); window->enable_opengl(); } command->canvas->unlock_canvas();