Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tgl.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzExt includes
Toshihiro Shimizu 890ddd
#include "ext/ttexturesstorage.h"
Toshihiro Shimizu 890ddd
#include "ext/plasticdeformerstorage.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "tcg/tcg_iterator_ops.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "ext/meshutils.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************************
Toshihiro Shimizu 890ddd
//    Templated drawing functions
Toshihiro Shimizu 890ddd
//********************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct NoColorFunction {
Shinya Kitaoka 120a6e
  void faceColor(int f, int m) {}
Shinya Kitaoka 120a6e
  void edgeColor(int e, int m) {}
Shinya Kitaoka 120a6e
  void vertexColor(int v, int m) {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
template 
Shinya Kitaoka 120a6e
          typename ColorFunction>
Shinya Kitaoka 120a6e
inline void tglDrawEdges(const TTextureMesh &mesh,
Shinya Kitaoka 120a6e
                         const VerticesContainer &vertices,
Shinya Kitaoka 120a6e
                         ColorFunction colorFunction) {
Shinya Kitaoka 120a6e
  // Draw the mesh wireframe
Shinya Kitaoka 120a6e
  glBegin(GL_LINES);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TTextureMesh::edges_container::const_iterator et, eEnd = mesh.edges().end();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (et = mesh.edges().begin(); et != eEnd; ++et) {
Shinya Kitaoka 120a6e
    const TTextureMesh::edge_type &ed = *et;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int v0 = ed.vertex(0), v1 = ed.vertex(1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    const PointType &p0 = vertices[v0];
Shinya Kitaoka 120a6e
    const PointType &p1 = vertices[v1];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    colorFunction.edgeColor(et.index(), -1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    colorFunction.vertexColor(v0, -1);
Shinya Kitaoka 120a6e
    glVertex2d(tcg::point_traits<pointtype>::x(p0),</pointtype>
Shinya Kitaoka 120a6e
               tcg::point_traits<pointtype>::y(p0));</pointtype>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    colorFunction.vertexColor(v1, -1);
Shinya Kitaoka 120a6e
    glVertex2d(tcg::point_traits<pointtype>::x(p1),</pointtype>
Shinya Kitaoka 120a6e
               tcg::point_traits<pointtype>::y(p1));</pointtype>
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glEnd();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename colorfunction=""></typename>
Shinya Kitaoka 120a6e
inline void tglDrawFaces(const TMeshImage &meshImage,
Shinya Kitaoka 120a6e
                         ColorFunction colorFunction) {
Shinya Kitaoka 120a6e
  glBegin(GL_TRIANGLES);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int m, mCount = meshImage.meshes().size();
Shinya Kitaoka 120a6e
  for (m = 0; m != mCount; ++m) {
Shinya Kitaoka 120a6e
    const TTextureMesh &mesh                  = *meshImage.meshes()[m];
Shinya Kitaoka 120a6e
    const tcg::list<ttexturevertex> &vertices = mesh.vertices();</ttexturevertex>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // Draw the mesh wireframe
Shinya Kitaoka 120a6e
    TTextureMesh::faces_container::const_iterator ft, fEnd = mesh.faces().end();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    for (ft = mesh.faces().begin(); ft != fEnd; ++ft) {
Shinya Kitaoka 120a6e
      int v0, v1, v2;
Shinya Kitaoka 120a6e
      mesh.faceVertices(ft.index(), v0, v1, v2);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      const TTextureVertex &p0 = vertices[v0];
Shinya Kitaoka 120a6e
      const TTextureVertex &p1 = vertices[v1];
Shinya Kitaoka 120a6e
      const TTextureVertex &p2 = vertices[v2];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      colorFunction.faceColor(ft.index(), m);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      colorFunction.vertexColor(v0, m), glVertex2d(p0.P().x, p0.P().y);
Shinya Kitaoka 120a6e
      colorFunction.vertexColor(v1, m), glVertex2d(p1.P().x, p1.P().y);
Shinya Kitaoka 120a6e
      colorFunction.vertexColor(v2, m), glVertex2d(p2.P().x, p2.P().y);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glEnd();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename colorfunction=""></typename>
Shinya Kitaoka 120a6e
inline void tglDrawFaces(const TMeshImage &meshImage,
Shinya Kitaoka 120a6e
                         const PlasticDeformerDataGroup *group,
Shinya Kitaoka 120a6e
                         ColorFunction colorFunction) {
Shinya Kitaoka 120a6e
  glBegin(GL_TRIANGLES);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Draw faces according to the group's sorted faces list
Shinya Kitaoka 120a6e
  typedef std::vector<std::pair<int, int="">> SortedFacesVector;</std::pair<int,>
Shinya Kitaoka 6f0974
Shinya Kitaoka 120a6e
  const SortedFacesVector &sortedFaces     = group->m_sortedFaces;
Shinya Kitaoka 120a6e
  const std::vector<ttexturemeshp> &meshes = meshImage.meshes();</ttexturemeshp>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int m = -1;
Shinya Kitaoka 120a6e
  const TTextureMesh *mesh;
Shinya Kitaoka 120a6e
  const double *dstCoords;
Shinya Kitaoka 6f0974
Shinya Kitaoka 120a6e
  int v0, v1, v2;
Shinya Kitaoka 6f0974
Shinya Kitaoka 120a6e
  // Draw each face individually. Change tile and mesh data only if they change
Shinya Kitaoka 120a6e
  SortedFacesVector::const_iterator sft, sfEnd(sortedFaces.end());
Shinya Kitaoka 120a6e
  for (sft = sortedFaces.begin(); sft != sfEnd; ++sft) {
Shinya Kitaoka 120a6e
    int f = sft->first, m_ = sft->second;
Shinya Kitaoka 6f0974
Shinya Kitaoka 120a6e
    if (m != m_) {
Shinya Kitaoka 120a6e
      m = m_;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      mesh      = meshes[m].getPointer();
Shinya Kitaoka 120a6e
      dstCoords = group->m_datas[m].m_output.get();
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    mesh->faceVertices(f, v0, v1, v2);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    const double *d0 = dstCoords + (v0 << 1), *d1 = dstCoords + (v1 << 1),
Shinya Kitaoka 120a6e
                 *d2 = dstCoords + (v2 << 1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    colorFunction.faceColor(f, m);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    colorFunction.vertexColor(v0, m), glVertex2d(*d0, *(d0 + 1));
Shinya Kitaoka 120a6e
    colorFunction.vertexColor(v1, m), glVertex2d(*d1, *(d1 + 1));
Shinya Kitaoka 120a6e
    colorFunction.vertexColor(v2, m), glVertex2d(*d2, *(d2 + 1));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glEnd();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************************
Toshihiro Shimizu 890ddd
//    Mesh Image Utility  functions implementation
Toshihiro Shimizu 890ddd
//********************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void transform(const TMeshImageP &meshImage, const TAffine &aff) {
Shinya Kitaoka 120a6e
  const std::vector<ttexturemeshp> &meshes = meshImage->meshes();</ttexturemeshp>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int m, mCount = meshes.size();
Shinya Kitaoka 120a6e
  for (m = 0; m != mCount; ++m) {
Shinya Kitaoka 120a6e
    TTextureMesh &mesh = *meshes[m];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    tcg::list<ttexturemesh::vertex_type> &vertices = mesh.vertices();</ttexturemesh::vertex_type>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    tcg::list<ttexturemesh::vertex_type>::iterator vt, vEnd(vertices.end());</ttexturemesh::vertex_type>
Shinya Kitaoka 120a6e
    for (vt = vertices.begin(); vt != vEnd; ++vt) vt->P() = aff * vt->P();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void tglDrawEdges(const TMeshImage &mi, const PlasticDeformerDataGroup *group) {
Shinya Kitaoka 120a6e
  const std::vector<ttexturemeshp> &meshes = mi.meshes();</ttexturemeshp>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int m, mCount = meshes.size();
Shinya Kitaoka 120a6e
  if (group) {
Shinya Kitaoka 120a6e
    for (m = 0; m != mCount; ++m)
Shinya Kitaoka 120a6e
      tglDrawEdges<const *,="" nocolorfunction="" tpointd="" tpointd,="">(</const>
Shinya Kitaoka 120a6e
          *meshes[m], (const TPointD *)group->m_datas[m].m_output.get(),
Shinya Kitaoka 120a6e
          NoColorFunction());
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    for (m = 0; m != mCount; ++m) {
Shinya Kitaoka 120a6e
      const TTextureMesh &mesh = *meshes[m];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      tglDrawEdges<tcg::list<ttexturemesh::vertex_type>, TTextureVertex,</tcg::list<ttexturemesh::vertex_type>
Shinya Kitaoka 120a6e
                   NoColorFunction>(mesh, mesh.vertices(), NoColorFunction());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void tglDrawFaces(const TMeshImage &image,
Shinya Kitaoka 120a6e
                  const PlasticDeformerDataGroup *group) {
Shinya Kitaoka 120a6e
  if (group)
Shinya Kitaoka 120a6e
    tglDrawFaces(image, group, NoColorFunction());
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    tglDrawFaces(image, NoColorFunction());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************************
Toshihiro Shimizu 890ddd
//    Colored drawing functions
Toshihiro Shimizu 890ddd
//********************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct LinearColorFunction {
Shinya Kitaoka 120a6e
  typedef double (*ValueFunc)(const LinearColorFunction *cf, int m,
Shinya Kitaoka 120a6e
                              int primitive);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  const TMeshImage &m_meshImg;
Shinya Kitaoka 120a6e
  const PlasticDeformerDataGroup *m_group;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double m_min, m_max;
Shinya Kitaoka 120a6e
  double *m_cMin, *m_cMax;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double m_dt;
Shinya Kitaoka 120a6e
  bool m_degenerate;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ValueFunc m_func;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  LinearColorFunction(const TMeshImage &meshImg,
Shinya Kitaoka 120a6e
                      const PlasticDeformerDataGroup *group, double min,
Shinya Kitaoka 120a6e
                      double max, double *cMin, double *cMax, ValueFunc func)
Shinya Kitaoka 120a6e
      : m_meshImg(meshImg)
Shinya Kitaoka 120a6e
      , m_group(group)
Shinya Kitaoka 120a6e
      , m_min(min)
Shinya Kitaoka 120a6e
      , m_max(max)
Shinya Kitaoka 120a6e
      , m_cMin(cMin)
Shinya Kitaoka 120a6e
      , m_cMax(cMax)
Shinya Kitaoka 120a6e
      , m_dt(max - min)
Shinya Kitaoka 120a6e
      , m_degenerate(m_dt < 1e-4)
Shinya Kitaoka 120a6e
      , m_func(func) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void operator()(int primitive, int m) {
Shinya Kitaoka 120a6e
    if (m_degenerate) {
Shinya Kitaoka 120a6e
      glColor4d(0.5 * (m_cMin[0] + m_cMax[0]), 0.5 * (m_cMin[1] + m_cMax[1]),
Shinya Kitaoka 120a6e
                0.5 * (m_cMin[2] + m_cMax[2]), 0.5 * (m_cMin[3] + m_cMax[3]));
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    double val = m_func(this, m, primitive);
Shinya Kitaoka 120a6e
    double t = (val - m_min) / m_dt, one_t = (m_max - val) / m_dt;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    glColor4d(
Shinya Kitaoka 120a6e
        one_t * m_cMin[0] + t * m_cMax[0], one_t * m_cMin[1] + t * m_cMax[1],
Shinya Kitaoka 120a6e
        one_t * m_cMin[2] + t * m_cMax[2], one_t * m_cMin[3] + t * m_cMax[3]);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
struct LinearVertexColorFunction final : public LinearColorFunction,
Shinya Kitaoka d1f6c4
                                         public NoColorFunction {
Shinya Kitaoka 120a6e
  LinearVertexColorFunction(const TMeshImage &meshImg,
Shinya Kitaoka 120a6e
                            const PlasticDeformerDataGroup *group, double min,
Shinya Kitaoka 120a6e
                            double max, double *cMin, double *cMax,
Shinya Kitaoka 120a6e
                            ValueFunc func)
Shinya Kitaoka 120a6e
      : LinearColorFunction(meshImg, group, min, max, cMin, cMax, func) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void vertexColor(int v, int m) { operator()(v, m); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
struct LinearFaceColorFunction final : public LinearColorFunction,
Shinya Kitaoka d1f6c4
                                       public NoColorFunction {
Shinya Kitaoka 120a6e
  LinearFaceColorFunction(const TMeshImage &meshImg,
Shinya Kitaoka 120a6e
                          const PlasticDeformerDataGroup *group, double min,
Shinya Kitaoka 120a6e
                          double max, double *cMin, double *cMax,
Shinya Kitaoka 120a6e
                          ValueFunc func)
Shinya Kitaoka 120a6e
      : LinearColorFunction(meshImg, group, min, max, cMin, cMax, func) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void faceColor(int v, int m) { operator()(v, m); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void tglDrawSO(const TMeshImage &image, double minColor[4], double maxColor[4],
Shinya Kitaoka 120a6e
               const PlasticDeformerDataGroup *group, bool deformedDomain) {
Shinya Kitaoka 120a6e
  struct locals {
Shinya Kitaoka 120a6e
    static double returnSO(const LinearColorFunction *cf, int m, int f) {
Shinya Kitaoka 120a6e
      return cf->m_group->m_datas[m].m_so[f];
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double min = 0.0, max = 0.0;
Shinya Kitaoka 120a6e
  if (group) min = group->m_soMin, max = group->m_soMax;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  LinearFaceColorFunction colorFunction(image, group, min, max, minColor,
Shinya Kitaoka 120a6e
                                        maxColor, locals::returnSO);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (group && deformedDomain)
Shinya Kitaoka 120a6e
    tglDrawFaces(image, group, colorFunction);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    tglDrawFaces(image, colorFunction);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void tglDrawRigidity(const TMeshImage &image, double minColor[4],
Shinya Kitaoka 120a6e
                     double maxColor[4], const PlasticDeformerDataGroup *group,
Shinya Kitaoka 120a6e
                     bool deformedDomain) {
Shinya Kitaoka 120a6e
  struct locals {
Shinya Kitaoka 120a6e
    static double returnRigidity(const LinearColorFunction *cf, int m, int v) {
Shinya Kitaoka 120a6e
      return cf->m_meshImg.meshes()[m]->vertex(v).P().rigidity;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  LinearVertexColorFunction colorFunction(image, group, 1.0, 1e4, minColor,
Shinya Kitaoka 120a6e
                                          maxColor, locals::returnRigidity);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (group && deformedDomain)
Shinya Kitaoka 120a6e
    tglDrawFaces(image, group, colorFunction);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    tglDrawFaces(image, colorFunction);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//***********************************************************************************************
Toshihiro Shimizu 890ddd
//    Texturized drawing  implementation
Toshihiro Shimizu 890ddd
//***********************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void tglDraw(const TMeshImage &meshImage, const DrawableTextureData &texData,
Shinya Kitaoka 120a6e
             const TAffine &meshToTexAff,
Shinya Kitaoka 120a6e
             const PlasticDeformerDataGroup &group) {
Shinya Kitaoka 120a6e
  typedef MeshTexturizer::TextureData::TileData TileData;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Prepare OpenGL
Shinya Kitaoka 120a6e
  glPushAttrib(GL_COLOR_BUFFER_BIT | GL_LINE_BIT |
Shinya Kitaoka 120a6e
               GL_HINT_BIT);  // Preserve original status bits
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glEnable(GL_BLEND);
shun-iwasawa ecfcc0
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Shinya Kitaoka 120a6e
  glEnable(GL_LINE_SMOOTH);
Shinya Kitaoka 120a6e
  glLineWidth(1.0f);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Prepare variables
Shinya Kitaoka 120a6e
  const std::vector<ttexturemeshp> &meshes = meshImage.meshes();</ttexturemeshp>
Shinya Kitaoka 120a6e
  const TTextureMesh *mesh;
Shinya Kitaoka 6f0974
Shinya Kitaoka 120a6e
  typedef std::vector<std::pair<int, int="">> SortedFacesVector;</std::pair<int,>
Shinya Kitaoka 120a6e
  const SortedFacesVector &sortedFaces = group.m_sortedFaces;
Shinya Kitaoka 6f0974
Shinya Kitaoka 120a6e
  const MeshTexturizer::TextureData *td = texData.m_textureData;
Shinya Kitaoka 120a6e
  int t, tCount = td->m_tileDatas.size();
Shinya Kitaoka 6f0974
Shinya Kitaoka 120a6e
  GLuint texId = -1;
Shinya Kitaoka 120a6e
  int m        = -1;
Shinya Kitaoka 120a6e
  const double *dstCoords;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int v0, v1, v2;
Shinya Kitaoka 120a6e
  int e1ovi, e2ovi;  // Edge X's Other Vertex Index (see below)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Prepare each tile's affine
Shinya Kitaoka 120a6e
  std::vector<taffine> tileAff(tCount);</taffine>
Shinya Kitaoka 120a6e
  for (t = 0; t != tCount; ++t) {
Shinya Kitaoka 120a6e
    const TileData &tileData = td->m_tileDatas[t];
Shinya Kitaoka 120a6e
    const TRectD &tileRect   = tileData.m_tileGeometry;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    tileAff[t] = TScale(1.0 / (tileRect.x1 - tileRect.x0),
Shinya Kitaoka 120a6e
                        1.0 / (tileRect.y1 - tileRect.y0)) *
Shinya Kitaoka 120a6e
                 TTranslation(-tileRect.x0, -tileRect.y0) * meshToTexAff;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Draw each face individually, according to the group's sorted faces list.
Shinya Kitaoka 120a6e
  // Change tile and mesh data only if they change - improves performance
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  SortedFacesVector::const_iterator sft, sfEnd(sortedFaces.end());
Shinya Kitaoka 120a6e
  for (sft = sortedFaces.begin(); sft != sfEnd; ++sft) {
Shinya Kitaoka 120a6e
    int f = sft->first, m_ = sft->second;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m != m_) {
Shinya Kitaoka 120a6e
      // Change mesh if different from current
Shinya Kitaoka 120a6e
      m = m_;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      mesh      = meshes[m].getPointer();
Shinya Kitaoka 120a6e
      dstCoords = group.m_datas[m].m_output.get();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Draw each face
Shinya Kitaoka 120a6e
    const TTextureMesh::face_type &fc = mesh->face(f);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    const TTextureMesh::edge_type &ed0 = mesh->edge(fc.edge(0)),
Shinya Kitaoka 120a6e
                                  &ed1 = mesh->edge(fc.edge(1)),
Shinya Kitaoka 120a6e
                                  &ed2 = mesh->edge(fc.edge(2));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      v0 = ed0.vertex(0);
Shinya Kitaoka 120a6e
      v1 = ed0.vertex(1);
Shinya Kitaoka 120a6e
      v2 = ed1.vertex((ed1.vertex(0) == v0) | (ed1.vertex(0) == v1));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      e1ovi = (ed1.vertex(0) == v1) |
Shinya Kitaoka 120a6e
              (ed1.vertex(1) == v1);  // ed1 and ed2 will refer to vertexes
Shinya Kitaoka 120a6e
      e2ovi = 1 - e1ovi;              // with index 2 and these.
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    const TPointD &p0 = mesh->vertex(v0).P(), &p1 = mesh->vertex(v1).P(),
Shinya Kitaoka 120a6e
                  &p2 = mesh->vertex(v2).P();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (t = 0; t != tCount; ++t) {
Shinya Kitaoka 120a6e
      // Draw face against tile
Shinya Kitaoka 120a6e
      const TileData &tileData = td->m_tileDatas[t];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Map each face vertex to tile coordinates
Shinya Kitaoka 120a6e
      TPointD s[3] = {tileAff[t] * p0, tileAff[t] * p1, tileAff[t] * p2};
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Test the face bbox - tile intersection
Shinya Kitaoka 120a6e
      if (std::min({s[0].x, s[1].x, s[2].x}) > 1.0 ||
Shinya Kitaoka 120a6e
          std::min({s[0].y, s[1].y, s[2].y}) > 1.0 ||
Shinya Kitaoka 120a6e
          std::max({s[0].x, s[1].x, s[2].x}) < 0.0 ||
Shinya Kitaoka 120a6e
          std::max({s[0].y, s[1].y, s[2].y}) < 0.0)
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // If the tile has changed, interrupt the glBegin/glEnd block and bind the
Shinya Kitaoka 120a6e
      // OpenGL texture corresponding to the new tile
Shinya Kitaoka 120a6e
      if (tileData.m_textureId != texId) {
Shinya Kitaoka 120a6e
        texId = tileData.m_textureId;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        glBindTexture(
Shinya Kitaoka 120a6e
            GL_TEXTURE_2D,
Shinya Kitaoka 120a6e
            tileData
Shinya Kitaoka 120a6e
                .m_textureId);  // This must be OUTSIDE a glBegin/glEnd block
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      const double *d[3] = {dstCoords + (v0 << 1), dstCoords + (v1 << 1),
Shinya Kitaoka 120a6e
                            dstCoords + (v2 << 1)};
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*
Shinya Kitaoka 120a6e
Now, draw primitives. A note about pixel arithmetic, here.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
Since line antialiasing in OpenGL just manipulates output fragments' alpha
Shinya Kitaoka 120a6e
components,
Shinya Kitaoka 120a6e
we must require that the input texture is NONPREMULTIPLIED.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
Furthermore, this function does not rely on the assumption that the output alpha
Shinya Kitaoka 120a6e
component
Shinya Kitaoka 120a6e
is discarded (as it happens when drawing on screen). This means that just using
Shinya Kitaoka 120a6e
a simple
Shinya Kitaoka 120a6e
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) is not an option, since this
Shinya Kitaoka 120a6e
way THE INPUT
Shinya Kitaoka 120a6e
SRC ALPHA GETS MULTIPLIED BY ITSELF - see glBlendFunc's docs - and that shows.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
The solution is to separate the rendering of RGB and M components - the formers
Shinya Kitaoka 120a6e
use
Shinya Kitaoka 120a6e
GL_SRC_ALPHA, while the latter uses GL_ONE. The result is a PREMULTIPLIED image.
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // First, draw antialiased face edges on the mesh border.
Shinya Kitaoka 120a6e
      bool drawEd0 = (ed0.facesCount() < 2), drawEd1 = (ed1.facesCount() < 2),
Shinya Kitaoka 120a6e
           drawEd2 = (ed2.facesCount() < 2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Shinya Kitaoka 120a6e
      glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      glBegin(GL_LINES);
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        if (drawEd0) {
Shinya Kitaoka 120a6e
          glTexCoord2d(s[0].x, s[0].y), glVertex2d(*d[0], *(d[0] + 1));
Shinya Kitaoka 120a6e
          glTexCoord2d(s[1].x, s[1].y), glVertex2d(*d[1], *(d[1] + 1));
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (drawEd1) {
Shinya Kitaoka 120a6e
          glTexCoord2d(s[e1ovi].x, s[e1ovi].y),
Shinya Kitaoka 120a6e
              glVertex2d(*d[e1ovi], *(d[e1ovi] + 1));
Shinya Kitaoka 120a6e
          glTexCoord2d(s[2].x, s[2].y), glVertex2d(*d[2], *(d[2] + 1));
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (drawEd2) {
Shinya Kitaoka 120a6e
          glTexCoord2d(s[e2ovi].x, s[e2ovi].y),
Shinya Kitaoka 120a6e
              glVertex2d(*d[e2ovi], *(d[e2ovi] + 1));
Shinya Kitaoka 120a6e
          glTexCoord2d(s[2].x, s[2].y), glVertex2d(*d[2], *(d[2] + 1));
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      glEnd();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
Shinya Kitaoka 120a6e
      glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      glBegin(GL_LINES);
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        if (drawEd0) {
Shinya Kitaoka 120a6e
          glTexCoord2d(s[0].x, s[0].y), glVertex2d(*d[0], *(d[0] + 1));
Shinya Kitaoka 120a6e
          glTexCoord2d(s[1].x, s[1].y), glVertex2d(*d[1], *(d[1] + 1));
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (drawEd1) {
Shinya Kitaoka 120a6e
          glTexCoord2d(s[e1ovi].x, s[e1ovi].y),
Shinya Kitaoka 120a6e
              glVertex2d(*d[e1ovi], *(d[e1ovi] + 1));
Shinya Kitaoka 120a6e
          glTexCoord2d(s[2].x, s[2].y), glVertex2d(*d[2], *(d[2] + 1));
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (drawEd2) {
Shinya Kitaoka 120a6e
          glTexCoord2d(s[e2ovi].x, s[e2ovi].y),
Shinya Kitaoka 120a6e
              glVertex2d(*d[e2ovi], *(d[e2ovi] + 1));
Shinya Kitaoka 120a6e
          glTexCoord2d(s[2].x, s[2].y), glVertex2d(*d[2], *(d[2] + 1));
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      glEnd();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Finally, draw the face
Shinya Kitaoka 120a6e
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Shinya Kitaoka 120a6e
      glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      glBegin(GL_TRIANGLES);
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        glTexCoord2d(s[0].x, s[0].y), glVertex2d(*d[0], *(d[0] + 1));
Shinya Kitaoka 120a6e
        glTexCoord2d(s[1].x, s[1].y), glVertex2d(*d[1], *(d[1] + 1));
Shinya Kitaoka 120a6e
        glTexCoord2d(s[2].x, s[2].y), glVertex2d(*d[2], *(d[2] + 1));
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      glEnd();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
Shinya Kitaoka 120a6e
      glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      glBegin(GL_TRIANGLES);
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        glTexCoord2d(s[0].x, s[0].y), glVertex2d(*d[0], *(d[0] + 1));
Shinya Kitaoka 120a6e
        glTexCoord2d(s[1].x, s[1].y), glVertex2d(*d[1], *(d[1] + 1));
Shinya Kitaoka 120a6e
        glTexCoord2d(s[2].x, s[2].y), glVertex2d(*d[2], *(d[2] + 1));
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      glEnd();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  glBindTexture(GL_TEXTURE_2D, 0);  // Unbind texture
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  glPopAttrib();
Toshihiro Shimizu 890ddd
}