OpenGL de プログラミング - 実践編05::まとめコード3_1
現在地: メニュー >> 実践編05 >> 実践編05::シャドウマッピング >> 実践編05::デプステクスチャ >> 実践編05::まとめコード3_1

問題


glCopyTexImage2DとglReadPixelsのプログラムを変更し、
「t」を押すとデプステクスチャを表示するようなプログラムを作成せよ。

答え


#include <iostream>
#include <GL/glut.h>
#include <cv.h>
#include <highgui.h>

//------------- プロトタイプ宣言 ------------------//
void display();
void reshape(int w, int h);
void myMouseFunc(int button,int state,int x,int y);
void myMouseMotion(int x,int y);
void keyboard(unsigned char key, int x, int y);

void DRAW_XYZ();
void DRAW_TRI();
void CopyToTexAndDisplay();
void ReadPixelsAndDisplay();

//----- テクスチャID -----//
GLuint texture[1];


//------------- 各種データ構造 ------------------------//
//マウスの状態
struct MOUSE
{
        int Xstart,Ystart;
        bool flag;
        double weight;
};
MOUSE MouseStatus={0,0,false,0.5};


//回転関係
struct ObjectRotate
{
        double xAngle,yAngle;
};
ObjectRotate ObjRot={0,0};

//------------- OpenGLの初期設定 -------------------------//
void GLUT_INIT()
{
        glutInitDisplayMode(GLUT_RGBA| GLUT_DOUBLE | GLUT_DEPTH);
        glutInitWindowSize(640,480);
        glutCreateWindow("Depth Texture");
}

void GLUT_CALL_FUNC()
{
        glutDisplayFunc(display);
        glutReshapeFunc(reshape);
        glutMouseFunc(myMouseFunc);
        glutMotionFunc(myMouseMotion);
        glutKeyboardFunc(keyboard);

}

void MY_INIT()
{
        glClearColor(1.0, 1.0, 1.0, 1.0);
        glEnable(GL_DEPTH_TEST);
        std::cout << "key [t]:glCopyTexImage2D\n";
}

//----------- メイン関数 -----------------//
int main(int argc, char **argv)
{
        glutInit(&argc,argv);
        GLUT_INIT();
        
        GLUT_CALL_FUNC();
        MY_INIT();
        glutMainLoop();

        return 0;
}

//------------- ここから各種コールバック -----------------//
void display()
{
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glLoadIdentity();
        gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

        glRotated(ObjRot.xAngle,1,0,0);
        glRotated(ObjRot.yAngle,0,1,0);

        DRAW_XYZ();
        DRAW_TRI();

		glPushMatrix();
		glTranslatef(0,0,-2.0);
		glColor3f(1,0,1);
		glutSolidTorus(0.2,0.3,20,20);
		glPopMatrix();


		glPushMatrix();
		glTranslatef(0,0,1.5);
		glColor3f(1,1,0);
		glutSolidTeapot(0.4);
		glPopMatrix();

        glutSwapBuffers();

}

void reshape(int w, int h)
{
        glViewport(0, 0, w, h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(30.0, (double)w / (double)h, 1.0, 100.0);
        glMatrixMode(GL_MODELVIEW);
}

//------- マウス処理 --------//
void myMouseFunc(int button,int state,int x,int y)
{
        if(button == GLUT_LEFT_BUTTON &&state == GLUT_DOWN){
                MouseStatus.Xstart = x;
                MouseStatus.Ystart = y;
                MouseStatus.flag = true;
        }
        else{
                MouseStatus.flag =false;
        }

}

void myMouseMotion(int x,int y)
{
        if(MouseStatus.flag == false)return;

        static int xdir,ydir;

        xdir = x - MouseStatus.Xstart;
        ydir = y - MouseStatus.Ystart;

        ObjRot.xAngle += (double)ydir * MouseStatus.weight;
        ObjRot.yAngle += (double)xdir * MouseStatus.weight;

        MouseStatus.Xstart = x;
        MouseStatus.Ystart = y;
        
        glutPostRedisplay();
}


//-------- キーボード処理 ---------//
void keyboard(unsigned char key, int x, int y)
{
        switch(key)
        {
        case 't':
                CopyToTexAndDisplay();
                break;

        case 'q':
        case 'Q':
        case '\033':
                exit(0);
                break;

        default:
                break;
        }
}


//------------ ここから各種関数 ---------------//
void DRAW_XYZ()
{
        glBegin(GL_LINES);

        glColor3d(0,1,0);//x
        glVertex2d(-100,0);
        glVertex2d(100, 0);

        glColor3d(1,0,0);//y
        glVertex2d(0,0);
        glVertex2d(0,100);

        glColor3d(0,0,1);//z
        glVertex3d(0,0,-100);
        glVertex3d(0,0, 100);
        glEnd();
}

void DRAW_TRI()
{
        glBegin(GL_TRIANGLES);
        glVertex2d(0,1);
        glVertex2d(-0.5, 0);
        glVertex2d(0.5, 0);
        glEnd();
}

void CopyToTexAndDisplay()
{
        std::pair<int,int> WindowSize(glutGet(GLUT_WINDOW_WIDTH),glutGet(GLUT_WINDOW_HEIGHT));
        IplImage *imgA = cvCreateImage(cvSize(WindowSize.first,WindowSize.second),IPL_DEPTH_8U,1);

        std::cout << "Depth Texture is Displaying ...\n";
        glGenTextures(1, &texture[0]);
        glBindTexture(GL_TEXTURE_2D, texture[0]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); //フィルタ
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        //テクスチャ格納用メモリ確保
        glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, WindowSize.first,WindowSize.second,0, GL_DEPTH_COMPONENT,GL_UNSIGNED_BYTE,NULL);
        
        glCopyTexImage2D( GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT,0,0,WindowSize.first,WindowSize.second,0);
        glGetTexImage(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT,GL_UNSIGNED_BYTE,imgA->imageData);


        //OpenCVでの表示用に上下の調整
        cvFlip(imgA,imgA);
 
        cvNamedWindow("Depth Texture",CV_WINDOW_AUTOSIZE);
        cvShowImage("Depth Texture",imgA);

        cvWaitKey(0); //wait処理

        glDeleteTextures(1,&texture[0]);

        cvReleaseImage(&imgA);//メモリ解放
        cvDestroyWindow("Depth Texture"); //ウィンドウを破棄

}

【メモ】


マウスで回転させて、物体が重なる位置にして表示させるとわかりやすいかも。
手前ほど、黒くなる。→ 値としては0に近い事になる