glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清屏 glLoadIdentity(); // 将矩阵清为单位矩阵 glPushMatrix(); // 压栈 glTranslatef(0.0, 0.0, -5000.0); // 平移到屏幕中心 glRotatef(0.0f, 1.0f, 0.0f, 0.0f); // 旋转 glRotatef(m_fxAngle, 1.0f, 0.0f, 0.0f); glRotatef(m_fzAngle, 0.0f, 0.0f, 1.0f); glTranslatef(m_fXOff, m_fYOff, m_fZOff); // 平移 glScalef(m_fScale, m_fScale, m_fScale); // 缩放 if (m_nViewMode == 0 || m_bTexture == FALSE) // 执行显示列表 glCallList(Terrain); glPopMatrix(); // 出栈 glFlush(); // 强制绘图完成 SwapBuffers(wglGetCurrentDC()); // 交换缓存 |
void glTranslated(GLdouble x, GLdouble y, GLdouble z ); void glTranslatef(GLfloat x, GLfloat y, GLfloat z ); void glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); void glScaled(GLdouble x, GLdouble y, GLdouble z); void glScalef(GLfloat x, GLfloat y, GLfloat z); |
switch(nChar) { // 漫游控制 case VK_UP: m_fYOff += 20; break; case VK_DOWN: m_fYOff -= 20; break; case VK_LEFT: m_fXOff -= 20; break; case VK_RIGHT: m_fXOff += 20; break; case 87: // W m_fxAngle++; break; case 83: // S m_fxAngle--; break; case 65: // A m_fzAngle++; break; case 68: // D m_fzAngle--; break; case 70: // F 前进 m_fScale += 0.05f; break; case 66: // B 后退 if (m_fScale > 0.05f) m_fScale -= 0.05f; break; default: break; } ReDraw(); // 重绘场景 |
m_LeftButtonDown = TRUE; // 开始鼠标漫游 m_LeftDownPos = point; |
if(m_LeftButtonDown) { // 正在鼠标漫游 m_fzAngle -= (float)(m_LeftDownPos.x - point.x)/3.0f; m_fxAngle -= (float)(m_LeftDownPos.y - point.y)/3.0f; m_LeftDownPos = point; ReDraw(); // 重绘场景 } |
m_LeftButtonDown = FALSE; // 结束鼠标漫游 |
上图为上述代码实现的对同一地景模型的不同角度观察结果图。
高差缩放与网格缩放处理
并非所有的场景都是起伏较大的,对于那些起伏不是很明显的地形,建模出来后可能就是一块平板,为了能够清楚的看出其地形走势,需要通过高差缩放来放大其各网格节点间的高程差距。这部分功能实现起来非常简单,只需将m_pDemH指向的高程数据缓冲区中的数据取值做相应的缩放处理并在重新计算法向量和初始化列表后重绘场景即可:
if (dlg.m_fValue > 0) { m_fHRate *= dlg.m_fValue; for (int i = 0; i < m_nHSize; i++) m_pDemH[i] = (int)(dlg.m_fValue * m_pDemH[i]); }else{ for (int i = 0; i < m_nHSize; i++) m_pDemH[i] = (int)(m_pDemH[i] / m_fHRate); m_fHRate = 1.0f; } |
// 加大网络间隔(缩小时除以2) m_nInterval *= 2; DemHeader.interval = (float)m_nInterval; for (int i = 0; i < m_nDemY; i++) { for (int j = 0; j < m_nDemX; j++) { m_pDemX[m_nDemX * i + j] = m_nInterval * j - (m_nDemX / 2) * m_nInterval; m_pDemY[m_nDemX * i + j] = m_nInterval * i - (m_nDemY / 2) * m_nInterval; } } |