PDA

View Full Version : glNormal3d(...) on Bezier, Vector-math

03-06-2002, 06:37 AM
I've implemented Bezier-Splines into my engine, and they work fine,
but in order to get the lighting done, I need to place the correct Vectors on
every triangle. My code is something like this:

void DrawGLScene()
{
glBegin(GL_LINE_LOOP);
while (m < 1)
{
glVertex( CalcVertex(x, m), CalcVertex(y, m), CalcVertex(z, m) );
m = m + 0.1f;
}
glEnd();
}

CalcVertex know everything about the Bezier, meaning the two points, and the two vectors. Can I get a function the would return all three points? Because I feel that I'm kinda cheating; this isn't exactly vector-math, I just worked around it!
(In POV-Ray it was easy: just something like <1, 2, 5> * 5 would equal <5, 10, 25> ).
For an extruded spline I do the same as above, I only add the line
glVertex3d (CalcVertex(x,m),CalcVertex(y,m),CalcVertex(z,m)-2);
after the first glVertex3d(...), and use a GL_TRIANGLE_STRIP, rather than GL_LINE_LOOP. That way, I get a proper Spline-Surface.
But if I want lighting in my engine, I have to have Vectors on every triangle. Does anyone know how to calculate them?

zeckensack
03-06-2002, 08:22 AM
You need the first derivatives of your spline evaluation function in x and in y (as you z is fixed, you don't need that). Put the results in a vector and normalize, that's your surface normal.

Rob The Bloke
03-06-2002, 07:07 PM
Originally posted by zeckensack:
You need the first derivatives of your spline evaluation function in x and in y (as you z is fixed, you don't need that). Put the results in a vector and normalize, that's your surface normal.

On a bezier it isn't too bad to calculate the derivatives, You could look at a paper on Gamasutra for the NURBS derivatives, but it's very hectic. To be fair though I always cheat.

you can approximate the vectors du and dv by subtracting the next vertex from the current one in both the u and v directions. Its then just a case of performing a cross product with these vectors and normalising the result to get your surface normal.

It will require a bit of blagging for the edges of the surface, but its not too bad. You can generally tell that its faked at the lowest tessellations, but at higher ones you wont notice.

As a couple of additional points though for performance, you actually dont need to calculate that much for a bezier patch.

Q(u) = B0(u)*P0 + B1(u)*P1 + B2(u)*P2 + B3(u)*P3

you'll notice that the blending functions only ever change when the LOD changes, in that case, cache them in an array every time you change the LOD, and then you avoid a lot of calculation per frame.

Lazy evaluation is the way with parametric surfaces & curves.

Bezier patchs should nicely fall into triangle strips that work extremely well with vertex arrays. I'd recommend drawing them that way for that very reason (fastest primitive plus non-immediate mode = very fast). Once you've calculated the vertex array, you'll only ever need to re-calculate the surface when a control point changes.

03-07-2002, 03:07 AM
Thanks a lot! I'm still a newbie, so I don't know what really gives me a performance hit, and what gives me a performance boost.
I wonder: Would a class that holds everything I need for the bezier be more appropriate?
Expect quite a lot questions from me in the near future, I'm really into OpenGL right now! I'd like to collect as much knowledge as my little brain can contain. Hey, that rhymed! :-)

03-07-2002, 03:13 AM
The class would calculate the Bezier and put everything into a Vertex-Array until something changed (thanks for that piece of advice, Rob).