質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

1178閲覧

OpenGL関数の呼び出しの順序

hikar

総合スコア13

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/03/01 13:13

OpenGLを使いグラフィクスの2D変換を行っているのですが、3Dグラフィクスwith GLUTこちらのサイトを見ていただければ、2D変換の順序として、
[a]モデリング変換M(ワールド座標変換へ)→
[b]視野変換V(カメラ座標系へ)→
[c]投影変換P(投影座標系へ)→
[d]ビューポート変換U(ビューポートへ)

という流れで説明しているのですが、ソースコードの書き方は全くの逆ので

[d]ビューポート変換U(ビューポートへ)
[c]投影変換P(投影座標系へ)→
[b]視野変換V(カメラ座標系へ)→
[a]モデリング変換M(ワールド座標変換へ)→
オブジェクト生成

という流れなのですが、コンピュータ内ではソースコードはどのような順序で処理されているのでしょうか?
どなたかわかる方おしえてください<(_ _)>

OpenGL

1#include "glut.h" 2#include <stdio.h> 3 4int windowWidth = 800; 5int windowHeight = 685; 6void display(void) { 7 glClear(GL_COLOR_BUFFER_BIT);//GLbitfield mask 8 9 glMatrixMode(GL_PROJECTION);//投影変換行列モードに切り替える 10 glLoadIdentity();//投影行列を単位行列に初期化 11 gluOrtho2D(//投影変換をする範囲を指定する 12 0, // GLdouble left 13 windowWidth, // GLdouble right 14 windowHeight, // GLdouble bottom 15 0); // GLdouble top 16 17 glMatrixMode(GL_MODELVIEW);//モデリング変換 18 glLoadIdentity();//モデリング行列を単位行列に初期化 19 20 glTranslatef(windowWidth / 2, windowHeight / 2, 0);//GLfloat x,y,z 21 22 static float angle; 23 angle += 1; 24 glRotated( 25 angle, //GLdouble angle, 26 0, 0, 1); //GLdouble x, y, z 27 glScalef(256,256,1); 28 glutWireTeapot(1); 29 glutSwapBuffers(); 30} 31 32void timer(int value) { 33 glutPostRedisplay();//システムに対して再描画をお願いする 34 35 glutTimerFunc( 36 1000/60,//unsigned int millis 37 timer, //void (GLUTCALLBACK *func)(int value) 38 0); // int value 39} 40 41void reshape(int width, int height) { 42 printf("reshape: width:%d height:%d\n", width, height); 43 glViewport( 44 0,0,//GLint x, y 45 windowWidth, windowHeight//GLsizei width, height 46 ); 47 windowWidth = width; 48 windowHeight = height; 49} 50 51int main(int argc,char*argv[]) { 52 glutInit( 53 &argc,//int *argcp 54 argv);//char **argv 55 glutInitDisplayMode(GL_DOUBLE); 56 glutInitWindowPosition(0,0); 57 glutInitWindowSize(windowWidth, windowHeight); 58 glutCreateWindow("title"); 59 glutDisplayFunc(display);//void (GLUTCALLBACK *func)(void) 60 glutTimerFunc( 61 0,//unsigned int millis 62 timer,//void (GLUTCALLBACK *func)(int value) 63 0);// int value 64 glutReshapeFunc(reshape);//void (GLUTCALLBACK *func)(int width, int height) 65 66 glutMainLoop(); 67}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

参考にされているサイトのいう

モデル座標系から、[a]モデリング変換M(ワール ド座標系へ)→[b]視野変換V(カメラ座標系へ)→[c]投影変換P(投影座標系へ)→[d]ビューポート変換U(ビューポートへ)の順番で変 換され、最終的には画面表示まで行われているのでした。

というのは、頂点座標から画面の座標への変換手続きであり、それを行っているのは実際に描画する段階での話、つまり掲示されているソースコードで言えばglutWireTeapot関数の中の話です。

glMatrixModegluOrtho2DglTranslatefなどの関数は、それらのマトリクスの設定を行っているだけに過ぎません。

擬似的にソースコードを書き直してみます。

c

1 // (1) 2 Matrix projMtx; 3 projMtx = loadIdentity(); 4 projMtx *= ortho2D(); 5 6 // (2) 7 Matrix modelViewMtx; 8 modelViewMtx = loadIdentity(); 9 modelViewMtx *= translate(width / 2, height / 2, 0); 10 modelViewMtx *= rotate(angle, 0, 0, 1); 11 modelViewMtx *= scale(256, 256, 1); 12 13 // (3) 14 Vector vs, vr; 15 vs.x = 1, vs.y = 1, vs.z = 1; 16 vr = vs * modelViewMtx * projMtx;

上記のソースコードであれば、(3)の前に行われている(1)/(2)の計算が前後入れ替わっても、(3)の結果には何も影響されない、という事がわかるのではないでしょうか。

投稿2020/03/01 16:51

katsuko

総合スコア3462

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hikar

2020/03/01 23:28

なるほど!上のソースプログラムは行列の積計算であって順番を入れ替えても出てくる答えは同じになるということですね! とても分かりやすい説明で、やっと理解出来ました(>_<)ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問