📄 tutorial_36.htm
字号:
static const int x = 0; <font color="#ffffaa">// 定义 X坐标</font>
static const int y = 1; <font color="#ffffaa">// 定义 Y 坐标</font>
static const int z = 2; <font color="#ffffaa">// 定义 Z 坐标</font>
<font color="#ffffaa">// 用减法在两点之间得到向量<br>// 从一点到另一点的X,Y,Z坐标<br>// 计算点1到点0的向量</font>
v1[x] = v[0][x] - v[1][x];
v1[y] = v[0][y] - v[1][y];
v1[z] = v[0][z] - v[1][z];
<font color="#ffffaa">// 计算点2到点1的向量</font>
v2[x] = v[1][x] - v[2][x];
v2[y] = v[1][y] - v[2][y];
v2[z] = v[1][z] - v[2][z];
<font color="#ffffaa">// 计算交叉乘积为我们提供一个表面的法线</font>
out[x] = v1[y]*v2[z] - v1[z]*v2[y];
out[y] = v1[z]*v2[x] - v1[x]*v2[z];
out[z] = v1[x]*v2[y] - v1[y]*v2[x];
ReduceToUnit(out); <font color="#ffffaa">// 规格化向量</font>
}
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_36_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_36_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_36_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_36_files/l.png"><img src="Tutorial_36_files/l.png"></td>
<td valign="top" width="100%">下面的例子正好用gluLookAt设立了一个观察点。我们设置一个观察点放置在0,5,50位置——正照看0,0,0并且所属的向上的向量正仰望(0,1,0)!:D</td>
<td background="Tutorial_36_files/r.png"><img src="Tutorial_36_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_36_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_36_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_36_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3">
</font><pre><font color="#aaffaa" size="3">void ProcessHelix() <font color="#ffffaa">// 绘制一个螺旋</font>
{
GLfloat x; <font color="#ffffaa">// 螺旋x坐标</font>
GLfloat y; <font color="#ffffaa">// 螺旋y坐标</font>
GLfloat z; <font color="#ffffaa">// 螺旋z坐标</font>
GLfloat phi; <font color="#ffffaa">// 角</font>
GLfloat theta; <font color="#ffffaa">// 角</font>
GLfloat v,u; <font color="#ffffaa">// 角</font>
GLfloat r; <font color="#ffffaa">// 螺旋半径</font>
int twists = 5; <font color="#ffffaa">// 5个螺旋</font>
GLfloat glfMaterialColor[]={0.4f,0.2f,0.8f,1.0f}; <font color="#ffffaa"> // 设置材料色彩</font>
GLfloat specular[]={1.0f,1.0f,1.0f,1.0f}; <font color="#ffffaa">// 设置镜象灯光</font>
glLoadIdentity(); <font color="#ffffaa"> // 重置Modelview矩阵</font>
gluLookAt(0, 5, 50, 0, 0, 0, 0, 1, 0); <font color="#ffffaa">// 场景(0,0,0)的视点中心 (0,5,50),Y轴向上</font>
glPushMatrix(); <font color="#ffffaa">// 保存Modelview矩阵</font>
glTranslatef(0,0,-50); <font color="#ffffaa">// 移入屏幕50个单位</font>
glRotatef(angle/2.0f,1,0,0); <font color="#ffffaa">// 在X轴上以1/2角度旋转</font>
glRotatef(angle/3.0f,0,1,0); <font color="#ffffaa">// 在Y轴上以1/3角度旋转</font>
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,glfMaterialColor);
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,specular);
</font></pre>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_36_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_36_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_36_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_36_files/l.png"><img src="Tutorial_36_files/l.png"></td>
<td valign="top" width="100%">然后我们计算螺旋的公式并给弹簧着色。十分简单,我就不再解释了,因为它不是这篇指南的主要目的。这段螺旋代码经过软件赞助者的许可被借用(并作了一点优化)。这是写作的简单的方法,但不是最块的方法。使用顶点数组可以使它更快!</td>
<td background="Tutorial_36_files/r.png"><img src="Tutorial_36_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_36_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_36_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_36_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3">
</font><pre><font color="#aaffaa" size="3"> r=1.5f; <font color="#ffffaa">// 半径</font>
glBegin(GL_QUADS); <font color="#ffffaa">// 开始绘制立方体</font>
for(phi=0; phi <= 360; phi+=20.0) <font color="#ffffaa">// 以20度的间隔绘制</font>
{
for(theta=0; theta<=360*twists; theta+=20.0)
{
v=(phi/180.0f*3.142f); <font color="#ffffaa">// 计算第一个点 ( 0 )的角度</font>
u=(theta/180.0f*3.142f); <font color="#ffffaa">// 计算第一个点 ( 0 )的角度</font>
x=float(cos(u)*(2.0f+cos(v) ))*r; <font color="#ffffaa">// 计算x的位置(第一个点)</font>
y=float(sin(u)*(2.0f+cos(v) ))*r; <font color="#ffffaa">// 计算y的位置(第一个位置)</font>
z=float((( u-(2.0f*3.142f)) + sin(v) ) * r); <font color="#ffffaa">// 计算z的位置(第一个位置)</font>
vertexes[0][0]=x; <font color="#ffffaa">// 设置第一个顶点的x值</font>
vertexes[0][1]=y; <font color="#ffffaa">// 设置第一个顶点的y值</font>
vertexes[0][2]=z; <font color="#ffffaa">// 设置第一个顶点的z值 </font>
v=(phi/180.0f*3.142f); <font color="#ffffaa">// 计算第二个点( 0 )的角度</font>
u=((theta+20)/180.0f*3.142f); <font color="#ffffaa">// 计算第二个点( 20 )的角度</font>
x=float(cos(u)*(2.0f+cos(v) ))*r; <font color="#ffffaa">// 计算x位置(第二个点)</font>
y=float(sin(u)*(2.0f+cos(v) ))*r; <font color="#ffffaa">// 计算y位置(第二个点)</font>
z=float((( u-(2.0f*3.142f)) + sin(v) ) * r); <font color="#ffffaa">// 计算z位置(第二个点)</font>
vertexes[1][0]=x; <font color="#ffffaa">// 设置第二个顶点的x值</font>
vertexes[1][1]=y; <font color="#ffffaa">// 设置第二个顶点的y值</font>
vertexes[1][2]=z; <font color="#ffffaa">// 设置第二个顶点的z值</font>
v=((phi+20)/180.0f*3.142f); <font color="#ffffaa">// 计算第三个点 ( 20 )的角度</font>
u=((theta+20)/180.0f*3.142f); <font color="#ffffaa">// 计算第三个点 ( 20 )的角度</font>
x=float(cos(u)*(2.0f+cos(v) ))*r; <font color="#ffffaa">// 计算x位置 (第三个点)</font>
y=float(sin(u)*(2.0f+cos(v) ))*r; <font color="#ffffaa">// 计算y位置 (第三个点)</font>
z=float((( u-(2.0f*3.142f)) + sin(v) ) * r); <font color="#ffffaa">// 计算z位置 (第三个点)</font>
vertexes[2][0]=x; <font color="#ffffaa">// 设置第三个顶点的x值</font>
vertexes[2][1]=y; <font color="#ffffaa">// 设置第三个顶点的y值</font>
vertexes[2][2]=z; <font color="#ffffaa">// 设置第三个顶点的z值</font>
v=((phi+20)/180.0f*3.142f); <font color="#ffffaa">// 计算第四个点( 20 )的角度</font>
u=((theta)/180.0f*3.142f); <font color="#ffffaa">// 计算第四个点( 0 )的角度</font>
x=float(cos(u)*(2.0f+cos(v) ))*r; <font color="#ffffaa">// 计算x位置 (第四个点)</font>
y=float(sin(u)*(2.0f+cos(v) ))*r; <font color="#ffffaa">// 计算y位置 (第四个点)</font>
z=float((( u-(2.0f*3.142f)) + sin(v) ) * r); <font color="#ffffaa">// 计算z位置 (第四个点))</font>
vertexes[3][0]=x; <font color="#ffffaa">// 设置第四个顶点的x值</font>
vertexes[3][1]=y; <font color="#ffffaa">// 设置第四个顶点的y值</font>
vertexes[3][2]=z; <font color="#ffffaa">// 设置第四个顶点的z值</font>
calcNormal(vertexes,normal); <font color="#ffffaa">// 计算立方体的法线</font>
glNormal3f(normal[0],normal[1],normal[2]); <font color="#ffffaa">// 设置法线</font>
<font color="#ffffaa">// 渲染四边形</font>
glVertex3f(vertexes[0][0],vertexes[0][1],vertexes[0][2]);
glVertex3f(vertexes[1][0],vertexes[1][1],vertexes[1][2]);
glVertex3f(vertexes[2][0],vertexes[2][1],vertexes[2][2]);
glVertex3f(vertexes[3][0],vertexes[3][1],vertexes[3][2]);
}
}
glEnd(); <font color="#ffffaa">// 绘制结束</font>
glPopMatrix(); <font color="#ffffaa">// 取出矩阵</font>
}
</font></pre>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_36_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_36_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_36_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_36_files/l.png"><img src="Tutorial_36_files/l.png"></td>
<td valign="top" width="100%">这两个事例(ViewOrtho and ViewPerspective)被编码以使它变得很容易地在一个直交的情形下绘制并且不费力的返回透视图。<br>
ViewOrtho简单地设立了这个射影矩阵,然后增加一份现行射影矩阵的拷贝到OpenGL栈上。这个恒等矩阵然后被装载并且当前屏幕正投影观察决议被提出。<br>
利用2维坐标以屏幕左上角0,0和屏幕右下角639,479来绘制是可能的。<br>
最后,modelview矩阵为透视材料激活。<br>
ViewPerspective设置射影矩阵模式取回ViewOrtho在堆栈上推进的非正交矩阵。然后样本视图被选择因此我们可以透视材料。<br>
我建议你保留这两个过程,能够着色2D而不需担心射影矩阵很不错。</td>
<td background="Tutorial_36_files/r.png"><img src="Tutorial_36_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_36_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_36_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_36_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3">
<pre>void ViewOrtho() <font color="#ffffaa">// 设置一个z正视图</font>
{
glMatrixMode(GL_PROJECTION); <font color="#ffffaa">// 选择投影矩阵</font>
glPushMatrix(); <font color="#ffffaa">// 保存当前矩阵</font>
glLoadIdentity(); <font color="#ffffaa">// 重置矩阵</font>
glOrtho( 0, 640 , 480 , 0, -1, 1 ); <font color="#ffffaa">// 选择标准模式</font>
glMatrixMode(GL_MODELVIEW); <font color="#ffffaa">// 选择样本视图矩阵</font>
glPushMatrix(); <font color="#ffffaa">// 保存当前矩阵</font>
glLoadIdentity(); <font color="#ffffaa">// 重置矩阵</font>
}
void ViewPerspective() <font color="#ffffaa">// 设置透视视图</font>
{
glMatrixMode( GL_PROJECTION ); <font color="#ffffaa">// </font><font color="#aaffaa" size="3"><font color="#ffffaa">选择投影矩阵</font></font>
glPopMatrix(); <font color="#ffffaa">// 取出矩阵</font>
glMatrixMode( GL_MODELVIEW ); <font color="#ffffaa">// 选择模型变换矩阵</font>
glPopMatrix(); <font color="#ffffaa">//弹出矩阵</font>
}
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_36_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_36_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_36_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_36_files/l.png"><img src="Tutorial_36_files/l.png"></td>
<td valign="top" width="100%">现在是解释那个冒牌的辐射状的模糊效果是如何作的时候了。<br>
我们需要绘制这个场景——它从中心开始在所有方向上模糊出现。窍门是在没有主要的性能瓶颈的情况下做出的。我们不能读写象素,并且如果我们想和非kick-butt视频卡兼容,我们不能使用扩展名何驱动程序特殊命令。<br>
没办法了吗?<br>
不,解决方法非常简单,OpenGL赋予我们“模糊”纹理的能力。OK……并非真正的模糊,但我们利用线性过滤去依比例决定一个纹理,结果(有些想象成分)看起来象高斯模糊。<br>
因此如果我们正确地在3D场景中放了大量的被拉伸的纹理并依比例决定会有什么发生?<br>
答案比你想象的还简单。<br>
问题一:透视一个纹理<br>
有一个后缓冲器在象素格式下问题容易解决。在没有后缓冲器的情况下透视一个纹理在眼睛看来是一个真正的痛苦。<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -