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

📄 tutorial_44.htm

📁 如果你相信它就好好学学吧,同样这里也只是个入门
💻 HTM
📖 第 1 页 / 共 3 页
字号:
        <p>现在你在头脑里应该有了一个大慨地图像了吧。我们来说说何时我们应该绘制光晕,一般来说平时我们是看不见这些光晕的,只有当我们对准光源的时候才能看见这些。所以我们首先要获得视景体的数据,下面的函数可以帮我们完成这个功能。</p>
    </td>
    <td class="r"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td></tr></tbody></table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
  <tbody>
  <tr>
    <td class="bl"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
    <td class="bc" width="100%"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
    <td class="br"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td></tr></tbody></table>
<pre><span class="theme">// 获得当前视景体的6个平面方程的参数</span><br>void glCamera::UpdateFrustum()<br>{<br>    GLfloat   clip[16];<br>	GLfloat   proj[16];<br>    GLfloat   modl[16];<br>    GLfloat   t;</pre>
<p> <span class="theme">//返回投影矩阵</span><br>
  glGetFloatv( GL_PROJECTION_MATRIX, proj );</p>
<p> <span class="theme">//返回模型变换矩阵</span><br>
  glGetFloatv( GL_MODELVIEW_MATRIX, modl );</p>
<p> <span class="theme">//计算剪切矩阵,即上面两个矩阵的乘积</span><br>
  clip[ 0] = modl[ 0] * proj[ 0] + modl[ 1] * proj[ 4] + modl[ 2] * proj[ 8] + 
  modl[ 3] * proj[12];<br>
  clip[ 1] = modl[ 0] * proj[ 1] + modl[ 1] * proj[ 5] + modl[ 2] * proj[ 9] + 
  modl[ 3] * proj[13];<br>
  clip[ 2] = modl[ 0] * proj[ 2] + modl[ 1] * proj[ 6] + modl[ 2] * proj[10] + 
  modl[ 3] * proj[14];<br>
  clip[ 3] = modl[ 0] * proj[ 3] + modl[ 1] * proj[ 7] + modl[ 2] * proj[11] + 
  modl[ 3] * proj[15];</p>
<p> clip[ 4] = modl[ 4] * proj[ 0] + modl[ 5] * proj[ 4] + modl[ 6] * proj[ 8] 
  + modl[ 7] * proj[12];<br>
  clip[ 5] = modl[ 4] * proj[ 1] + modl[ 5] * proj[ 5] + modl[ 6] * proj[ 9] + 
  modl[ 7] * proj[13];<br>
  clip[ 6] = modl[ 4] * proj[ 2] + modl[ 5] * proj[ 6] + modl[ 6] * proj[10] + 
  modl[ 7] * proj[14];<br>
  clip[ 7] = modl[ 4] * proj[ 3] + modl[ 5] * proj[ 7] + modl[ 6] * proj[11] + 
  modl[ 7] * proj[15];</p>
<p> clip[ 8] = modl[ 8] * proj[ 0] + modl[ 9] * proj[ 4] + modl[10] * proj[ 8] 
  + modl[11] * proj[12];<br>
  clip[ 9] = modl[ 8] * proj[ 1] + modl[ 9] * proj[ 5] + modl[10] * proj[ 9] + 
  modl[11] * proj[13];<br>
  clip[10] = modl[ 8] * proj[ 2] + modl[ 9] * proj[ 6] + modl[10] * proj[10] + 
  modl[11] * proj[14];<br>
  clip[11] = modl[ 8] * proj[ 3] + modl[ 9] * proj[ 7] + modl[10] * proj[11] + 
  modl[11] * proj[15];</p>
<p> clip[12] = modl[12] * proj[ 0] + modl[13] * proj[ 4] + modl[14] * proj[ 8] 
  + modl[15] * proj[12];<br>
  clip[13] = modl[12] * proj[ 1] + modl[13] * proj[ 5] + modl[14] * proj[ 9] + 
  modl[15] * proj[13];<br>
  clip[14] = modl[12] * proj[ 2] + modl[13] * proj[ 6] + modl[14] * proj[10] + 
  modl[15] * proj[14];<br>
  clip[15] = modl[12] * proj[ 3] + modl[13] * proj[ 7] + modl[14] * proj[11] + 
  modl[15] * proj[15];</p>
<p> <span class="theme">//提取右面的平面方程系数</span><br>
  m_Frustum[0][0] = clip[ 3] - clip[ 0];<br>
  m_Frustum[0][1] = clip[ 7] - clip[ 4];<br>
  m_Frustum[0][2] = clip[11] - clip[ 8];<br>
  m_Frustum[0][3] = clip[15] - clip[12];<br>
  t = GLfloat(sqrt( m_Frustum[0][0] * m_Frustum[0][0] + m_Frustum[0][1] * m_Frustum[0][1] 
  + m_Frustum[0][2] * m_Frustum[0][2] ));<br>
  m_Frustum[0][0] /= t;<br>
  m_Frustum[0][1] /= t;<br>
  m_Frustum[0][2] /= t;<br>
  m_Frustum[0][3] /= t;</p>
<p> <span class="theme">//提取左面的平面方程系数</span><br>
  m_Frustum[1][0] = clip[ 3] + clip[ 0];<br>
  m_Frustum[1][1] = clip[ 7] + clip[ 4];<br>
  m_Frustum[1][2] = clip[11] + clip[ 8];<br>
  m_Frustum[1][3] = clip[15] + clip[12];<br>
  t = GLfloat(sqrt( m_Frustum[1][0] * m_Frustum[1][0] + m_Frustum[1][1] * m_Frustum[1][1] 
  + m_Frustum[1][2] * m_Frustum[1][2] ));<br>
  m_Frustum[1][0] /= t;<br>
  m_Frustum[1][1] /= t;<br>
  m_Frustum[1][2] /= t;<br>
  m_Frustum[1][3] /= t;</p>
<p> <span class="theme">//提取下面的平面方程系数</span><br>
  m_Frustum[2][0] = clip[ 3] + clip[ 1];<br>
  m_Frustum[2][1] = clip[ 7] + clip[ 5];<br>
  m_Frustum[2][2] = clip[11] + clip[ 9];<br>
  m_Frustum[2][3] = clip[15] + clip[13];<br>
  t = GLfloat(sqrt( m_Frustum[2][0] * m_Frustum[2][0] + m_Frustum[2][1] * m_Frustum[2][1] 
  + m_Frustum[2][2] * m_Frustum[2][2] ));<br>
  m_Frustum[2][0] /= t;<br>
  m_Frustum[2][1] /= t;<br>
  m_Frustum[2][2] /= t;<br>
  m_Frustum[2][3] /= t;</p>
<p> <span class="theme">//提取上面的平面方程系数</span><br>
  m_Frustum[3][0] = clip[ 3] - clip[ 1];<br>
  m_Frustum[3][1] = clip[ 7] - clip[ 5];<br>
  m_Frustum[3][2] = clip[11] - clip[ 9];<br>
  m_Frustum[3][3] = clip[15] - clip[13];<br>
  t = GLfloat(sqrt( m_Frustum[3][0] * m_Frustum[3][0] + m_Frustum[3][1] * m_Frustum[3][1] 
  + m_Frustum[3][2] * m_Frustum[3][2] ));<br>
  m_Frustum[3][0] /= t;<br>
  m_Frustum[3][1] /= t;<br>
  m_Frustum[3][2] /= t;<br>
  m_Frustum[3][3] /= t;</p>
<p> <span class="theme">//提取远面的平面方程系数</span><br>
  m_Frustum[4][0] = clip[ 3] - clip[ 2];<br>
  m_Frustum[4][1] = clip[ 7] - clip[ 6];<br>
  m_Frustum[4][2] = clip[11] - clip[10];<br>
  m_Frustum[4][3] = clip[15] - clip[14];<br>
  t = GLfloat(sqrt( m_Frustum[4][0] * m_Frustum[4][0] + m_Frustum[4][1] * m_Frustum[4][1] 
  + m_Frustum[4][2] * m_Frustum[4][2] ));<br>
  m_Frustum[4][0] /= t;<br>
  m_Frustum[4][1] /= t;<br>
  m_Frustum[4][2] /= t;<br>
  m_Frustum[4][3] /= t;</p>
