56
50

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ofMeshの基礎

Last updated at Posted at 2015-10-31

##始めに
今回はopenFrameworksでよく使われるofMesh及びofVboMeshに関しての記事です.
内容的には、まだopenFrameworksを始めたばかりでofMeshをこれから使ってみたいと思っている人向けだと思います.
ofSpherePrimitiveやofBoxPrimitiveなんかも内部ではofMeshを使って描画しています.
サンプルコード→meshSample
今回のサンプルでは前回の記事のSceneElementとSceneManagerも用いています.

##ofMeshと頂点の繋ぎ方
ofMeshとはポリゴンを構成する頂点の座標とその色やテクスチャ座標の集合であり, またその頂点の描画順を持つことが出来ます. 描画順に関しては特に必ず必要という訳ではありませんが知っておいて損はないでしょう.

今回は簡単な四角形を書いてみます
こんな感じのイメージで頂点を4つ追加します.
FPS_45_5791.png

SquereSample.h

#include "SceneElement.cpp"
class SquereSample : public SceneElement {
    ....
    ofMesh mesh;
}
SquareSample.cpp
void SquereSample::init(){
    mesh.addVertex(ofVec3f(100,100,0));
    mesh.addVertex(ofVec3f(100,200,0));
    mesh.addVertex(ofVec3f(200,200,0));
    mesh.addVertex(ofVec3f(200,100,0));
}

void SquereSample::draw(){
    mesh.draw(); 
    ofTranslate(200, 0);
    mesh.drawWireframe(); //線のみ表示
}

しかしこれを実行しても…
FPS_45_5791.png
三角形一個しかできないですね.これはopenGLにはポリゴンの頂点の繋ぎ方が定められていて、デフォルトではGL_TRIANGLESという設定になっているからです。この繋ぎ方では最初の頂点から順に3つづつ頂点を組み合わせて三角形を描画します.ですので四角形を書こうと思うと以下のように合計6個の頂点を追加しなければなりません.

SquareSample.cpp
void SquereSample::init(){
    mesh.addVertex(ofVec3f(100,100,0));
    mesh.addVertex(ofVec3f(100,200,0));
    mesh.addVertex(ofVec3f(200,200,0));
    mesh.addVertex(ofVec3f(100,100,0));
    mesh.addVertex(ofVec3f(200,100,0));
    mesh.addVertex(ofVec3f(200,200,0));
}

こうすると以下のように四角形を描くことができます.
FPS_59_4061.png

しかしこれでは同じ頂点を繰り返し用いるのにも関わらず追加する必要がありますので色々と都合が悪いです.ここで先に記述した頂点の描画順を指定することで再利用していきます.
init()内を以下のように書き換えindexを利用することでも上記の四角形を描くことが可能です.
基本的には頂点を幾つかの三角形で常に共有したい場合は以下のようにindexを用いると良いと思いますが、最後に掲載した動画のように個々の三角形として扱いたい場合はindexは使わずにいた方が良いです.

SquareSample.cpp
void SquereSample::init(){
    mesh.addVertex(ofVec3f(100,100,0));
    mesh.addVertex(ofVec3f(100,200,0));
    mesh.addVertex(ofVec3f(200,200,0));
    mesh.addVertex(ofVec3f(200,100,0));

    mesh.useIndices = true;
    mesh.addIndex(0);
    mesh.addIndex(1);
    mesh.addIndex(2);
    mesh.addIndex(0);
    mesh.addIndex(3);
    mesh.addIndex(2);
}

今回は頂点の繋ぎ方でGL_TRIANGLESを例にしましたが他にも以下の繋ぎ方があります。
・GL_POINTS
・GL_LINES
・GL_LINE_STRIP
・GL_LINE_LOOP
・GL_TRIANGLE_STRIP
・GL_TRIANGLE_FAN
・GL_QUAD_STRIP
・GL_POLYGON

それぞれの繋ぎ方に関してはこちらを参考にしてください→Document

例えばGL_LINESにして四角形を書こうと思うと以下のように書けます.

SquareSample.cpp
void SquereSample::init(){
    
    mesh.addVertex(ofVec3f(100,100,0));
    mesh.addVertex(ofVec3f(100,200,0));
    mesh.addVertex(ofVec3f(200,200,0));
    mesh.addVertex(ofVec3f(200,100,0));

    mesh.setMode(OF_PRIMITIVE_LINES);
    mesh.addIndex(0);
    mesh.addIndex(1);
    mesh.addIndex(1);
    mesh.addIndex(2);
    mesh.addIndex(2);
    mesh.addIndex(3);
    mesh.addIndex(3);
    mesh.addIndex(0);
}

しかしこの場合、面という概念が存在しないので上図のように塗りつぶされることはありません.

また更に頂点の色を指定することができます.
頂点の繋ぎ方はGL_TRIANGLESとして説明していきます.
Meshには頂点と同じように以下のように頂点の色を指定します.

SquareSample.cpp
void SquereSample::init(){
    
    ...

    mesh.addColor(ofColor(255,0,0));
    mesh.addColor(ofColor(0,255,0));
    mesh.addColor(ofColor(0,0,255));
    mesh.addColor(ofColor(0,0,0));
}

これで各頂点に色を付ける事が出来ました.
FPS_45_4799.png

以上の原理さえわかっていれば色んな図形を描く事ができますね.
他にもcolorを指定せずにMeshに画像のデータを貼り付けることもできたり、頂点の順番によって法線が決まることとその影響等もありますが今回は省略します.要望があれば追記したいと思います.

##終わりに
以上がofMeshについての基本的な内容でした.oFで3Dモデルを読み込んだりちょっと変わった図形を描きたい時にも使えるので深く押さえておきたいところです.今回書いた内容を用いれば下に貼り付けたデモのようなガラスが割れるような表現も出来ますし, よくあるPointCloudなんかもできちゃいますね.
Meshをもっと使い倒していきたいところです.

IMAGE ALT TEXT HERE

56
50
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
56
50

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?