/* * 視野テクスチャ */ #include GLuint texName[1]; /* 箱 */ void box(double x, double y, double z) { /* 頂点データ */ const GLdouble vertex[8][3]={ {-x, -y, -z}, { x, -y, -z}, { x, y, -z}, {-x, y, -z}, {-x, -y, z}, { x, -y, z}, { x, y, z}, {-x, y, z}, }; /* 面データ */ static const GLdouble *face[6][4]={ {vertex[0], vertex[1], vertex[2], vertex[3]}, {vertex[1], vertex[5], vertex[6], vertex[2]}, {vertex[5], vertex[4], vertex[7], vertex[6]}, {vertex[4], vertex[0], vertex[3], vertex[7]}, {vertex[4], vertex[5], vertex[1], vertex[0]}, {vertex[3], vertex[2], vertex[6], vertex[7]}, }; /* 面の法線ベクトル */ static const GLdouble normal[6][3]={ { 0.0, 0.0,-1.0}, { 1.0, 0.0, 0.0}, { 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0}, { 0.0,-1.0, 0.0}, { 0.0, 1.0, 0.0}, }; /* 箱の色 */ static const GLfloat color[] = {0.8, 0.8, 0.2, 1.0}; int i, j; glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color); glBegin(GL_QUADS); for (j = 0; j < 6; j++){ glNormal3dv(normal[j]); for (i = 4; --i >= 0;){ glVertex3dv(face[j][i]); } } glEnd(); } /* 初期化 */ void init(void) { GLfloat lightAmb[] = {0.0, 0.0, 0.0, 1.0}; GLfloat lightPos[] = {0.0, 1.0, -1.0, 1.0}; GLfloat lightDif[] = {1.0, 1.0, 1.0, 1.0}; /* 背景色の指定 R 赤 G 緑 B 青 A 透明度 の順 */ glClearColor(0.0, 0.0, 0.0, 0.0); /* 光源の設定 */ glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb); glLightfv(GL_LIGHT0, GL_POSITION, lightPos); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDif); glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.0); glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.2); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); /* デプスバッファの有効化 */ glEnable(GL_DEPTH_TEST); } void resize(int w, int h) { /* ビューポートの設定 */ glViewport(0, 0, w, h); /* 射影変換モードに */ glMatrixMode(GL_PROJECTION); /* 変換行列を単位行列に */ glLoadIdentity(); /* 正射影の視野長方形 左、右、下、上、手前、奥 */ glFrustum(-1.33, 1.33, -1.0, 1.0, 1.0, 15.0); /* 射影変換モードに */ glMatrixMode(GL_MODELVIEW); } /* テクスチャ設定 */ void initTexture(void) { /* テクスチャ自動生成用 */ static double genfunc[4][4]={ {1.0, 0.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 0.0, 1.0}, }; /* テクスチャデータ image0 */ GLubyte image0[4][4][3]={ 255, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255 }; glGenTextures(1 , texName); glBindTexture(GL_TEXTURE_2D , texName[0]); /* テクスチャの設定 */ glTexImage2D( GL_TEXTURE_2D ,0 /* ミップマップ */ ,3 /* RGBなので3 */ ,4 /* 幅 */ ,4 /* 高さ */ ,0 /* 境界線の幅 */ ,GL_RGB /* RGB形式 */ ,GL_UNSIGNED_BYTE /* 符号無しバイトデータ */ ,image0); /* イメージへのポインタ */ /* S方向に繰り返すGL_REPEAT 打ち切る GL_CLAMP */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); /* T方向に繰り返すGL_REPEAT 打ち切る GL_CLAMP */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); /* 画像縮小時に画像は近い色を選択 */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); /* 画像拡大時に画像は近い色を選択 */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); /* 元の面の色への対応 反映 GL_MODULATE 無視 GL_DECAL */ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); /* 頂点の視野空間における座標値をテクスチャ座標に使う */ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); /* テクスチャ座標生成関数の設定 */ glTexGendv(GL_S, GL_EYE_PLANE, genfunc[0]); glTexGendv(GL_T, GL_EYE_PLANE, genfunc[1]); glTexGendv(GL_R, GL_EYE_PLANE, genfunc[2]); glTexGendv(GL_Q, GL_EYE_PLANE, genfunc[3]); } void deinitTexture(void) { /* テクスチャの解放 */ glDeleteTextures(2, texName); } /* 画面表示 */ void display(void) { /* 背景色でクリア */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslated(0.0, 0.0, -3.0); glPushMatrix(); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D , texName[0]); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glEnable(GL_TEXTURE_GEN_R); glEnable(GL_TEXTURE_GEN_Q); /* テクスチャ行列の設定 */ glMatrixMode(GL_TEXTURE); glLoadIdentity(); glRotated(180.0, 0.0, 1.0, 0.0); glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 3.0); /* (0.0, 1.0, -3.0) から見下ろす */ glTranslated(0.0, -3.0, -1.0); glRotated(90.0, 1.0, 0.0, 0.0); /* モデルビュー変換行列の設定に戻す */ glMatrixMode(GL_MODELVIEW); glPushMatrix(); glRotated(45.0, 1.0, 0.0, 0.0); glRotated(45.0, 0.0, 1.0, 0.0); box(0.5, 0.5 ,0.5); glPopMatrix(); glPushMatrix(); glTranslated(0.0, -1.5, 0.0); box(0.5, 0.5 ,0.5); glPopMatrix(); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_R); glDisable(GL_TEXTURE_GEN_Q); glDisable(GL_TEXTURE_2D); glPopMatrix(); glFlush(); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitWindowPosition(100, 50); glutInitWindowSize(400, 300); glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH); glutCreateWindow(argv[0]); /* 各関数の指定 */ glutDisplayFunc(display); glutReshapeFunc(resize); /* 初期化 */ init(); /* テクスチャ準備 */ initTexture(); /* メインループ */ glutMainLoop(); /* テクスチャ後片付け */ deinitTexture(); return 0; }