<p> <span class="theme">//提取近面的平面方程系数</span><br>
  m_Frustum[5][0] = clip[ 3] + clip[ 2];<br>
  m_Frustum[5][1] = clip[ 7] + clip[ 6];<br>
  m_Frustum[5][2] = clip[11] + clip[10];<br>
  m_Frustum[5][3] = clip[15] + clip[14];<br>
  t = GLfloat(sqrt( m_Frustum[5][0] * m_Frustum[5][0] + m_Frustum[5][1] * m_Frustum[5][1] 
  + m_Frustum[5][2] * m_Frustum[5][2] ));<br>
  m_Frustum[5][0] /= t;<br>
  m_Frustum[5][1] /= t;<br>
  m_Frustum[5][2] /= t;<br>
  m_Frustum[5][3] /= t;<br>
  }</p>
<p></p>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
  <tbody>
  <tr>
    <td class="tl"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
    <td class="tc" width="100%"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="100%"></td>
    <td class="tr"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td></tr></tbody></table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
  <tbody>
  <tr>
    <td class="l"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
      <td class="back3" valign="top" width="100%">现在我们可以测试一个点或圆是否在视景体内了。下面的函数可以测试一个点是否在视景体内。</td>
    <td class="r"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td></tr></tbody></table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
  <tbody>
  <tr>
    <td class="bl"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
    <td class="bc" width="100%"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
    <td class="br"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td></tr></tbody></table>
<pre>BOOL glCamera::PointInFrustum(glPoint p)<br>{<br>	int i;<br><br>	for(i = 0; i &lt; 6; i++)<br>	{<br>		if(m_Frustum[i][0] * p.x + m_Frustum[i][1] * p.y + m_Frustum[i][2] * p.z + m_Frustum[i][3] &lt;= 0)<br>		{<br>			return(FALSE);<br>		}<br>	}<br>	return(TRUE);<br>}</pre>
<p></p>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
  <tbody>
  <tr>
    <td class="tl"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
    <td class="tc" width="100%"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="100%"></td>
    <td class="tr"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td></tr></tbody></table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
  <tbody>
  <tr>
    <td class="l"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
    <td class="back3" valign="top" width="100%"><p>下面的函数用来测试某个点是否位于当前场景物体的前面: </p>
        </td>
    <td class="r"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td></tr></tbody></table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
  <tbody>
  <tr>
    <td class="bl"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
    <td class="bc" width="100%"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
    <td class="br"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td></tr></tbody></table>
<pre>bool glCamera::IsOccluded(glPoint p)<br>{<br>	GLint viewport[4];						<br>	GLdouble mvmatrix[16], projmatrix[16];  <br>	GLdouble winx, winy, winz;				<br>	GLdouble flareZ;						<br>	GLfloat bufferZ;						</pre>
<p> glGetIntegerv (GL_VIEWPORT, viewport); <br>
  glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix); <br>
  glGetDoublev (GL_PROJECTION_MATRIX, projmatrix); </p>
<p> <span class="theme">// 返回顶点p在单位立方体中的位置</span><br>
  gluProject(p.x, p.y, p.z, mvmatrix, projmatrix, viewport, &amp;winx, &amp;winy, 
  &amp;winz);<br>
  flareZ = winz;</p>
<p> <span class="theme">// 读取点(winx,winy)的深度坐标</span><br>
  glReadPixels(winx, winy,1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &amp;bufferZ);</p>
<p> <span class="theme">// 如果深度坐标小于点的坐标,则返回true</span><br>
  if (bufferZ &lt; flareZ)<br>
  return true;<br>
  <span class="theme">//否则返回false</span><br>
  else<br>
  return false;<br>
  }</p>
<p></p>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
  <tbody>
  <tr>
    <td class="tl"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
    <td class="tc" width="100%"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="100%"></td>
    <td class="tr"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td></tr></tbody></table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
  <tbody>
  <tr>
    <td class="l"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
      <td class="back3" valign="top" width="100%">我
们通过检测光源是否正对我们的视线来决定是否绘制光晕,但如果你的视点超过了光源的位置,则会发生看不见光晕的现象。为了避免这种现象,我们在移动视点的
使用,也相应的移动我们的光源。为了在视点和光源之间绘制多个光晕,我们需要计算之间的向量,下面的代码完成这个功能:</td>
    <td class="r"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td></tr></tbody></table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
  <tbody>
  <tr>
    <td class="bl"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
    <td class="bc" width="100%"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
    <td class="br"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td></tr></tbody></table>
<pre><span class="theme">//下面的函数完成具体的渲染光晕的任务</span><br>void glCamera::RenderLensFlare()<br>{<br>	GLfloat Length = 0.0f;</pre>
<p> <span class="theme">// 如果我们的光源在我们的视线范围内,则绘制它</span><br>
  if(SphereInFrustum(m_LightSourcePos, 1.0f) == TRUE)<br>
  {<br>
  vLightSourceToCamera = m_Position - m_LightSourcePos; <span class="theme">// 
  计算光源到我们视线的距离</span><br>
  Length = vLightSourceToCamera.Magnitude(); </p>
<p> <span class="theme">//下面三个函数计算光源位置到光晕结束位置之间的向量</span><br>
  ptIntersect = m_DirectionVector * Length; <br>
  ptIntersect += m_Position;<br>
  vLightSourceToIntersect = ptIntersect - m_LightSourcePos; <br>
  Length = vLightSourceToIntersect.Magnitude(); <br>
  vLightSourceToIntersect.Normalize(); <br>
  <br>
  glEnable(GL_BLEND); <br>
  glBlendFunc(GL_SRC_ALPHA, GL_ONE); <br>
  glDisable(GL_DEPTH_TEST); <br>
  glEnable(GL_TEXTURE_2D);</p>
<pre>&nbsp;
</pre>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
  <tbody>
  <tr>
    <td class="tl"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
    <td class="tc" width="100%"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="100%"></td>
    <td class="tr"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td></tr></tbody></table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
  <tbody>
  <tr>
    <td class="l"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
    <td class="back3" valign="top" width="100%">
      <p>首先我们需要找到光源位置和视点位置之间的向量,接下来我们需要在视线的方向设置一个插值点,这个点的距离必须和光源位置和视点位置之间的距离相等。完成以后,我们找出可以产生光晕的方向,即下图红线的方向,在这个线上我们可以绘制我们的光晕。</p>
      <p>
        </p><center>
          <img src="Tutorial_44_files/illustration.jpg" height="512" width="512">
        </center>
          <br>
      <p></p>
    </td>
    <td class="r"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td></tr></tbody></table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
  <tbody>
  <tr>
    <td class="bl"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
    <td class="bc" width="100%"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td>
    <td class="br"><img alt="" src="Tutorial_44_files/blank1.gif" height="28" width="28"></td></tr></tbody></table>
<pre>		if (!IsOccluded(m_LightSourcePos))	<span class="theme">//如果光晕可见</span><br>		{<br>			<span class="theme">// 渲染中间的光晕</span><br>			RenderBigGlow(0.60f, 0.60f, 0.8f, 1.0f, m_LightSourcePos, 16.0f);<br>			RenderStreaks(0.60f, 0.60f, 0.8f, 1.0f, m_LightSourcePos, 16.0f);<br>			RenderGlow(0.8f, 0.8f, 1.0f, 0.5f, m_LightSourcePos, 3.5f);</pre>
<p> <span class="theme">//绘制到光晕结束位置的0.1处的光晕</span><br>
  pt = vLightSourceToIntersect * (Length * 0.1f); <br>
  pt += m_LightSourcePos; <br>
  RenderGlow(0.9f, 0.6f, 0.4f, 0.5f, pt, 0.6f); </p>
<p> <span class="theme">//绘制到光晕结束位置的0.15处的光晕</span><br>
  pt = vLightSourceToIntersect * (Length * 0.15f); <br>
  pt += m_LightSourcePos; <br>
  RenderHalo(0.8f, 0.5f, 0.6f, 0.5f, pt, 1.7f); <br>
  <br>
  <span class="theme">//绘制到光晕结束位置的0.175处的光晕</span><br>

⌨️ 快捷键说明

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