サンプルプログラム

サンプルプログラムの例(各行の意味はこの最後や、配布資料、インターネットで調べてください)

【注】サンプルプログラムをコンパイルして、実行できるようになるまで、いろいろ調整してください。
   全部のサンプルプログラムが実行できたならば、それらを組み合わせて新しい図を作ってみてください。

2次元図形を描く1(ウィンドウの大きさをマウスで変更すると図も変化する)



// deform_disp.c   図形の描画 //以下はコメント
#include <GL/glut.h> // GLUTライブラリを使用

void display(void) // 表示関数
{
  glClear(GL_COLOR_BUFFER_BIT); //背景色で塗る
  glColor3d( 1.0, 0.5, 0.5 );   // 描画色を赤で指定(赤成分,緑成分,青成分)
  glLineWidth( 1.5 );           // 線幅指定(画素単位)
  glPointSize( 6.0 );           // 点の大きさ指定(画素単位)

// 次のglBegin( )の7つのいずれか1つのみを有効にしてみよう
//  glBegin(GL_POINTS);           // 表示対象(点群)作成
//  glBegin(GL_LINES);            // 表示対象(線分)作成
//  glBegin(GL_LINE_STRIP);       // 表示対象(折れ線)作成
//  glBegin(GL_LINE_LOOP);        // 表示対象(閉じた折れ線)作成
//  glBegin(GL_TRIANGLE_STRIP);   // 表示対象(三角形の連なり)作成
//  glBegin(GL_TRIANGLE_FAN);     // 表示対象(1頂点を共有した三角形群)作成
  glBegin(GL_TRIANGLES);        // 表示対象(三角形)作成
     glVertex2d(-0.69, 0.4 );   // 2次元の頂点座標(x,y)
     glVertex2d(-0.69,-0.4 );
     glVertex2d( 0.  , 0.8 );
     glVertex2d( 0.  ,-0.8 );
     glVertex2d( 0.69, 0.4 );
     glVertex2d( 0.69,-0.4 );
  glEnd();                      // 表示対象作成終了
  glFlush();                    // 画面に出力
}

int main(int argc, char *argv[])    // 主関数(プログラムのスタート)
{
  glutInit(&argc, argv);            // グラフィック初期化
  glutInitDisplayMode(GLUT_RGBA);   // 画素毎に色を指定する描画モード
  glutInitWindowSize( 480,480 );    // ウィンドウの大きさ指定
  glutCreateWindow(argv[0]);        // 描画ウィンドウ作成(引数は表示される文字列を与える)
  glutDisplayFunc(display);         // 描画関数指定
  glClearColor(1.0, 1.0, 1.0, 1.0); // 背景色指定(白)
  glutMainLoop();                   // 割り込み待ち
  return 0;
}

2次元図形を描く2 (ウィンドウの大きさが変わっても、図は変わらない)

reshape( ) は、マウスでウィンドウの大きさを変えたときに呼ばれる関数
glOrth( ) は、表示するデータ空間の範囲を指定する関数

// const_disp.c   図形の描画 図形の大きさがウィンドウの大きさに依存しない

#include <GL/glut.h> // GLUTライブラリ

void display(void)
{
  glClear(GL_COLOR_BUFFER_BIT);
  glColor3d( 1.0, 0.5, 0.5 );   // ピンク色

  glBegin(GL_TRIANGLES);   // 三角形作成
     glVertex2d(-0.69, 0.4 );
     glVertex2d(-0.69,-0.4 );
     glVertex2d( 0.  , 0.8 );
     glVertex2d( 0.  ,-0.8 );
     glVertex2d( 0.69, 0.4 );
     glVertex2d( 0.69,-0.4 );
  glEnd();
  glFlush();
}

void reshape(int w, int h) // w, h は、ウィンドウの横、縦の長さ
{
  glViewport(0, 0, w, h);  // 表示領域をウィンドウ全体に指定
  glLoadIdentity();        // 変換行列の初期化
  // ワールド座標系での表示範囲: -w/480 < x < w/480,  -h/480 < y < h/480
  glOrtho(-(float)w/480.,(float)w/480.,-(float)h/480.,(float)h/480., -1.0, 1.0);
}

