void ZoneManager::Render(const RenderOptions& renderOptions, const ViewFrustum3d& viewFrustum)
{
   bool bDrawBoundingBox = renderOptions.Get(RenderOptions::optionTerrainZoneBoundingBox);
   bool bUseFrustumCulling = renderOptions.Get(RenderOptions::optionTerrainFrustumCulling);

   m_indexBuffer.Bind();

   // call all blocks to render themselves
   for (size_t i=0, iMax=m_vecRenderData.size(); i<iMax; i++)
   {
      if (bUseFrustumCulling)
      {
         unsigned int xzone, yzone;
         IndexToZone(i, xzone, yzone);

         ATLASSERT(xzone < c_uiNumZones);
         ATLASSERT(yzone < c_uiNumZones);

         const AABox& box1 = m_vecRenderData[i].GetBoundingBox();
         AABox box2;
         box2.UpdateBound(Vector3d(xzone * m_uiZoneSize, 0.0, yzone * m_uiZoneSize) + box1.Min());
         box2.UpdateBound(Vector3d(xzone * m_uiZoneSize, 0.0, yzone * m_uiZoneSize) + box1.Max());

         // check if given quad is visible
         if (ViewFrustum3d::resultOutside == viewFrustum.IsBoxInside(box2))
            continue;
      }

      m_vecRenderData[i].Render(m_indexBuffer, bDrawBoundingBox);
   }

   m_indexBuffer.Unbind();
}
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::RenderFrame(RenderOptions& options) const throw()
{
   // set front face to clockwise
   glPushAttrib(GL_POLYGON_BIT);
   glFrontFace(GL_CW);

   // enable backface culling
   glEnable(GL_CULL_FACE);
   glCullFace(GL_BACK);

   ATLASSERT(m_uiCurrentFrame < static_cast<unsigned int>(m_spModelData->m_iNumFrames));

   // render bounding box
   if (options.Get(RenderOptions::optionModelBoundingBox))
      RenderBoundingBox(m_uiCurrentFrame);

   m_spTexture->Bind();

   if (m_enRenderMode == renderDirect)
   {
      unsigned int uiPolycount = 0;
      RenderFramePercent(m_uiCurrentFrame, m_uiNextFrame, m_dPercentFrameDone, uiPolycount);

      OpenGL::CountPolygons(uiPolycount);
   }
   else
      if (m_enRenderMode == renderDisplayList ||
         m_enRenderMode == renderDisplayListOnDemandPrepare)
      {
      unsigned int uiStep = static_cast<unsigned int>(m_dPercentFrameDone * c_uiNumStepsPerFrame);
      if (uiStep >= c_uiNumStepsPerFrame)
         uiStep = c_uiNumStepsPerFrame - 1;

      unsigned int uiListIndex = m_uiCurrentFrame*c_uiNumStepsPerFrame + uiStep;

      if (m_enRenderMode == renderDisplayListOnDemandPrepare &&
         !m_spModelData->m_deqDisplayListPrepared[uiListIndex])
      {
         // prepare item
         const_cast<ModelDisplayState&>(*this).
            PrepareFrameStep(m_spModelData->m_frameDisplayLists, true, m_uiCurrentFrame, uiStep);

         m_spModelData->m_deqDisplayListPrepared[uiListIndex] = true;
      }
      else
      {
         // just call appropriate display list
         m_spModelData->m_frameDisplayLists.Call(uiListIndex);
      }

      OpenGL::CountPolygons(m_spModelData->m_uiDisplayListPolycount);
      }
      else
         ATLASSERT(false);

   glDisable(GL_TEXTURE_2D);

   glDisable(GL_CULL_FACE);
   glPopAttrib();
}
void ModelDisplayState::RenderAnimatedModelVertexBuffer(RenderOptions& options) const
{
   AnimatedModel3d& model = *m_spModel->GetAnimated();
   const Data& data = model.GetData();

   m_vbo.Bind();
   model.IndexBuffer().Bind();

   // render all groups
   for (size_t i=0, iMax=data.m_vecGroups.size(); i<iMax; i++)
   {
      const Group& group = data.m_vecGroups[i];

      BindMaterial(group);

      const GroupRenderData& renderData = model.GroupRenderDataVector()[i];

      model.IndexBuffer().RenderRange(renderData.m_range);

      OpenGL::CountPolygons(renderData.m_range.m_uiSize / 3);

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

   model.IndexBuffer().Unbind();
   m_vbo.Unbind();
}
void ModelRenderInstance::Render(RenderOptions& renderOptions)
{
   m_spDisplayState->Tick();

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

   if (renderOptions.Get(RenderOptions::optionModelFilled))
      glPolygonMode(GL_FRONT, GL_FILL);
   else
      glPolygonMode(GL_FRONT, GL_LINE);

   glPushMatrix();

   // position model
   Vector3d vPos = CalculatedPos();
   glTranslated(vPos.X(), vPos.Y(), vPos.Z());

   glRotated(m_dViewAngle, 0.0, 1.0, 0.0);

   double dTransparency = CalcPlayerTransparency();

   // blend model
   if (dTransparency < 1.0)
   {
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   }

   double dLuminance = m_bSelected ? 1.2 : 1.0;
   glColor4d(dLuminance, dLuminance, dLuminance, dTransparency);

   m_spDisplayState->Render(renderOptions);

   glPopMatrix();
}
void ModelDisplayState::Render(RenderOptions& options)
{
   if (options.Get(RenderOptions::optionModelJoints))
      OpenGL::RenderXyzAxes();

   if (!m_flagUploaded.IsSet())
      return;

   //RenderAnimatedModelImmediateMode(options);
   RenderAnimatedModelVertexBuffer(options);

   RenderStaticModels(options);

   // render joint lines and points
   if (options.Get(RenderOptions::optionModelJoints))
      RenderJoints();
}
void ModelDisplayState::RenderStaticModels(RenderOptions& options) const
{
   const std::vector<CompositeModel3d::StaticModelData>& vecStaticModels =
      m_spModel->StaticList();

   ATLASSERT(m_vecStaticModelTextures.size() == vecStaticModels.size());

   for (size_t i=0, iMax = vecStaticModels.size(); i<iMax; i++)
   {
      // enable model texture, if loaded
      if (m_vecStaticModelTextures[i] != NULL)
         m_vecStaticModelTextures[i]->Bind();

      // find mount point and matrix
      const CompositeModel3d::StaticModelData& data = vecStaticModels[i];

      ATLASSERT(data.m_iJointIndex >= 0);
      ATLASSERT(size_t(data.m_iJointIndex) < m_vecJointRenderData.size());

      size_t uiMountIndex = static_cast<size_t>(data.m_iJointIndex);

      Matrix4d matGlobal = m_vecJointRenderData[uiMountIndex].GlobalMatrix();
      matGlobal.Transpose();

      // transform current modelview matrix
      glPushMatrix();

      glMultMatrixd(matGlobal.Data());

      // render model
      data.m_spStatic->Render(options);

      // render mount point
      if (options.Get(RenderOptions::optionModelJoints))
         RenderMountPoint();

      glPopMatrix();
   }
}