最終更新: mikk_ni3_92 2010年02月26日(金) 16:40:19履歴
現在地: メニュー >> 発展編01 >> 発展編01::テクスチャデータの上書き >> 発展編01::まとめコード11
2枚の画像を用意して、1枚のテクスチャオブジェクトにデータを上書きせよ。
その他条件:次のようなキー操作
「F1」:2枚目の画像を上書き
「F2」:リセット(2枚目の画像を上書き)
「F3」:カラーバッファを書き込む
2枚の画像を用意して、1枚のテクスチャオブジェクトにデータを上書きせよ。
その他条件:次のようなキー操作
「F1」:2枚目の画像を上書き
「F2」:リセット(2枚目の画像を上書き)
「F3」:カラーバッファを書き込む
#include <iostream> #include <cv.h> #include <highgui.h> #include <gl/glut.h> #ifdef _DEBUG #pragma comment (lib , "cv200d.lib") #pragma comment (lib , "cxcore200d.lib") #pragma comment (lib , "highgui200d.lib") #else #pragma comment (lib,"cv200.lib") #pragma comment (lib,"cxcore200.lib") #pragma comment (lib,"highgui200.lib") #endif //各種外部変数 const char *filename="first.png";//オリジナル画像 const char *secondfile="second.png"; //上書き用画像(オリジナルより小さなサイズ) //テクスチャId const int TexNum = 1; GLuint texId[TexNum]; std::pair<int ,int> originalTexSize; unsigned char *originaldata;//オリジナルデータ格納用 //------- 各種描画 ---------------// void draw() { glPushMatrix(); glPushAttrib(GL_ENABLE_BIT|GL_CURRENT_BIT); glEnable(GL_TEXTURE_2D); glColor3f(0.95,0.95,0.95); glTranslatef(-0.5,-0.5,0);//位置調整 glBegin(GL_QUADS); glTexCoord2f(0,0); glVertex3f(0,0,0); glTexCoord2f(1,0); glVertex3f(1,0,0); glTexCoord2f(1,1); glVertex3f(1,1,0); glTexCoord2f(0,1); glVertex3f(0,1,0); glEnd(); glPopAttrib(); glPopMatrix(); } //------- 各種コールバック -------------// void display() { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(0,0,3,0,0,0,0,1,0); draw(); glutSwapBuffers(); } void reshape(int w, int h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(30,static_cast<float>(w)/h,0.1,200); glMatrixMode(GL_MODELVIEW); } void specialKey(int key,int x, int y) { if(key == GLUT_KEY_F1) { cv::Ptr<IplImage> imgSub = cvLoadImage(secondfile); if(imgSub.empty()) { std::cerr << "Can't Load Image\n"; return; } cvConvertImage(imgSub,imgSub,CV_CVTIMG_FLIP|CV_CVTIMG_SWAP_RB); //画像を読み込んで上書き glTexSubImage2D(GL_TEXTURE_2D,0, imgSub->width*0.5,imgSub->height*0.5,//表示位置のオフセット imgSub->width,imgSub->height,//画像サイズを GL_RGB,GL_UNSIGNED_BYTE, imgSub->imageData); }else if(key == GLUT_KEY_F2) { //リセット用 glTexSubImage2D(GL_TEXTURE_2D,0,0,0, originalTexSize.first,originalTexSize.second,GL_RGB,GL_UNSIGNED_BYTE,originaldata); }else if(key == GLUT_KEY_F3) { //現在のカラーバッファをテクスチャに転送+上書き glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0, 0,0, originalTexSize.first,originalTexSize.second); } glutPostRedisplay(); } //----------- 各種GLUTの初期化----------------// void otherMyInit() { glClearColor(0.8f,0.8f,0.8f,1); glEnable(GL_DEPTH); } void GLUT_CallBackFuncs() { glutDisplayFunc(display); glutReshapeFunc(reshape); glutSpecialFunc(specialKey); } void GLUT_Inits(int argc, char *argv[]) { glutInit(&argc,argv); glutInitWindowSize(512,512); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutCreateWindow("texture Copy"); GLUT_CallBackFuncs(); otherMyInit(); } //-------- テクスチャの読み込み ----------// bool LoadTexture() { cv::Ptr<IplImage> imgA = cvLoadImage(filename); if(imgA.empty()) { return false; } originalTexSize.first = imgA->width; originalTexSize.second = imgA->height; cvConvertImage(imgA,imgA,CV_CVTIMG_FLIP|CV_CVTIMG_SWAP_RB); glGenTextures(TexNum,&texId[0]); glBindTexture(GL_TEXTURE_2D,texId[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,3,imgA->width,imgA->height,0,GL_RGB,GL_UNSIGNED_BYTE,imgA->imageData); //もともとのデータを確保しておく(glGetTexImage関数を使用した場合) originaldata = new unsigned char[imgA->imageSize]; glGetTexImage(GL_TEXTURE_2D,0,GL_RGB,GL_UNSIGNED_BYTE,originaldata); return true; } //----------- メイン関数 ------------// int main(int argc, char *argv[]) { GLUT_Inits(argc,argv); if( LoadTexture() == false) { std::cerr << "Can't Load Image\n"; return -1; } glutMainLoop(); return 0; }