2Dと3Dの描画を切り替える

2Dと言っても、今では3Dを平面的に扱って表示しています。
その方が高速だったからです。
そして、なんと言っても2Dを3Dの一部として扱うと、移動、回転、
拡大縮小が自由自在に行える利点もあります。
そこで2Dと3Dを同時に描画しようとした場合、工夫が必要になります。
上手く切り替えてやらないと3Dも2Dも同じように移動、回転、拡大縮小
してしまいます。
それには、まず3Dを描画してから glPushMatrix(); で階層を降ります。
そして2Dを描画して glPopMatrix(); で階層を上がります。
これを繰り返します。
つまり3Dを親階層として2Dを子階層とします。
なので、子階層で何をしようが、親階層には影響が無いのです。

 

ファイル
main.cpp

main.cpp

#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#include <GL/freeglut/freeglut.h>
#include <math.h>

#define WIDTH 320
#define HEIGHT 240
#define Pai 3.1415926

float anglex=0.0f;
float angley=0.0f;
float anglez=0.0f;

//2D描画用
void view2D() {
glMatrixMode(GL_PROJECTION);// 射影変換行列設定
glPushMatrix();// 現在の射影変換行列を保存
glOrtho(0, WIDTH, HEIGHT, 0, -1, 1);// 正射影変換設定
glMatrixMode(GL_MODELVIEW);// モデルビュー変換行列設定
glPushMatrix();// 現在のモデルビュー行列を保存
glLoadIdentity();// 単位行列を設定
}

//3D描画用
void view3D() {
glMatrixMode(GL_PROJECTION);// 射影変換行列設定
glPopMatrix();// 射影変換行列を復元
glMatrixMode(GL_MODELVIEW);// モデルビュー変換行列設定
glPopMatrix();// モデルビュー行列を復元
glLoadIdentity();// 単位行列を設定
}
void Circle2DFill(float radius,int x,int y)
{
 for (float th1 = 0.0;  th1 <= 360.0;  th1 = th1 + 1.0)
 {            
  float th2 = th1 + 10.0;
  float th1_rad = th1 / 180.0 * Pai;
  float th2_rad = th2 / 180.0 * Pai;

  float x1 = radius * cos(th1_rad);
  float y1 = radius * sin(th1_rad);
  float x2 = radius * cos(th2_rad);
  float y2 = radius * sin(th2_rad);

  glBegin(GL_TRIANGLES);
   glVertex2f( x, y );
   glVertex2f( x1+x, y1+y );    
   glVertex2f( x2+x, y2+y );
  glEnd();
 }
}
void DrawTriangle()
{
 glBegin(GL_TRIANGLES);
 glColor4f(1.0, 0.0, 0.0, 1.0f);
 glVertex3f(50 , 30, 0);
 glColor4f(0.0, 1.0, 0.0, 1.0f);
 glVertex3f(10 , 100, 0);
 glColor4f(0.0, 0.0, 1.0, 1.0f);
 glVertex3f(90 , 100, 0);
    glEnd();
}
void DrawQuadrangle()
{
 glBegin(GL_QUADS);
 glColor4f(1.0, 1.0, 0.0, 1.0f);
 glVertex3f(100 , 180, 0);
 glColor4f(1.0, 1.0, 1.0, 1.0f);
 glVertex3f(200 , 180, 0);
 glColor4f(0.0, 1.0, 1.0, 1.0f);
 glVertex3f(200 , 220, 0);
 glColor4f(0.0, 0.0, 0.0, 1.0f);
 glVertex3f(100 , 220, 0);
    glEnd();
}
void display(void)
{
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 //3D切り替え
 view3D();
 glRotated(angley, 0.0, 1.0, 0.0);
 glRotated(anglex, 1.0, 0.0, 0.0);
 glRotated(anglez, 0.0, 0.0, 1.0);

 //頂点位置設定用
 glOrtho(0.0, WIDTH, HEIGHT, 0.0, -1.0, 1.0);

 DrawTriangle();
 DrawQuadrangle();

 //2D切り替え
 view2D();
 glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
 Circle2DFill(50.0f,250,100);

 glutSwapBuffers();
}
void idle(void)
{
 angley+=0.05f;
 anglex+=0.0025f;
 anglez+=0.03f;
 Sleep(1);
 glutPostRedisplay();
}
void Init(){
 glClearColor(0.8, 0.8, 0.8, 1.0);
 glOrtho(0, WIDTH, HEIGHT, 0, -1, 1);
}
int main(int argc, char *argv[])
{
 glutInitWindowPosition(100, 100);
 glutInitWindowSize(WIDTH, HEIGHT);
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
 glutCreateWindow("2Dと3Dの切り替え");
 glutDisplayFunc(display);
 glutIdleFunc(idle);
 Init();
 glutMainLoop();
 return 0;
}

 

 

 

 

 

 

 

最終更新:2015年01月04日 22:15
添付ファイル