-// Draw mask with scaling to simulate feathering
- GLUtesselator *tesselator = gluNewTess();
- gluTessProperty(tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
- gluTessCallback(tesselator, GLU_TESS_VERTEX, (GLvoid (*) ( )) &glVertex3dv);
- gluTessCallback(tesselator, GLU_TESS_BEGIN, (GLvoid (*) ( )) &glBegin);
- gluTessCallback(tesselator, GLU_TESS_END, (GLvoid (*) ( )) &glEnd);
- gluTessCallback(tesselator, GLU_TESS_COMBINE, (GLvoid (*) ( ))&combine_callback);
-
- vertex_cache = new List<Vertex>;
-
-
-// Draw every submask as a new polygon
- int total_submasks = command->keyframe_set->total_submasks(
- command->start_position_project,
- PLAY_FORWARD);
- float scale = command->keyframe->feather + 1;
- int display_list = glGenLists(1);
- glNewList(display_list, GL_COMPILE);
- for(int k = 0; k < total_submasks; k++)
- {
- gluTessBeginPolygon(tesselator, NULL);
- gluTessBeginContour(tesselator);
- ArrayList<MaskPoint*> *points = new ArrayList<MaskPoint*>;
- command->keyframe_set->get_points(points,
- k,
- command->start_position_project,
- PLAY_FORWARD);
-
- int first_point = 0;
-// Need to tabulate every vertex in persistent memory because
-// gluTessVertex doesn't copy them.
- ArrayList<GLdouble*> coords;
- coords.set_array_delete();
- 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;
- float 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;
- float 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);
- }
-
- 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));
-
- if(j > 0 || first_point)
- {
- GLdouble *coord = new GLdouble[3];
- coord[0] = x / scale;
- coord[1] = -h + y / scale;
- coord[2] = 0;
- coords.append(coord);
- first_point = 0;
- }
+// 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; i<edge.size(); ++i ) {
+ MaskCoord &a = edge[i];
+ MaskCoord &b = i<edge.size()-1 ? edge[i+1] : edge[0];
+ draw_spots(spots, a.x,a.y+h, b.x,b.y+h);