OpenGL VBOのglMapBuffer関数について
OpenGL VBOのglMapBuffer関数について
今、VBOの学習をしていているのですが、glMapBuffer関数について良く分かっていません。
まずこちらのwikiに載っているプログラムを見ていただきたいです。(転載していいのかよくわからなかったので、ここには載せていません。ご了承ください。)
http://seesaawiki.jp/w/mikk_ni3_92/d/VB ... a5%c91%5f2
このプログラムの
void display() の中の
//アップデート
と書かれている箇所にglMapBuffer関数が使われています。
このプログラムによって、y軸を中心に回転させているようなのですが、どんな原理になっているのか全然わからないので
どなたかご教授していただけないでしょうか?
まずこちらのwikiに載っているプログラムを見ていただきたいです。(転載していいのかよくわからなかったので、ここには載せていません。ご了承ください。)
http://seesaawiki.jp/w/mikk_ni3_92/d/VB ... a5%c91%5f2
このプログラムの
void display() の中の
//アップデート
と書かれている箇所にglMapBuffer関数が使われています。
このプログラムによって、y軸を中心に回転させているようなのですが、どんな原理になっているのか全然わからないので
どなたかご教授していただけないでしょうか?
Re: OpenGL VBOのglMapBuffer関数について
glMapBufferはメインメモリのデータとビデオメモリのデータを同期するための関数です。
glMapBufferの第二引数がGL_READ_WRITEの場合、glMapBufferを呼び出したときにビデオメモリの内容がメインメモリにロードされ、glUnmapBufferを呼び出したときにメインメモリの内容がビデオメモリに書き戻されます。
こうすることでビデオメモリをメインメモリのように操作することができます。
VBOの回転行列を更新することでy軸を中心に回転させています。
glMapBufferの第二引数がGL_READ_WRITEの場合、glMapBufferを呼び出したときにビデオメモリの内容がメインメモリにロードされ、glUnmapBufferを呼び出したときにメインメモリの内容がビデオメモリに書き戻されます。
こうすることでビデオメモリをメインメモリのように操作することができます。
VBOの回転行列を更新することでy軸を中心に回転させています。
Re: OpenGL VBOのglMapBuffer関数について
返答ありがとうございます。
すみません、私の言葉足らずでした。
の部分がなぜy軸回転を表しているかというのと、更新というのは、何かもともと行列があってそれを書き変えているということだと思うのですが、
その書きかえられている部分というのはwiki上のプログラムではどこになるのでしょうか?
なかなか言葉で言い表すのは難しいですが、よろしくお願いします。
すみません、私の言葉足らずでした。
glBindBuffer(GL_ARRAY_BUFFER, VboId[0]);
float *ptr = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
if(ptr)
{
static float tmp[3];
for(int loop = 0; loop < aryElemNum;loop += 3)
{
//計算用にコピー
tmp[0] = ptr[loop];
tmp[1] = ptr[loop+1];
tmp[2] = ptr[loop+2];
ptr[loop]=cos(PI_OVER_180*angle)*tmp[0] + sin(PI_OVER_180*angle)*tmp[2];
ptr[loop+1] = tmp[1];
ptr[loop+2]= -sin(angle*PI_OVER_180)*tmp[0]+cos(PI_OVER_180*angle)*tmp[2];
}
glUnmapBuffer(GL_ARRAY_BUFFER);
}
その書きかえられている部分というのはwiki上のプログラムではどこになるのでしょうか?
なかなか言葉で言い表すのは難しいですが、よろしくお願いします。
Re: OpenGL VBOのglMapBuffer関数について
h2so5さんのレスの繰り返しになりますけど・・・
> なぜy軸回転を表す
cos/sinを使ってる部分がそうなんだなと見当つきませんか。
> もともと行列があってそれを書き換える
掲示されたコードでは、glMapBufferでもともとの行列を取り出していることになるのかな。
なのでptrに値を代入しているところが、実際に更新する処理になっていると思います。
その後、glUnmapBufferでビデオメモリに転送していると。
理解できなかったらすみません。
> なぜy軸回転を表す
cos/sinを使ってる部分がそうなんだなと見当つきませんか。
> もともと行列があってそれを書き換える
掲示されたコードでは、glMapBufferでもともとの行列を取り出していることになるのかな。
なのでptrに値を代入しているところが、実際に更新する処理になっていると思います。
その後、glUnmapBufferでビデオメモリに転送していると。
理解できなかったらすみません。
written by へにっくす
Re: OpenGL VBOのglMapBuffer関数について
そもそもポインタが分からないということかもしれませんが。
コメントで説明書いてみました。
コメントで説明書いてみました。
glBindBuffer(GL_ARRAY_BUFFER, VboId[0]);
// ※※ 以後、GL_ARRAY_BUFFER(頂点バッファ)とはVboId[0]に格納したIDのもの
float *ptr = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
// ※※ 頂点バッファを読み書きするため、メインメモリに割り当て、割り当てたメモリの先頭アドレスが戻る
if(ptr) // 割り当てに成功していれば真
{
static float tmp[3];
for(int loop = 0; loop < aryElemNum;loop += 3)
{
//計算用にコピー
tmp[0] = ptr[loop];
tmp[1] = ptr[loop+1];
tmp[2] = ptr[loop+2];
// ※※ メインメモリに割り当てられた頂点バッファの指定の位置から値をコピー
ptr[loop]=cos(PI_OVER_180*angle)*tmp[0] + sin(PI_OVER_180*angle)*tmp[2];
ptr[loop+1] = tmp[1];
ptr[loop+2]= -sin(angle*PI_OVER_180)*tmp[0]+cos(PI_OVER_180*angle)*tmp[2];
// ※※ メインメモリ上で回転した値に書き変える
}
glUnmapBuffer(GL_ARRAY_BUFFER);
// ※※ 頂点バッファの割り当て解除。ビデオメモリ上の頂点バッファがメインメモリ上で書き変えた値に更新される
}
Re: OpenGL VBOのglMapBuffer関数について
へにっくすさん、ISLeさん返答ありがとうございます。
glMapbufferがどのような役割を果たしているかというのは何となくですが、わかってきました。
実はまだいろいろとすっきりしていないところがあるのですが、とりあえず確実に分からないところがあるのでご教授ください。
それは、どうしてy軸回転を表しているのかという疑問についてですが、cos,sinを使っている部分が回転を表しているという予想はついておりました。
しかし、数学によると3次元でのy軸回転を表す式というのは行列で、
(cosθ 0 -sinθ)
( 0 1 0 ) ←3×3行列です
(sinθ 0 cosθ)
と表されるのですが、プログラム上だとこれが となっているのがピンとこないわけです・・・・・
glMapbufferがどのような役割を果たしているかというのは何となくですが、わかってきました。
実はまだいろいろとすっきりしていないところがあるのですが、とりあえず確実に分からないところがあるのでご教授ください。
それは、どうしてy軸回転を表しているのかという疑問についてですが、cos,sinを使っている部分が回転を表しているという予想はついておりました。
しかし、数学によると3次元でのy軸回転を表す式というのは行列で、
(cosθ 0 -sinθ)
( 0 1 0 ) ←3×3行列です
(sinθ 0 cosθ)
と表されるのですが、プログラム上だとこれが となっているのがピンとこないわけです・・・・・
Re: OpenGL VBOのglMapBuffer関数について
連投失礼します。
やはり分からないことがもう一つあります。
glGenBuffers,glBindBuffer,glBufferDataをつかって、CPU上の配列データをGPU上にコピーをしていることは分かります。
そして、そのコピーした配列データを
glMapBufferで修正できるようにしているのですよね。
このプログラムで配列データというのは、紛れもなく だと思います。
すなわちこの配列をglMapBufferでy軸回転を表す配列に修正しているということでしょうか?
仮にそうなっているとすれば、VBO上(GPU上)での配列データはy軸回転を表すものになり、これでCPU上の頂点の配列データを使って描画した物体を回転させているということなのでしょうか?
やはり分からないことがもう一つあります。
glGenBuffers,glBindBuffer,glBufferDataをつかって、CPU上の配列データをGPU上にコピーをしていることは分かります。
そして、そのコピーした配列データを
glMapBufferで修正できるようにしているのですよね。
このプログラムで配列データというのは、紛れもなく だと思います。
すなわちこの配列をglMapBufferでy軸回転を表す配列に修正しているということでしょうか?
仮にそうなっているとすれば、VBO上(GPU上)での配列データはy軸回転を表すものになり、これでCPU上の頂点の配列データを使って描画した物体を回転させているということなのでしょうか?
Re: OpenGL VBOのglMapBuffer関数について
VBOで回転行列を扱っているというのは間違いです。申し訳ありません。
コードをよく見たら座標をそのまま更新していますね。回転行列の演算はCPUで行って、回転後の座標をGPUに直接転送していることになります。
コードをよく見たら座標をそのまま更新していますね。回転行列の演算はCPUで行って、回転後の座標をGPUに直接転送していることになります。
Re: OpenGL VBOのglMapBuffer関数について
h2so5さん、へにっくすさん返答ありがとうございます。
なるほど!
ということは頂点座標の配列データを、VBO内でy軸回転させたあとの座標の配列データに修正したということなのですね。
そしてそれを、glDrawArraysで描画したわけですね。
へにっくすさん、数式を解説していただくために画像まで用意してくださってありがとうございました。
大変分かりやすかったです。
なるほど!
ということは頂点座標の配列データを、VBO内でy軸回転させたあとの座標の配列データに修正したということなのですね。
そしてそれを、glDrawArraysで描画したわけですね。
へにっくすさん、数式を解説していただくために画像まで用意してくださってありがとうございました。
大変分かりやすかったです。
Re: OpenGL VBOのglMapBuffer関数について
ちなみにVertex Buffer Object(VBO)のvertexが頂点という意味です。
行列はmatrixです。
行列はmatrixです。
Re: OpenGL VBOのglMapBuffer関数について
ISLeさん補足説明ありがとうございます。
すみません、やはりもう一つ分からないところが出てきました。
cosとsinの中身にangleが使われていますが、これは1で初期化されています。
PI_OVER_180も定数で、これとangleをかけていることから、単位である「°」を「ラジアン」に変えているのはわかるのですが、
angleの値を変動させてるプログラムは見当たらないので、回転し続けるというアニメーションになる理屈が分かりません。
cos,sinの中身は定数になっているのではないのでしょうか?
すみません、やはりもう一つ分からないところが出てきました。
cosとsinの中身にangleが使われていますが、これは1で初期化されています。
PI_OVER_180も定数で、これとangleをかけていることから、単位である「°」を「ラジアン」に変えているのはわかるのですが、
angleの値を変動させてるプログラムは見当たらないので、回転し続けるというアニメーションになる理屈が分かりません。
cos,sinの中身は定数になっているのではないのでしょうか?
Re: OpenGL VBOのglMapBuffer関数について
全然理解していないですね。
何もイベントがなければ、glutIdleFuncで登録されたidle関数が呼ばれること、
idle関数で常に再描画イベントが呼ばれる(glutPostRedisplay)こと、
glutDisplayFuncで再描画イベントとしてdisplay関数が登録されていること、
display関数が呼ばれるたびにangleごと回転して各頂点の座標が上書きされること。
上書き、というのがポイントですよ。以下の図のようにくるくる回転することになる。
図では8分割ですが、これがangleごとになってると想像してください。1度なんだから360分の1ですね。
何もイベントがなければ、glutIdleFuncで登録されたidle関数が呼ばれること、
idle関数で常に再描画イベントが呼ばれる(glutPostRedisplay)こと、
glutDisplayFuncで再描画イベントとしてdisplay関数が登録されていること、
display関数が呼ばれるたびにangleごと回転して各頂点の座標が上書きされること。
上書き、というのがポイントですよ。以下の図のようにくるくる回転することになる。
図では8分割ですが、これがangleごとになってると想像してください。1度なんだから360分の1ですね。
written by へにっくす
Re: OpenGL VBOのglMapBuffer関数について
へにっくすさん、返答ありがとうございます。
確かに、じっくり考えてみるとangleそのものを変動させる必要なんかないですね。
同じ角速度で回転しているのだったら当たり前のことでした・・・
最後まで私の質問にお付き合いしていただき、ありがとうございました。
確かに、じっくり考えてみるとangleそのものを変動させる必要なんかないですね。
同じ角速度で回転しているのだったら当たり前のことでした・・・
最後まで私の質問にお付き合いしていただき、ありがとうございました。