スポンサーリンク

OpenGLでグリッドを描く

ただXY平面を表現するだけだと目的に合わないので角度を自由に設定できるようにする。

コード(本体)

// グリッド一つ分
class cell {
  glm::vec3 _min;  //始点
  glm::vec3 _vecx; //方向1
  glm::vec3 _vecy; //方向2

public:
  cell(glm::vec3 _min_, glm::vec3 _vec_x, glm::vec3 _vec_y) {
    _min = _min_;
    _vecx = _vec_x;
    _vecy = _vec_y;
  }
  const glm::vec3& cmin()const {
    return _min;
  }
  const glm::vec3& cvecx()const {
    return _vecx;
  }
  const glm::vec3& cvecy()const {
    return _vecy;
  }

  // セルの中心
  glm::vec3 center()const {
    return _min + _vecx / 2.f + _vecy / 2.f;
  }
};

      
class grid {
  std::vector<cell> _cells;
  int _xcount;
  int _ycount;
  float _xwidth;
  float _ywidth;
  glm::vec3 _center;

public:

  size_t cellCount()const {
    return _cells.size();
  }
  cell& operator[](const size_t index) {
    return _cells[index];
  }
  const cell& operator[](const size_t index)const {
    return _cells[index];
  }
  grid() {}

  grid(const grid& g) {
    _cells = g._cells;
    _xcount = g._xcount;
    _ycount = g._ycount;
    _xwidth = g._xwidth;
    _ywidth = g._ywidth;
    _center = g._center;
  }
  grid& operator=(const grid& g) {
    _cells = g._cells;
    _xcount = g._xcount;
    _ycount = g._ycount;
    _xwidth = g._xwidth;
    _ywidth = g._ywidth;
    _center = g._center;
  }
  grid& operator=(grid&& g) {
    _cells = std::move(g._cells);
    _xcount = g._xcount;
    _ycount = g._ycount;
    _xwidth = g._xwidth;
    _ywidth = g._ywidth;
    _center = g._center;
    return *this;
  }

  // 平面一つ分。xcount × ycountのcellからなる
  grid(
    const glm::vec3 vecX,
    const glm::vec3 vecY,
    const glm::vec3 center,
    const float width,
    const float height,
    const int xcount,
    const int ycount) {

    _xcount = xcount;
    _ycount = ycount;
    _xwidth = width;
    _ywidth = height;

    _center = center;

    glm::vec3 NVecX = glm::normalize(vecX);
    glm::vec3 NVecY = glm::normalize(vecY);

    ////////////////////
    _cells.clear();

    // セル一個の縦方向、横方向のベクトル。長さはセル一個分
    const glm::vec3 CellVX = NVecX * (_xwidth / xcount);
    const glm::vec3 CellVY = NVecY * (_ywidth / ycount);

    // 面の始点
    const glm::vec3 Start = _center - NVecX * _xwidth / 2.f - NVecY * _ywidth / 2.f;

    for (size_t y = 0; y < ycount; y++) {
      for (size_t x = 0; x < xcount; x++) {

        // 各セルの始点
        glm::vec3 from =
          Start +
          CellVX * (float)x + CellVY * (float)y;

        // セルを記録
        _cells.push_back(
          cell(
            from,
            CellVX,
            CellVY
          )
        );

      }
    }

  }


  /*
  p0    p3
  +---------+
  |     |
  |     |
  |     |
  |     |
  +---------+
  p1    p2
  */
  glm::vec3 p0(const size_t index)const {
    return _cells[index].cmin();
  }
  glm::vec3 p1(const size_t index)const {

    return
      _cells[index].cmin() +
      _cells[index].cvecx();
  }
  glm::vec3 p2(const size_t index) const {
    return
      _cells[index].cmin() +
      _cells[index].cvecx() +
      _cells[index].cvecy();
  }
  glm::vec3 p3(const size_t index) const {
    return
      _cells[index].cmin() +
      _cells[index].cvecy();
  }

};

表示用関数

//! @brief グリッドを表示
//! @param [in] g グリッドオブジェクト
//! @param [in] dispcenter セルの中央を表示するか
void drawGrid(const grid& g, const bool dispcenter) {

  glLineWidth(1);
  glColor3d(1, 1, 1);
  for (size_t i = 0; i < g.cellCount(); i++) {
    glBegin(GL_LINE_LOOP);
    glVertex3fv(glm::value_ptr(g.p0(i)));
    glVertex3fv(glm::value_ptr(g.p1(i)));
    glVertex3fv(glm::value_ptr(g.p2(i)));
    glVertex3fv(glm::value_ptr(g.p3(i)));

    glEnd();
  }

  if (dispcenter) {
    glPointSize(1);
    glColor3d(1, 1, 1);
    glBegin(GL_POINTS);
    for (size_t i = 0; i < g.cellCount(); i++) {
      glVertex3fv(
        glm::value_ptr(g[i].center()));
    }
    glEnd();
  }
}

使用方法

grid g(
  glm::vec3(1,0,0),
  glm::vec3(0,1,0),
  glm::vec3(0,0,0),
  4.f,4.f,
  10,10
);

drawGrid(g, false);

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: