Meshを描画する
Meshとは?
Meshは頂点情報の集合のことです。複雑な物体を描画する時に用います。
VBOで高速化
VBOとは?
VBOは頂点バッファオブジェクトのことです。予めOpenGL側で頂点データを作成しておき、その後GPUで計算する手法のことです。CPUの負荷が減り、GPUで高速に演算できるメリットがあります。
//VBO ofVbo myVbo; //頂点座標 ofVec3f myVerts[NUM_PARTICLES]; //頂点の色情報 ofFloatColor myColor[NUM_PARTICLES];
ofVboクラスからインスタンスを生成します。また頂点座標、色情報を入れる配列を宣言しておきます。
setup
void ofApp::setup(){ ofBackground(0); ofEnableDepthTest(); ofEnableBlendMode(OF_BLENDMODE_ADD); cam.setDistance(100); //頂点の色を初期化 for(int i = 0;i < WIDTH;i++){ for(int j = 0;j < HEIGHT;j++){ myVerts[j * WIDTH + i].set(i - WIDTH/2,j - HEIGHT/2,0); myColor[j * WIDTH + i].set(0.5,0.8,1.0,1.0); } } //頂点バッファに位置と色情報を設定 myVbo.setVertexData(myVerts, NUM_PARTICLES, GL_DYNAMIC_DRAW); myVbo.setColorData(myColor, NUM_PARTICLES, GL_DYNAMIC_DRAW); }
set()を使って、位置と色情報を設定します。
・setのドキュメント
http://openframeworks.cc/documentation/math/ofVec3f.html#!show_set
・setVertexData、setColorDataの使い方
http://openframeworks.cc/documentation/gl/ofVbo.html#!show_setVertexData
http://openframeworks.cc/documentation/gl/ofVbo.html#!show_setColorData
setVertexData、setColorDataの最後の引数にはデータのアクセス方法を定義します。
The possible options for usage are: GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY, GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, or GL_DYNAMIC_COPY
今回使っているのは「GL_DYNAMIC_DRAW」でデータが頻繁に書き換えられることに適しています。
update
void ofApp::update(){ //頂点情報の削除 mesh.clearVertices(); //頂点の位置を更新 for(int i = 0;i < WIDTH;i++){ for(int j = 0;j < HEIGHT;j++){ float x = sin(i * 0.1 + ofGetElapsedTimef()) * 1.0; float y = sin(j * 0.15 + ofGetElapsedTimef()) * 10.0; float z = x + y; myVerts[j * WIDTH + i] = ofVec3f(i - WIDTH/2,j - HEIGHT/2,z); } } //頂点バッファ更新 myVbo.updateVertexData(myVerts, NUM_PARTICLES); }
ofGetElapsedTimef()は経過時間を指します。
draw
void ofApp::draw(){ //カメラ開始 cam.begin(); //頂点をドットで表示 glPointSize(sin(ofGetElapsedTimef()) * 4.0); myVbo.draw(GL_POINTS,0,NUM_PARTICLES); cam.end(); //ログ表示 string info; info = "Vertex num = " + ofToString(NUM_PARTICLES,0) + "¥n"; info += "FPS =" + ofToString(ofGetFrameRate(),2); ofDrawBitmapString(info, 30, 30); }
glPointSizeをsin関数で変化させるようにしてみました。これで少し波が光っているように見えます。