int main(int argc, char *argv[])
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGBA);
  glutInitWindowSize( 640,480 );
  glutCreateWindow(argv[0]);
  glutDisplayFunc(display);
  glutReshapeFunc(reshape);        // 再描画関数指定
  glClearColor(1., 1., 1., 1.);
  glutMainLoop();
  return 0;
}

グラデーション表示(1)


// gradation0.c  グラデーション表示の基本
// 頂点毎に色を指定、中間は線形補間された中間色となる

#include <GL/glut.h> // GLUTライブラリ

void display(void)
{
  glClear(GL_COLOR_BUFFER_BIT);
    glLineWidth(7.);         // 線分の幅を7画素分とする

    glBegin(GL_TRIANGLES);   // 中央の三角形 
      glColor3f( 1.,0.,0. ); glVertex2f( 0.,  0.666 );
      glColor3f( 0.,1.,0. ); glVertex2f(-0.5,-0.2 );
      glColor3f( 0.,0.,1. ); glVertex2f( 0.5,-0.2 );
    glEnd();

    glBegin(GL_LINES);       // 左側の斜め線
      glColor3f( 1.,0.,0. ); glVertex2f(-0.2, 0.666 );
      glColor3f( 0.,1.,0. ); glVertex2f(-0.8,-0.2 );
    glEnd();

    glBegin(GL_TRIANGLES);   // 右側の縦長四角形   
      glColor3f( 1.,0.,0. ); glVertex2f( 0.8, 0.666 );
      glColor3f( 0.,0.,1. ); glVertex2f( 0.6,-0.2 );
      glColor3f( 0.,0.,1. ); glVertex2f( 0.8,-0.2 );

      glColor3f( 1.,0.,0. ); glVertex2f( 0.8, 0.666 );
      glColor3f( 1.,0.,0. ); glVertex2f( 0.6, 0.666 );
      glColor3f( 0.,0.,1. ); glVertex2f( 0.6,-0.2 );
    glEnd();

  glFlush();
}
 
int main(int argc, char *argv[])
{
  glutInitWindowPosition(10, 10);
  glutInitWindowSize(300, 300);
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGBA);
  glutCreateWindow(argv[0]);
  glutDisplayFunc(display);
  glClearColor( 1.,1.,1.,1. );
  glutMainLoop();
  return 0;
}       

グラデーション表示と、矢印キーの割り込み処理


// gradation.c  グラデーション表示と矢印キーの割り込み処理
// 同じ矢印キーを何度か押すとグラデーションが巡回的に変化する

#include <GL/glut.h> // GLUTライブラリ

float co[][3]={1.,0.,0., 1.,1.,0., 0.,1.,0., 0.,1.,1., 0.,0.,1., 1.,0.,1.};
float a=0.8, b=0.693, c=0.4;
int n=0;

void display(void)
{
  glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_TRIANGLES);
      glColor3fv( co[n] );       glVertex2f( 0.,a );
      glColor3fv( co[(n+1)%6] ); glVertex2f(-b, c );
      glColor3f(1.,1.,1.);       glVertex2f( 0.,0.);
 
      glColor3fv( co[(n+1)%6] ); glVertex2f(-b, c );
      glColor3fv( co[(n+2)%6] ); glVertex2f(-b,-c );
      glColor3f(1.,1.,1.);       glVertex2f( 0.,0.);
 
      glColor3fv( co[(n+2)%6] ); glVertex2f(-b, -c);
      glColor3fv( co[(n+3)%6] ); glVertex2f( 0.,-a);
      glColor3f(1.,1.,1.);       glVertex2f( 0.,0.);
 
      glColor3fv( co[(n+3)%6] ); glVertex2f( 0.,-a);
      glColor3fv( co[(n+4)%6] ); glVertex2f( b, -c);
      glColor3f(1.,1.,1.);       glVertex2f( 0.,0.);
 
      glColor3fv( co[(n+4)%6] ); glVertex2f( b, -c);
      glColor3fv( co[(n+5)%6] ); glVertex2f( b,  c);
      glColor3f(1.,1.,1.);       glVertex2f( 0.,0.);
 
      glColor3fv( co[(n+5)%6] ); glVertex2f( b,  c);
      glColor3fv( co[n] );       glVertex2f( 0., a);
      glColor3f(1.,1.,1.);       glVertex2f( 0.,0.);
    glEnd();
  glFlush();
}
 
