PDA

View Full Version : 2D vector graphics with opengl



noeska
08-18-2009, 12:07 PM
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 :-)

Thanks for your answers in advance.

Brolingstanz
08-19-2009, 11:43 AM
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.

davej
08-19-2009, 02:29 PM
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.

noeska
08-26-2009, 12:03 PM
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);