コマンドの実行
クライアント/サーバー
OpenGL のコマンド処理はクライアント/サーバーモデルとされています
つまり、クライアントがコマンドを発行し、サーバーがコマンドを解釈して処理をするのです
例えば、ネットワーク上のクライアントソフトウェアがコマンドを発行し
別の OpenGL サーバーがコマンドを受け取り、処理を行うということも可能なのです
前回は、アプリケーションがクライアントとなり、OpenGL にコマンドを渡しました
これは、クライアントとサーバーが同一のコンピュータであるというだけです
コマンドの処理を、どのコンピュータで実行するかという問題は不定です
もちろん、コンピュータの機種も問われるべき問題ではありません
しかし、ここでひとつ問題が発生します
ネットワークでは、小さなコマンド一つひとつを個別に転送するようなことはしません
通常は、効率的に回線を利用するため、まとまったパケットとして集められます
そのため、クライアントには OpenGL が描画を終了したことを保障することができないのです
コマンドを発行したからといって、サーバーが描画を終了しているとは限らないのです
そこで、発行した OpenGL コマンドの実行を強制するという方法が用いられます
コマンドの実行は glFlush() 関数を使います
void glFlush(void);
この関数は、コマンドの実行を強制し、一定時間内に処理を返します
これを呼び出せば、パケットを強制送信してサーバーに描画を要求することができます
もちろん、クライアントとサーバーが同一コンピュータであれば、あまり意味はありません
しかし、glFlush() 関数は描画を保障するという効果があるため、使用するべきだと考えられます
#include <windows.h>
#include <GL/gl.h>
#include <GL/glut.h>
void disp( void ) {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glVertex2f(-0.9 , 0.9);
glVertex2f(-0.9 , -0.9);
glVertex2f(0.9 , 0.9);
glEnd();
glFlush();
}
int main(int argc , char ** argv) {
glutInit(&argc , argv);
glutInitWindowPosition(100 , 50);
glutInitWindowSize(500 , 500);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutCreateWindow("Kitty on your lap");
glutDisplayFunc(disp);
glutMainLoop();
return 0;
}
このプログラムでは、ディスプレイ コールバックの末尾で glFlush() を呼び出しています
そのため、この時点で確実にコマンドが実行されることを保証することができるのです
ただし、glFlush() は強制実行の効果がありますが、限られた時間内に制御を返します
確実に同期をとることが目的ならば、glFlush() 関数は適切ではありません
同期を目的とする場合 glFinish() 関数を使います
void glFinish(void);
この関数は、コマンドが完全に履行されるまで制御を返しません
発行済みコマンドを強制実行し、グラフィックス ハードウェアやネットワークが
コマンドの効果が現れた(描画を終了した)ことを保障した時点で制御が戻ります
因みに glFlush() と glFinish() 関数は glBegin() と glEnd() 関数の間で使うことはできません