void init(void)
{
  glClearColor( 1.,1.,1.,1. );
}

void special_key(int key, int x, int y) 
//   SHIFTキーやCTRLキーを併用する場合はコメント行を参照
{
//  int SHIFT=0, CTRL=0;
//	if( glutGetModifiers() == GLUT_ACTIVE_SHIFT ) SHIFT = 1;
//	if( glutGetModifiers() == GLUT_ACTIVE_CTRL ) CTRL = 1;
  switch(key){
    case GLUT_KEY_LEFT: 
    case GLUT_KEY_UP:
      n++; if( n>5 ) n=0; break;
    case GLUT_KEY_RIGHT:
    case GLUT_KEY_DOWN:
			n--; if( n<0 ) n=5; break;
    default: break;
  }
  glutPostRedisplay();
}

void reshape(int w, int h)
{
  glViewport(0, 0, w, h);
  glLoadIdentity();
}
 
int main(int argc, char *argv[])
{
  glutInitWindowPosition(10, 10);
  glutInitWindowSize(300, 300);
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGBA);
  glutCreateWindow(argv[0]);
  glutDisplayFunc(display);
  glutReshapeFunc(reshape);
  glutSpecialFunc(special_key); // 矢印キーによる割り込み処理関数を指定
  init();
  glutMainLoop();
  return 0;
}       

英数字の表示(固定文字)


// char_disp0.c   英数字の表示
//(ラスター文字(ビットマップフォント)とベクター文字(アウトラインフォント))

#include <GL/glut.h>

void strout(float x, float y, char *str) { 
  void *font = GLUT_BITMAP_TIMES_ROMAN_24; 
  glRasterPos2f(x,y); 
  while( *str ) glutBitmapCharacter(font, *str++); 
} 
 
void display(void)
{
  char *ptr, *ft="Outline font";

  glClear(GL_COLOR_BUFFER_BIT);
  glLoadIdentity();
  glColor3f( 1.,0.,0. );            // 赤はビットマップフォント
  strout( -0.4,0.3,"Bitmap font" );

  glColor3f( 0.,0.,1. );            // 青はアウトラインフォント
  glTranslatef( -0.4,-0.4,0. );
  glScalef(0.001,0.001,1.);
  ptr = ft;
  while(*ptr)glutStrokeCharacter(GLUT_STROKE_ROMAN,*ptr++);
  glFlush();                        // 画面に出力
}

int main(int argc, char *argv[])    // 主関数(プログラムのスタート)
{
  glutInit(&argc, argv);            // グラフィック初期化
  glutInitDisplayMode(GLUT_RGBA);   // 画素毎に色を指定する描画モード
  glutCreateWindow(argv[0]);        // 描画ウィンドウ作成
  glutDisplayFunc(display);         // 描画関数指定
  glClearColor(1.0, 1.0, 1.0, 1.0); // 背景色指定(白)
  glLineWidth(2.);                  // 線幅
  glutMainLoop();                   // 割り込み待ち
  return 0;
}

英数字の表示(変数の文字化)


// char_disp.c   英数字の描画
#include <stdio.h> // for sprintf()
#include <GL/glut.h>

void strout(float x, float y, char *str) { 
  void *font = GLUT_BITMAP_TIMES_ROMAN_24; 
  glRasterPos2f(x,y); 
  while( *str ) glutBitmapCharacter(font, *str++); 
} 
 
