void ModelDisplayState::RenderAnimatedModelImmediateMode(RenderOptions& options) const
{
   AnimatedModel3d& model = *m_spModel->GetAnimated();
   const Data& data = model.GetData();

   AABox boundingBox;

   // now render all groups, using vertex and normals from joint render data
   for (const Group& group : data.m_vecGroups)
   {
      BindMaterial(group);

      glBegin(GL_TRIANGLES);

      for (size_t uiTriangleIndex : group.m_vecTriangleIndices)
      {
         ATLASSERT(uiTriangleIndex < data.m_vecTriangles.size());

         const Triangle& t = data.m_vecTriangles[uiTriangleIndex];
         for (unsigned int v=0; v<3; v++)
         {
            glTexCoord2fv(t.aTex[v].Data());

            size_t vertexIndex = t.auiVertexIndices[v];
            const Vertex& vert = data.m_vecVertices[vertexIndex];

            Vector3d vNormal = t.aNormals[v];
            model.TransformNormal(vert, m_vecJointRenderData, vNormal);

            glNormal3dv(vNormal.Data());

            Vector3d vVertex = vert.m_vPos;
            model.TransformVertex(vert, m_vecJointRenderData, vVertex);
            glVertex3dv(vVertex.Data());

            if (options.Get(RenderOptions::optionModelBoundingBox))
               boundingBox.UpdateBound(vVertex);
         }
      }

      glEnd();

      OpenGL::CountPolygons(group.m_vecTriangleIndices.size());

      if (options.Get(RenderOptions::optionModelNormals))
         RenderModelNormals(group);
   }

   if (options.Get(RenderOptions::optionModelBoundingBox))
      OpenGL::RenderBoundingBox(boundingBox.Min(), boundingBox.Max());
}
void ModelDisplayState::RenderFramePercent(unsigned int uiNumFrame, unsigned int uiNextFrame,
   double dPercent, unsigned int& uiPolycount) const throw()
{
   const std::vector<int>& vecGlcmds = m_spModelData->m_vecGlcmds;

   for (size_t i = 0, iMax = vecGlcmds.size(); i<iMax && vecGlcmds[i] != 0; i++)
   {
      int iCmd = vecGlcmds[i];
      if (iCmd < 0)
      {
         glBegin(GL_TRIANGLE_FAN);
         iCmd = -iCmd;
      }
      else
      {
         glBegin(GL_TRIANGLE_STRIP);
      }

      // count polygons:
      // a fan or strip initially needs 3 points for a triangle, and one point for each next triangle
      if (iCmd > 6)
         uiPolycount += iCmd / 3 - 2;

      ATLASSERT(i + iCmd * 3 < iMax);

      // parse all OpenGL commands of this group
      for (int j = 0; j<iCmd; j++, i += 3)
      {
         // glcmds[0] : final S texture coord.
         // glcmds[1] : final T texture coord.
         // glcmds[2] : vertex index to draw
         GLCommand* pGLcmd = reinterpret_cast<GLCommand*>((void*)&vecGlcmds[i + 1]);
         int index = pGLcmd->index;

         ATLASSERT(index < m_spModelData->m_iNumXyz);
         Vector3d& v1 = m_spModelData->m_vecVertices[m_spModelData->m_iNumXyz * uiNumFrame + index];
         Vector3d& v2 = m_spModelData->m_vecVertices[m_spModelData->m_iNumXyz * uiNextFrame + index];
         int iNormalIndex = m_spModelData->m_vecLightNormals[index];

         // send texture coords. to OpenGL
         glTexCoord2f(pGLcmd->s, pGLcmd->t);

         // send normal vector to OpenGL
         ATLASSERT(iNormalIndex < sizeof(s_anorms) / sizeof(*s_anorms));
         glNormal3fv(s_anorms[iNormalIndex]);

         Vector3d vDist = v2 - v1;
         vDist *= dPercent;

         Vector3d v = v1 + vDist;

         glVertex3dv(v.Data());
      }

      glEnd();
   }
}
void ModelDisplayState::RenderModelNormals(const Group& group) const
{
   AnimatedModel3d& model = *m_spModel->GetAnimated();
   const Data& data = model.GetData();

   OpenGL::PushedAttributes attrib(GL_LINE_BIT | GL_ENABLE_BIT | GL_CURRENT_BIT);

   glDisable(GL_LIGHTING);
   glDisable(GL_DEPTH_TEST);
   glDisable(GL_TEXTURE_2D);

   glLineWidth(2.0f);

   glBegin(GL_LINES);

   for (size_t uiTriangleIndex : group.m_vecTriangleIndices)
   {
      ATLASSERT(uiTriangleIndex < data.m_vecTriangles.size());

      const Triangle& t = data.m_vecTriangles[uiTriangleIndex];
      for (unsigned int v=0; v<3; v++)
      {
         size_t vertexIndex = t.auiVertexIndices[v];
         const Vertex& vert = data.m_vecVertices[vertexIndex];

         Vector3d vVertex = vert.m_vPos;
         model.TransformVertex(vert, m_vecJointRenderData, vVertex);

         Vector3d vNormal = t.aNormals[v];
         model.TransformNormal(vert, m_vecJointRenderData, vNormal);

         vNormal.Normalize();
         vNormal *= 0.1;
         vNormal += vVertex;

         glVertex3dv(vVertex.Data());
         glVertex3dv(vNormal.Data());
      }
   }

   glEnd();
}
void PolygonGraphRenderer::PreparePolygons()
{
   m_displayListPolygons.Init();

   m_displayListPolygons.Open();

   for (PolygonGraph::CenterPtr p : m_graph.m_centers)
   {
      std::vector<PolygonGraph::CornerPtr> vecCorners = p->corners;

      // order them clockwise
      std::sort(vecCorners.begin(), vecCorners.end(),
         PolygonGraph::CornerSorter(p->point));

      // draw triangle fan
      glBegin(GL_TRIANGLE_FAN);

      Color c = PolygonGraph::ColorByBiomeType(p->enBiomeType);
      //Color c = PolygonGraph::ColorByTerrainType(p->enTerrainType);
      //Color c = PolygonGraph::ColorByElevation(p->elevation);
      //Color c = PolygonGraph::ColorByMoisture(p->moisture);


      glColor3ubv(c.m_color);

      // normal
      ATLASSERT(vecCorners.size() >= 2);
      Vector3d center(p->point.X(), p->elevation * c_dElevationScaleFactor, p->point.Y());
      Vector3d p1(vecCorners[0]->point.X(), vecCorners[0]->elevation * c_dElevationScaleFactor, vecCorners[0]->point.Y());
      Vector3d p2(vecCorners[1]->point.X(), vecCorners[1]->elevation * c_dElevationScaleFactor, vecCorners[1]->point.Y());
      Vector3d normal;
      normal.Cross(center-p1, center-p2);
      normal.Normalize();

      glNormal3dv(normal.Data());

      // center
      glVertex3d(p->point.X(), p->elevation * c_dElevationScaleFactor, p->point.Y());

      for (PolygonGraph::CornerPtr q : vecCorners)
         glVertex3d(q->point.X(), q->elevation * c_dElevationScaleFactor, q->point.Y());

      glVertex3d(vecCorners[0]->point.X(), vecCorners[0]->elevation * c_dElevationScaleFactor,
         vecCorners[0]->point.Y());

      glEnd();
   }

   m_displayListPolygons.Close();
}