2D vector graphics with opengl

I am trying to draw 2d vector graphics using opengl.
So far i am able to draw quadratic en cubic splines.
First i ‘convert’ the spline into line segments with an adjusteable quality, next i tesselate that with GluTess.
That gives me nice enough shapes.

But now comes the problem how do i use fills on that, giving it a color is no problem and i even managed to do (angled) gradient fills with interpolating colors at vertex positions.

But how to do circular fills on that? Is that even possible?

Could i use pixel shaders for filling, if so how would i write such an shader. Are there tutorials on ‘drawing’ with pixelshaders?

Also i read the loop blinn resolution independent curve rendering, but my math knowledge is not enough to understand it.
They store information on rendering the spline in the texture coords? One thing that i made work from that is rendering quadratic splines using a shader. But i fail completely at the cubic splines. Who can explain that proces in plain english. I get lost in all the formulas and different curve types. Making line segments from a cubic spline is much easier :slight_smile:

Thanks for your answers in advance.

For an intuitive look at splines search for “Blossoming”. There’s a great old paper by Lyle Ramshaw online that’ll walk you through all the (not so gory) details.

You might also look at http://research.microsoft.com/en-us/um/people/hoppe/ravg_tr.pdf which covers similar stuff to the Loop/Blinn paper.

I went back to drawing splines the old way.
For filling i now use the stencilbuffer.
This works good, drawing a circle with rings allowed me to make circular gradient fill.
Now i have problems as i want the alpha set independently of the gradient fill. I.e. i want to have an horizontal gradient color fill and a vertical alpha (transparency) fill.

I got something working, but not with my favorite alpha blending, instead i got some bleach effect that is order dependend in the way it draws.

Below is my testcase. It draws a large green quad en 2 smaller quads on top. A red and a blue one. Both have gradient alpha blending. Drawing the 2nd quad first and a strange effect happens.

 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
  glEnable(GL_BLEND); 

  glcolor4f(0,1,0,1); 
  glbegin(GL_QUADS); 
     glVertex3f(0, 480, 0.0);      // Top Left 
     glVertex3f(640, 480, 0.0);      // Top Right 

     glVertex3f(640, 0, 0.0);      // Bottom Right 
     glVertex3f(0, 0, 0.0);      // Bottom Left 
  glend; 

  //FIRST QUAD 

  //turning off writing to the color buffer and depth buffer so we only 
  //write to stencil buffer 
  glColorMask(FALSE, FALSE, FALSE, FALSE); 
  //enable stencil buffer 
  glEnable(GL_STENCIL_TEST); 
  //write a one to the stencil buffer everywhere we are about to draw 
  glStencilFunc(GL_ALWAYS, 2, $FFFFFFFF); 
  //this is to always pass a one to the stencil buffer where we draw 
  glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); 
  //draw shape 

  glbegin(GL_QUADS); 
     glVertex3f(0, 260, 0.0);      // Top Left 
     glVertex3f(280, 260, 0.0);      // Top Right 
     glVertex3f(280, 0, 0.0);      // Bottom Right 
     glVertex3f(0, 0, 0.0);      // Bottom Left 
  glend; 

  //until stencil test is diabled, only write to areas where the 
  //stencil buffer has a one. This fills the shape 
  glStencilFunc(GL_EQUAL, 2, $FFFFFFFF); 
  // don't modify the contents of the stencil buffer 
  glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 


  //draw alpha fill 
  glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
  glColorMask(FALSE,FALSE,FALSE, TRUE); 

  glbegin(GL_QUADS); 
    glcolor4f(1,1,1,1); //SOLID 
     glVertex3f(0, 260, 0.0);      // Top Left 
     glVertex3f(280, 260, 0.0);      // Top Right 
    glcolor4f(1,1,1,0.0); //TRANSPARENT 
     glVertex3f(280, 0, 0.0);      // Bottom Right 
     glVertex3f(0, 0, 0.0);      // Bottom Left 
  glend; 

  //draw fill 
  glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA); 
  glColorMask(TRUE,TRUE, TRUE, FALSE); //but not alpha 

  glbegin(GL_QUADS); 
    glcolor4f(1,0,0,1); //RED 
     glVertex3f(0, 260, 0.0);      // Top Left 
     glVertex3f(280, 260, 0.0);      // Top Right 
     glVertex3f(280, 0, 0.0);      // Bottom Right 
     glVertex3f(0, 0, 0.0);      // Bottom Left 
  glend; 

  //'default' rendering again 
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
  glColorMask(TRUE,TRUE, TRUE, TRUE); 
  glDisable(GL_STENCIL_TEST); 

  //SECOND QUAD 

    //turning off writing to the color buffer and depth buffer so we only 
  //write to stencil buffer 
  glColorMask(FALSE, FALSE, FALSE, FALSE); 
  //enable stencil buffer 
  glEnable(GL_STENCIL_TEST); 
  //write a one to the stencil buffer everywhere we are about to draw 
  glStencilFunc(GL_ALWAYS, 4, $FFFFFFFF); 
  //this is to always pass a one to the stencil buffer where we draw 
  glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); 
  //draw shape 

  glbegin(GL_QUADS); 
     glVertex3f(100, 360, 0.0);      // Top Left 
     glVertex3f(380, 360, 0.0);      // Top Right 
     glVertex3f(380, 100, 0.0);      // Bottom Right 
     glVertex3f(100, 100, 0.0);      // Bottom Left 
  glend; 

  //until stencil test is diabled, only write to areas where the 
  //stencil buffer has a one. This fills the shape 
  glStencilFunc(GL_EQUAL, 4, $FFFFFFFF); 
  // don't modify the contents of the stencil buffer 
  glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 


  //draw alpha fill 
  glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
  glColorMask(FALSE,FALSE,FALSE, TRUE); 

  glbegin(GL_QUADS); 
    glcolor4f(1,1,1,1); //SOLID 
     glVertex3f(100, 360, 0.0);      // Top Left 
     glVertex3f(380, 360, 0.0);      // Top Right 
    glcolor4f(1,1,1,0.0); //TRANSPARENT 
     glVertex3f(380, 0, 0.0);      // Bottom Right 
     glVertex3f(100, 100, 0.0);      // Bottom Left 
  glend; 

  //draw fill 
  glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA); 
  glColorMask(TRUE,TRUE, TRUE, FALSE); //but not alpha 

  glbegin(GL_QUADS); 
    glcolor4f(0,0,1,1); //BLUE 
     glVertex3f(100, 360, 0.0);      // Top Left 
     glVertex3f(380, 360, 0.0);      // Top Right 
     glVertex3f(380, 100, 0.0);      // Bottom Right 
     glVertex3f(100, 100, 0.0);      // Bottom Left 
  glend; 

  //'default' rendering again 
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
  glColorMask(TRUE,TRUE, TRUE, TRUE); 
  glDisable(GL_STENCIL_TEST);

How do apply color and alpha separately and still get the effect you get from glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);