void display(void)
{
  int i;
  float x;
  char *ptr,s1[10], *ft="Outline font";

  glClear(GL_COLOR_BUFFER_BIT);
  glColor3d( 0.,0.,0. );
  glLineWidth( 1.5 );

  glBegin(GL_LINES);
    glVertex2f( -0.8,0. );
    glVertex2f(  0.8,0. );
    for( i=-4; i<=4; i++ ){
      x = (float)i*0.2;
      glVertex2f(x,0.05); glVertex2f(x,-0.05);
    }
  glEnd();

  glColor3f( 1.,0.,0. );      // 赤はビットマップフォント
  strout( -0.4,0.3,"Bitmap font" );
  for( i=-4; i<=4; i++ ){
    x = (float)i*0.2;
    sprintf(s1,"%d",i);
    strout( x-0.02,0.08,s1 ); // ビットマップフォント
  }

  glColor3f( 0.,0.,1. );      // 青はアウトラインフォント
  for( i=-4; i<=4; i++ ){
    x = (float)i*0.2;
    sprintf(s1,"%d",i);
    ptr = s1;
    glPushMatrix();
      glTranslatef( x-0.02,-0.2,0. );
      glScalef(0.0005,0.001,0.0008);
      // アウトラインフォント出力
      while(*ptr)glutStrokeCharacter(GLUT_STROKE_ROMAN,*ptr++);
    glPopMatrix();
  }
  glPushMatrix();
    glTranslatef( -0.4,-0.4,0. );
    glScalef(0.0005,0.001,0.0008);
    ptr = ft;
    while(*ptr)glutStrokeCharacter(GLUT_STROKE_ROMAN,*ptr++);
  glPopMatrix();
  glFlush();                    // 画面に出力
}

int main(int argc, char *argv[])    // 主関数(プログラムのスタート)
{
  glutInit(&argc, argv);            // グラフィック初期化
  glutInitDisplayMode(GLUT_RGBA);   // 画素毎に色を指定する描画モード
  glutInitWindowSize( 600,300 );    // ウィンドウの大きさ指定
  glutCreateWindow(argv[0]);        // 描画ウィンドウ作成
  glutDisplayFunc(display);         // 描画関数指定
  glClearColor(1.0, 1.0, 1.0, 0.0); // 背景色指定(白)
  glutMainLoop();                   // 割り込み待ち
  return 0;
}

曲線の描画(短い折れ線で近似させる)


// curve_disp.c  リサージュ(Lissajous)図形 
// 曲線を描くときは、短い折れ線を描く
   
#include <math.h>      // sin(), cos()
#include <GL/glut.h>
 
double a, b, x[3], y[3], rad=0.01745329252;  // π/180

void display(void)
{
  int i,k0,k1,k2; 
  glClear(GL_COLOR_BUFFER_BIT);
  glBegin(GL_LINE_STRIP);       // 折れ線を生成する
    glVertex2d( x[0],y[0] );    // 最初の2点で折れ線を描く
    glVertex2d( x[1],y[1] );
    for( i=0; i<=180; i++ ){ // 漸化式で次々と点を求めて折れ線を描く
      k0 = i%3;                 // %演算子は iを3で割ったときの余り
      k1 = (i+1)%3;             // k0, k1, k2 の値は、順に 0, 1, 2 を繰り返す
      k2 = (i+2)%3;
      x[k2] = a*x[k1]-x[k0];    // 漸化式: x[i+2] = a*x[i+1] - x[i]
      y[k2] = b*y[k1]-y[k0];
      glVertex2d( x[k2]*.99,y[k2]*.99 ); 
    }
  glEnd();                      // 折れ線生成ここまで
  glFlush();                    // 画面に出力
}
 
void init(void)
{
  double p1=6.,p2=8.;            // 2種類の振動の周期
  glClearColor( 1.,1.,1.,1. );
  glColor3f( 1.,0.4,0. );
  glLineWidth(2.);
  a = 2.*cos(rad*p1);             // 漸化式の係数(x座標)
  b = 2.*cos(rad*p2);             // 漸化式の係数(y座標)
  x[0] = 0.;  x[1] = sin(rad*p1); // 最初の2点のx座標
  y[0] = 0.;  y[1] = sin(rad*p2); // 最初の2点のy座標
}
 
int main(int argc, char *argv[])
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGBA);
  glutInitWindowSize( 500,500 );
  glutCreateWindow(argv[0]);
  glutDisplayFunc(display);
  init();
  glutMainLoop();
  return 0;
}

マウス情報の取り込み1(クリックで座標を取り込む)


// mouse_click.c   マウスボタンでクリックした位置を表示

#include <GL/glut.h>
 
int px = 200, py = 150; // 初期位置
 
void display(void) { 
   glClear(GL_COLOR_BUFFER_BIT); 
   glBegin( GL_POINTS ); 
     glVertex2i( px,py );  // 点を表示
   glEnd( );
   glFlush( ); 
} 
 
void init(void) { 
   glClearColor(1., 1., 1., 1.); // 背景は白
   glColor3f( 0.,0.2,1. );        // 青色で描く
   glPointSize( 11. );           // 点の大きさは11画素
} 
 
void mouse(int button, int status, int x, int y) { 
   switch ( button ) { 
     case GLUT_LEFT_BUTTON:       // マウス左ボタンが 
       if( status == GLUT_DOWN ){ // 押された場合
         px = x;  py = y;         // マウス座標を(px,py)に取得
       } break; 
     default:  break; 
   } 
   glutPostRedisplay( ); 
} 
 
void reshape(int w, int h) { 
   glViewport(0, 0, w, h); 
   glLoadIdentity();
   // マウスの座標系はy=0はウィンドウの一番上の位置
   // マウス座標のyの正方向は下方向であり、
   // yの範囲の指定は ウィンドウの下、上の順で指定する
   glOrtho(0.,(float)w,(float)h,0.,-10.,10. ); 
} 
 
int main(int argc, char *argv[]) { 
   glutInit(&argc, argv);
   glutInitWindowSize( 400,300 );
   glutCreateWindow(argv[0]); 
   glutDisplayFunc(display); 
   glutReshapeFunc(reshape); 
   glutMouseFunc(mouse);   // マウスボタンが押されたときの割込処理関数を指定
   init(); 
   glutMainLoop(); 
   return 0; 
} 

マウス情報の取り込み2(ドラッグで座標値の連続取り込み)


// mouse_drag.c   マウス左ボタンで点を捕らえて動かす(ドラッグ)

#include <GL/glut.h>
 
int px = 200, py = 150; // 点の初期位置
 
void display(void) { 
   glClear(GL_COLOR_BUFFER_BIT); 
   glBegin( GL_POINTS ); 
     glVertex2i( px,py );  // 点を表示
   glEnd( );
   glFlush( ); 
} 

void motion(int x, int y) { 
   px = x;  py = y;  // マウス位置に点を置く
   glutPostRedisplay( ); 
}

void reshape(int w, int h) { 
   glViewport(0, 0, w, h); 
   glLoadIdentity();
   // マウスの座標系はy=0はウィンドウの一番上の位置
   // マウス座標のyの正方向は下方向なので、
   // yの範囲の指定は top=0で、bottom=hとして引数を与える
   //引数は順にleft、right、bottom、top、near、farの境界値
   glOrtho(0.,(float)w,(float)h,0.,-10.,10. ); 
} 

void init() {
   glClearColor(1., 1., 1., 1.);  // 背景は白
   glColor3f( 0.,0.2,1. );        // 青色で描く
   glPointSize(15.);              // 点の大きさ
} 
 
int main(int argc, char *argv[]) { 
   glutInit(&argc, argv);
   glutInitWindowSize( 400,300 );
   glutCreateWindow(argv[0]); 
   glutDisplayFunc(display); 
   glutReshapeFunc(reshape); 
   glutMotionFunc(motion); // マウスボタンが押された状態で動くときの割込処理関数
   init();
   glutMainLoop(); 
   return 0; 
} 

マウス情報の取り込み3(マウスが動いただけで、座標値の連続取り込み)


// mouse_passive_motion.c   マウスを動かすだけで点が追跡する

#include <GL/glut.h>
 
int p[] = {200,150}; // 点の初期位置
 
void display(void) { 
   glClear(GL_COLOR_BUFFER_BIT); 
   glBegin( GL_POINTS ); 
     glVertex2iv( p );  // 配列で与えられた整数点を表示
   glEnd( );
   glFlush( ); 
} 
 
void pmotion(int x, int y) { 
   p[0] = x;  p[1] = y;
   glutPostRedisplay( ); 
}

void reshape(int w, int h) { 
   glViewport(0, 0, w, h); 
   glLoadIdentity();
   glOrtho(0.,(float)w,(float)h,0.,-10.,10. ); 
} 

void init() {
   glClearColor(1., 1., 1., 1.); // 背景は白
   glColor3f( 0.,0.,1. );        // 青色で描く
   glPointSize(15.);             // 点の大きさ
} 
 
int main(int argc, char *argv[]) { 
   glutInit(&argc, argv);
   glutInitWindowSize( 400,300 );
   glutCreateWindow(argv[0]); 
   glutDisplayFunc(display); 
   glutReshapeFunc(reshape); 
   glutPassiveMotionFunc(pmotion); // マウスがただ動いただけでの割込処理関数を指定
   init();
   glutMainLoop(); 
   return 0; 
} 

複数のウィンドウに描く


// two_wins.c   二つのウィンドウを表示する

#include <GL/glut.h>

int WinID[2]; 

void display(void)
{
  glClear(GL_COLOR_BUFFER_BIT);
  glBegin(GL_TRIANGLES);     // 2つの三角形
     glVertex2d(-0.69, 0.4 );
     glVertex2d(-0.69,-0.4 );
     glVertex2d( 0.  , 0.8 );
     glVertex2d( 0.  ,-0.8 );
     glVertex2d( 0.69, 0.4 );
     glVertex2d( 0.69,-0.4 );
  glEnd();
  glFlush();
}
 
void display2(void)
{
  glClear(GL_COLOR_BUFFER_BIT);
  glBegin(GL_TRIANGLE_STRIP); // 六角形
     glVertex2d(-0.69, 0.4 );
     glVertex2d(-0.69,-0.4 );
     glVertex2d( 0.  , 0.8 );
     glVertex2d( 0.  ,-0.8 );
     glVertex2d( 0.69, 0.4 );
     glVertex2d( 0.69,-0.4 );
  glEnd();
  glFlush();
}
 
int main(int argc, char *argv[])
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGBA);
  // ウィンドウ0を生成
  glutInitWindowSize(640,480);
  glutInitWindowPosition(0,10);
  WinID[0] = glutCreateWindow(argv[0]);
  glClearColor(1.0, 1.0, 1.0, 0.0);

  // ウィンドウ1を生成
  glutInitWindowSize(320,320);
  glutInitWindowPosition(650,10);
  WinID[1] = glutCreateWindow(argv[0]);
  glClearColor(1.0, 1.0, 1.0, 0.0);

  // ウィンドウ0を表示
  glutSetWindow(WinID[0]);
  glColor3f( 1.,0.,0. );
  glutDisplayFunc(display);

  // ウィンドウ1を表示
  glutSetWindow(WinID[1]);
  glColor3f( 0.,0.,1. );
  glutDisplayFunc(display2);

  glutMainLoop();
  return 0;
}

1つのウィンドウ内の複数のビューポートに描く


// two_viewports.c   マウスボタンでクリックした位置を複数のビューポートに表示
#define  FRAME  1
#include <GL/glut.h>

int _w=800, _h=400;  // 初期ウィンドウサイズ
int pt[100][2];      // 点列データ
int np = 0;         // 点列個数(マウスで入力)
 
void display(void) { 
   int i;
   glClear(GL_COLOR_BUFFER_BIT); 

   glViewport( 0,0, _w/2,_h );   // 左半分領域
   glCallList( FRAME );
   glColor3f( 0.1,0.9,0. );
   glBegin( GL_POINTS );
     for( i=0; i<np; i++ ) glVertex2iv(pt[i]); // 配列で点を指定
   glEnd( );
   glColor3f( 1.,.8,0.7 );
   glBegin( GL_TRIANGLES );
     for( i=0; i<np; i++ ) glVertex2iv(pt[i]); // 配列で点を指定
   glEnd( );

   glViewport( _w/2,0,_w/2,_h ); // 右半分領域
   glCallList( FRAME );
   glColor3f( 0.,0.,1. );
   glBegin( GL_LINE_STRIP ); 
     for( i=0; i<np; i++ ) glVertex2iv(pt[i]);
   glEnd( );
   glColor3f( 0.1,0.9,0. );
   glBegin( GL_POINTS );
     for( i=0; i<np; i++ ) glVertex2iv(pt[i]);
   glEnd( );

   glutSwapBuffers();
} 
 
void reshape(int w, int h) {
//   glViewport(0, 0, w, h);
   _w = w;  _h = h;
   glLoadIdentity();
   // ビューポートの大きさでワールド座標系の範囲を設定
   glOrtho(0.,(float)(w/2),(float)h,0.,-10.,10. ); 
} 

void mouse(int button, int status, int x, int y) { 
   switch ( button ) { 
     case GLUT_LEFT_BUTTON:       // マウス左ボタンが 
       if( status == GLUT_DOWN ){ // 押された場合
         if( np < 99 ){
           if( x > _w/2 ) x -= (_w/2); // 右領域の点はx座標を変換
           pt[np][0] = x;  pt[np][1] = y; // マウス座標を配列に取得
           np++;
         }
       } break;
     default:  break; 
   }
   glutPostRedisplay( ); 
} 
 
void init(void) { 
   glClearColor(1., 1., 1., 0.);
   glPointSize( 7. );

   glNewList( FRAME,GL_COMPILE ); // ビューポートの外枠
     glColor3f( 0.,0.,0. );
     glBegin(GL_LINE_LOOP);
       glVertex2i(1,_h-1);  glVertex2i(_w/2-1,_h-1);
       glVertex2i(_w/2-1,1);  glVertex2i(1,1);
     glEnd();
   glEndList();
} 
 
int main(int argc, char *argv[]) { 
   glutInit(&argc, argv);
	 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
   glutInitWindowSize(_w,_h);
   glutCreateWindow(argv[0]); 
   glutDisplayFunc(display); 
   glutReshapeFunc(reshape); 
   glutMouseFunc(mouse);  // マウス割り込み処理関数を指定
   init(); 
   glutMainLoop(); 
   return 0; 
} 

OpenGL, GLUT関数の説明

void glViewport(int x, int y, int w, int h)
 ・ビューポートの設定。ビューポートとは, 開いたウィンドウの中で, 実際に描画が行われる領域のこと。
 ・正規化デバイス座標系(±1の範囲内の領域を含む)の2点 (-1, -1), (1, 1) を結ぶ線分を対角線とする矩形領域が表示される
 ・引数 x, y にはその領域の左下隅の位置, w には幅, h には高さをデバイス座標系,すなわちディスプレイ上の画素数で指定.
 ・関数 reshape() の引数 w, h にはそれぞれウィンドウの幅と高さが入っているので,glViewport(0,0,w,h) はリサイズ後のウィンドウの全面を表示領域に使うことを意味する.

void glLoadIdentity(void) 
 ・変換行列には初期値として単位行列を設定する.座標変換の合成は行列の積で表される.

void glOrtho(double l, double r, double b, double t, double n, double f)
 ・ワールド座標系を正規化デバイス座標系に平行投影 (orthographic projection : 正射影)する行列を変換行列に右側から掛ける。
 ・引数は左から, l に左端 (left) , r に右端 (right) , b に下端 (bottom) , t に上端 (top) , n に前方面 (near) , f に後方面 (far) の各位置座標を指定する。

glutReshapeFunc(void (*func)(int w, int h))
 ・引数 func には, ウィンドウがリサイズされたときに実行する関数のポインタ(関数名)を与える
 ・この関数の引数にはリサイズ後のウィンドウの幅と高さが渡される

 ・reshape() の処理によって, プログラムは glViewport() で指定した領域にglOrtho() で指定した領域内の図形を表示する
 ・ここで glOrtho() で指定するの領域の大きさをビューポートの大きさに、幅、高さの比が同一になるように設定すれば, 表示図形の大きさをビューポートの大きさにかかわらず一定に保つことができる。
 ・ビューポートの大きさは開いたウィンドウの大きさと一致させている場合, ウィンドウをリサイズしても表示内容の大きさを一定に保つことができる.

void glutInitWindowSize(int w, int h) 
 新たに開くウィンドウの幅と高さを指定する。指定しないときは, 300×300 のウィンドウが開く。

void glutInitWindowPosition(int x, int y)
 新たに開くウィンドウの位置を指定する。指定しないときは, ウィンドウマネージャが勝手に決める。

マウス関連関数の説明

glutMouseFunc(void (*func)(int button, int state, int x, int y))
 引数 func には, マウスのボタンが押されたときに実行する関数のポインタ(関数名)を与える.
 この与える関数の引数:
 ・ button には押されたボタン (GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON)のいずれか,
 ・ state には「押した (GLUT_DOWN)」のか「離した (GLUT_UP)」のいずれか,
 ・ x と y にはその位置が渡される.

glVertex2iv( const GLint *v )
 ・glVertex2i( ) と同様に2次元の座標値を設定する
 ・引数 v には2個の要素をもつ GLint 型 (int と等価) の配列を指定する.
 ・v[0] には x 座標値, v[1] には y 座標値を格納しておく.