⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tutorial_27.htm

📁 如果你相信它就好好学学吧,同样这里也只是个入门
💻 HTM
📖 第 1 页 / 共 4 页
字号:
	}
</pre>
</font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_27_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_27_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_27_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_27_files/l.png"><img src="Tutorial_27_files/l.png"></td>
    <td valign="top" width="100%">下面设置必要的状态来渲染阴影.<br>
      首先,禁用灯光和绘制颜色,因为我们不计算光照,这样可以节约计算量.<br>
      接着,设置深度缓存,深度测试还是需要的,但我们不希望我们的阴影体向实体一样具有深度,所以关闭深度缓存.<br>
      最后我们启用蒙板缓存,让阴影体的位置在蒙板中被设置为1.</td>
    <td background="Tutorial_27_files/r.png"><img src="Tutorial_27_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_27_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_27_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_27_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
</font><pre><font color="#aaffaa" size="3">	glDisable( GL_LIGHTING );					<font color="#ffffaa">// 关闭灯光</font>
	glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );		<font color="#ffffaa">// 关闭颜色缓存的写入</font>	
	glDepthFunc( GL_LEQUAL );					<font color="#ffffaa">// 设置深度比较函数</font>
	glDepthMask( GL_FALSE );					<font color="#ffffaa">// 关闭深度缓存的写入</font>	
	glEnable( GL_STENCIL_TEST );				<font color="#ffffaa">// 使用蒙板缓存</font>
	glStencilFunc( GL_ALWAYS, 1, 0xFFFFFFFFL );	<font color="#ffffaa">		// 设置蒙板函数</font>
</font></pre>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_27_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_27_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_27_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_27_files/l.png"><img src="Tutorial_27_files/l.png"></td>
    <td valign="top" width="100%">现在到了阴影被实际渲染得地方了,我们使用了下面提到的doShadowPass函数,它用来绘制阴影体的边界面.我们通过两个步骤来绘制阴影体,首先使用前向面增加阴影体在蒙板缓存中的值,接着使用后向面减少阴影体在蒙板缓存中的值.</td>
    <td background="Tutorial_27_files/r.png"><img src="Tutorial_27_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_27_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_27_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_27_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3"> 
</font><pre><font color="#aaffaa" size="3">	<font color="#ffffaa">// 如果是逆时针(即面向视点)的多边形,通过了蒙板和深度测试,则把蒙板的值增加1</font>
	glFrontFace( GL_CCW );
	glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
	doShadowPass( object, lightPosition );
	<font color="#ffffaa">// 如果是顺时针(即背向视点)的多边形,通过了蒙板和深度测试,则把蒙板的值减少1</font>
	glFrontFace( GL_CW );
	glStencilOp( GL_KEEP, GL_KEEP, GL_DECR );
	doShadowPass( object, lightPosition );
</font></pre>
 
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_27_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_27_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_27_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_27_files/l.png"><img src="Tutorial_27_files/l.png"></td>
    <td valign="top" width="100%">为了更好的理解这两个步骤,我建议你把第二步注释掉看看效果,如下所示: <font face="Tahoma,Verdana,sans-serif" size="-1"><br>
      <br>
      <table align="center" border="0">
        <tbody><tr align="center" valign="top"> 
          <td><img src="Tutorial_27_files/pass1.jpg" height="150" width="200"></td>
          <td><img src="Tutorial_27_files/pass2.jpg" height="150" width="200"></td>
        </tr>
        <tr align="center" valign="top"> 
          <td>图 1: 步骤1</td>
          <td>图 2: 步骤2</td>
        </tr>
      </tbody></table>
      <br>
      <br>
      </font>最后一步就是把阴影体所在的位置绘制上阴影的颜色</td>
    <td background="Tutorial_27_files/r.png"><img src="Tutorial_27_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_27_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_27_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_27_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
<pre>	glFrontFace( GL_CCW );
	glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );	

	<font color="#ffffaa">// 把阴影绘制上颜色</font>
	glColor4f( 0.0f, 0.0f, 0.0f, 0.4f );
	glEnable( GL_BLEND );
	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
	glStencilFunc( GL_NOTEQUAL, 0, 0xFFFFFFFFL );
	glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
	glPushMatrix();
	glLoadIdentity();
	glBegin( GL_TRIANGLE_STRIP );
		glVertex3f(-0.1f, 0.1f,-0.10f);
		glVertex3f(-0.1f,-0.1f,-0.10f);
		glVertex3f( 0.1f, 0.1f,-0.10f);
		glVertex3f( 0.1f,-0.1f,-0.10f);
	glEnd();
	glPopMatrix();
}
</pre>
</font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_27_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_27_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_27_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_27_files/l.png"><img src="Tutorial_27_files/l.png"></td>
    <td valign="top" width="100%">下面的部分我们绘制构成阴影体边界的四边形,当我们循环所有的三角形面的时候,我们检测它是否是边界边,如果是我们绘制从灯光到这个边界边的射线,并衍生它用来构成四边形.
<p>这里要用一个蛮力,我们检测物体模型中每一个三角形面,找出其边界并连接灯光到边界的直线,把直线延长出一定的距离,构成阴影体.</p>
      <p>下面的代码完成这些功能,它看起来并没有想象的复杂.</p></td>
    <td background="Tutorial_27_files/r.png"><img src="Tutorial_27_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_27_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_27_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_27_files/br.png" height="28" width="28"></td></tr></tbody></table>
<pre><font color="#aaffaa" size="3">void doShadowPass(glObject *o, float *lp)
{
	unsigned int	i, j, k, jj;
	unsigned int	p1, p2;
	sPoint			v1, v2;

	<font color="#ffffaa">//对模型中的每一个面</font>
	for (i=0; i<o->nPlanes;i++)
	{	
		<font color="#ffffaa">//如果面在灯光的前面</font>
		if (o-&gt;planes[i].visible)
		{
			<font color="#ffffaa">//对于被灯光照射的面的每一个相邻的面</font>
			for (j=0;j&lt;3;j++)
			{
				k = o-&gt;planes[i].neigh[j];
				<font color="#ffffaa">//如果面不存在,或不被灯光照射,那么这个边是边界</font>
				if ((!k) || (!o-&gt;planes[k-1].visible))
				{
					<font color="#ffffaa">// 获得面的两个顶点</font>
					p1 = o-&gt;planes[i].p[j];
					jj = (j+1)%3;
					p2 = o-&gt;planes[i].p[jj];

					<font color="#ffffaa">//计算边的顶点到灯光的方向,并放大100倍</font>
					v1.x = (o-&gt;points[p1].x - lp[0])*100;
					v1.y = (o-&gt;points[p1].y - lp[1])*100;
					v1.z = (o-&gt;points[p1].z - lp[2])*100;

					v2.x = (o-&gt;points[p2].x - lp[0])*100;
					v2.y = (o-&gt;points[p2].y - lp[1])*100;
					v2.z = (o-&gt;points[p2].z - lp[2])*100;
					
					<font color="#ffffaa">//绘制构成阴影体边界的面</font>
					glBegin(GL_TRIANGLE_STRIP);
						glVertex3f(o-&gt;points[p1].x,
									o-&gt;points[p1].y,
									o-&gt;points[p1].z);
						glVertex3f(o-&gt;points[p1].x + v1.x,
									o-&gt;points[p1].y + v1.y,
									o-&gt;points[p1].z + v1.z);

						glVertex3f(o-&gt;points[p2].x,
									o-&gt;points[p2].y,
									o-&gt;points[p2].z);
						glVertex3f(o-&gt;points[p2].x + v2.x,
									o-&gt;points[p2].y + v2.y,
									o-&gt;points[p2].z + v2.z);
					glEnd();
				}
			}
		}
	}

}
</o-></font>
</pre>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_27_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_27_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_27_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_27_files/l.png"><img src="Tutorial_27_files/l.png"></td>
    <td valign="top" width="100%">既然我们已经能绘制阴影了,那么我们开始绘制我们的场景吧</td>
    <td background="Tutorial_27_files/r.png"><img src="Tutorial_27_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_27_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_27_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_27_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
</font><pre><font color="#aaffaa" size="3">bool drawGLScene()
{
	GLmatrix16f Minv;
	GLvector4f wlp, lp;

	<font color="#ffffaa">// 清空缓存</font>
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

	glLoadIdentity();							<font color="#ffffaa">// 设置灯光,并绘制球</font>
	glTranslatef(0.0f, 0.0f, -20.0f);				
	glLightfv(GL_LIGHT1, GL_POSITION, LightPos);			
	glTranslatef(SpherePos[0], SpherePos[1], SpherePos[2]);		
	gluSphere(q, 1.5f, 32, 16);					</font></pre>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_27_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_27_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_27_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_27_files/l.png"><img src="Tutorial_27_files/l.png"></td>
    <td valign="top" width="100%">下面我们计算灯光在物体坐标系中的位置</td>
    <td background="Tutorial_27_files/r.png"><img src="Tutorial_27_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_27_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_27_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_27_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
</font><pre><font color="#aaffaa" size="3">	glLoadIdentity();						
	glRotatef(-yrot, 0.0f, 1.0f, 0.0f);				
	glRotatef(-xrot, 1.0f, 0.0f, 0.0f);				
	glTranslatef(-ObjPos[0], -ObjPos[1], -ObjPos[2]);		
	glGetFloatv(GL_MODELVIEW_MATRIX,Minv);				<font color="#ffffaa">// 计算从世界坐标系变化到物体坐标系中的坐标</font>
	lp[0] = LightPos[0];						<font color="#ffffaa">// 保存灯光的位置</font>
	lp[1] = LightPos[1];						
	lp[2] = LightPos[2];						
	lp[3] = LightPos[3];						

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -