📄 tutorial_28.htm
字号:
<p>求值器基于Bernstein多项式定义曲线,定义p(u ')为:<br>
<font size="+2">p(u')=∑B<sup>n</sup><sub>i</sub>(u')Ri</font></p>
<p>这里Ri为控制点<br>
<font size="+2">B<sup>n</sup><sub>i</sub>(u')=[<sup>n</sup><sub>i</sub>]u'<sup>i</sup>(1-u')<sup>n-i</sup></font><br>
<br>
且0<sup>0</sup>=1,[<sup>n</sup><sub>0</sub>]=1</p>
<p>u'=(u-u1)/(u2-u1)</p>
<p>当为贝塞尔曲线时,控制点为4,相应的4个Bernstein多项式为:<br>
<font size="+2">1、B<sup>3</sup><sub>0</sub></font> =(1-u)<sup>3</sup><br>
<font size="+2">2、B<sup>3</sup><sub>1</sub></font> =3u(1-u)<sup>2</sup><br>
<font size="+2">3、B<sup>3</sup><sub>2</sub></font> =3u<sup>2</sup>(1-u)<br>
<font size="+2">4、B<sup>3</sup><sub>3</sub></font> =u<sup>3</sup><br>
</p>
</td>
<td background="Tutorial_28_files/r.png"><img src="Tutorial_28_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_28_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_28_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_28_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3"><pre><font color="#ffffaa">// 计算贝塞尔方程的值</font>
<font color="#ffffaa">// 变量u的范围在0-1之间</font>
POINT_3D Bernstein(float u, POINT_3D *p) {
POINT_3D a, b, c, d, r;
a = pointTimes(pow(u,3), p[0]);
b = pointTimes(3*pow(u,2)*(1-u), p[1]);
c = pointTimes(3*u*pow((1-u),2), p[2]);
d = pointTimes(pow((1-u),3), p[3]);
r = pointAdd(pointAdd(a, b), pointAdd(c, d));
return r;
}
</pre></font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_28_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_28_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_28_files/tr.png" height="28" width="28"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td background="Tutorial_28_files/l.png"><img src="Tutorial_28_files/l.png"></td>
<td valign="top" width="100%">这
个函数完成共享工作,生成所有三角带,保存在display
list。我们这样就不需要每贞都重新计算曲面,除了当其改变时。另外,你可能想用一个很酷的效果,用MORPHING教程改变控制点位置。这可以做一个
很光滑,有机的,morphing效果,只要一点点开销(你只要改变16个点,但要从新计算)。“最后”的数组元素用来保存前一行点,(因为三角带需要两
行)。而且,纹理坐标由表示百分比的u,v来计算(平面映射)。<br>
还有一个我们没做的是计算法向量做光照。到了这一步,你基本上有2种选择。第一是找每个三角形的中心计算X,Y轴的切线,再做叉积得到垂直与两向量的向
量,再归一化,得到法向量。或者(恩,这是更好的方法)你可以直接用三角形的法矢(用你最喜欢的方法计算)得到一个近似值。我喜欢后者;我认为不值得为了
一点点真实感影响速度。</td>
<td background="Tutorial_28_files/r.png"><img src="Tutorial_28_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_28_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_28_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_28_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3">
<pre><font color="#ffffaa">// 生成贝塞尔曲面的显示列表</font>
GLuint genBezier(BEZIER_PATCH patch, int divs) {
int u = 0, v;
float py, px, pyold;
GLuint drawlist = glGenLists(1); <font color="#ffffaa">// 创建显示列表</font>
POINT_3D temp[4];
POINT_3D *last = (POINT_3D*)malloc(sizeof(POINT_3D)*(divs+1)); <font color="#ffffaa">// 更具每一条曲线的细分数,分配相应的内存</font>
if (patch.dlBPatch != NULL) <font color="#ffffaa">// 如果显示列表存在则删除</font>
glDeleteLists(patch.dlBPatch, 1);
temp[0] = patch.anchors[0][3]; <font color="#ffffaa">// 获得u方向的四个控制点</font>
temp[1] = patch.anchors[1][3];
temp[2] = patch.anchors[2][3];
temp[3] = patch.anchors[3][3];
for (v=0;v<=divs;v++) { <font color="#ffffaa">// 根据细分数,创建各个分割点额参数</font>
px = ((float)v)/((float)divs);
<font color="#ffffaa">// 使用Bernstein函数求的分割点的坐标</font>
last[v] = Bernstein(px, temp);
}
glNewList(drawlist, GL_COMPILE); <font color="#ffffaa">// 创建一个新的显示列表</font>
glBindTexture(GL_TEXTURE_2D, patch.texture); <font color="#ffffaa">// 邦定纹理</font>
for (u=1;u<=divs;u++) {
py = ((float)u)/((float)divs); <font color="#ffffaa">// 计算v方向上的细分点的参数</font>
pyold = ((float)u-1.0f)/((float)divs); <font color="#ffffaa">// </font><font color="#aaffaa" size="3"><font color="#ffffaa">上一个v方向上的细分点的参数</font></font>
temp[0] = Bernstein(py, patch.anchors[0]); <font color="#ffffaa">// 计算每个细分点v方向上贝塞尔曲面的控制点</font>
temp[1] = Bernstein(py, patch.anchors[1]);
temp[2] = Bernstein(py, patch.anchors[2]);
temp[3] = Bernstein(py, patch.anchors[3]);
glBegin(GL_TRIANGLE_STRIP); <font color="#ffffaa">// 开始绘制三角形带</font>
for (v=0;v<=divs;v++) {
px = ((float)v)/((float)divs); <font color="#ffffaa">// 沿着u轴方向顺序绘制</font>
glTexCoord2f(pyold, px); <font color="#ffffaa">// 设置纹理坐标</font>
glVertex3d(last[v].x, last[v].y, last[v].z); <font color="#ffffaa">// 绘制一个顶点</font>
last[v] = Bernstein(px, temp); <font color="#ffffaa">// 创建下一个顶点</font>
glTexCoord2f(py, px); <font color="#ffffaa">// 设置纹理</font>
glVertex3d(last[v].x, last[v].y, last[v].z); <font color="#ffffaa">// 绘制新的顶点</font>
}
glEnd(); <font color="#ffffaa">// 结束三角形带的绘制</font>
}
glEndList(); <font color="#ffffaa">// 显示列表绘制结束</font>
free(last); <font color="#ffffaa">// 释放分配的内存</font>
return drawlist; <font color="#ffffaa">// 返回创建的显示列表</font>
}
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_28_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_28_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_28_files/tr.png" height="28" width="28"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td background="Tutorial_28_files/l.png"><img src="Tutorial_28_files/l.png"></td>
<td valign="top" width="100%">这里我们调用一个我认为有一些很酷的值的矩阵。</td>
<td background="Tutorial_28_files/r.png"><img src="Tutorial_28_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_28_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_28_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_28_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
<pre>void initBezier(void) {
mybezier.anchors[0][0] = makePoint(-0.75, -0.75, -0.50); <font color="#ffffaa">// 设置贝塞尔曲面的控制点</font>
mybezier.anchors[0][1] = makePoint(-0.25, -0.75, 0.00);
mybezier.anchors[0][2] = makePoint( 0.25, -0.75, 0.00);
mybezier.anchors[0][3] = makePoint( 0.75, -0.75, -0.50);
mybezier.anchors[1][0] = makePoint(-0.75, -0.25, -0.75);
mybezier.anchors[1][1] = makePoint(-0.25, -0.25, 0.50);
mybezier.anchors[1][2] = makePoint( 0.25, -0.25, 0.50);
mybezier.anchors[1][3] = makePoint( 0.75, -0.25, -0.75);
mybezier.anchors[2][0] = makePoint(-0.75, 0.25, 0.00);
mybezier.anchors[2][1] = makePoint(-0.25, 0.25, -0.50);
mybezier.anchors[2][2] = makePoint( 0.25, 0.25, -0.50);
mybezier.anchors[2][3] = makePoint( 0.75, 0.25, 0.00);
mybezier.anchors[3][0] = makePoint(-0.75, 0.75, -0.50);
mybezier.anchors[3][1] = makePoint(-0.25, 0.75, -1.00);
mybezier.anchors[3][2] = makePoint( 0.25, 0.75, -1.00);
mybezier.anchors[3][3] = makePoint( 0.75, 0.75, -0.50);
mybezier.dlBPatch = NULL; <font color="#ffffaa">// 默认的显示列表为0</font>
}
</pre>
</font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_28_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_28_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_28_files/tr.png" height="28" width="28"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td background="Tutorial_28_files/l.png"><img src="Tutorial_28_files/l.png"></td>
<td valign="top" width="100%">这是一个优化的调位图的函数。可以很简单的把他们放进一个简单循环里调一组。 </td>
<td background="Tutorial_28_files/r.png"><img src="Tutorial_28_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_28_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_28_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_28_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
<pre><font color="#ffffaa">// 加载一个*.bmp文件,并转化为纹理</font>
BOOL LoadGLTexture(GLuint *texPntr, char* name)
{
BOOL success = FALSE;
AUX_RGBImageRec *TextureImage = NULL;
glGenTextures(1, texPntr); <font color="#ffffaa">// 生成纹理1</font>
FILE* test=NULL;
TextureImage = NULL;
test = fopen(name, "r");
if (test != NULL) {
fclose(test);
TextureImage = auxDIBImageLoad(name);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -