#include <iostream> #include <gl/glew.h> #include <gl/glut.h> #pragma comment(lib,"glew32.lib") //------------ 各種外部変数 ------------// std::pair<int,int> TextureWH(512,512); unsigned int texID[1]; //FBO用ID unsigned int FboID[1]; //RBO用ID unsigned int RboID[1]; //---------- 各種プロトタイプ -----------// void display(); void reshape(int w, int h); void timer(int value); void createTexture(); void createFBOandRBO(); bool checkFramebufferStatus(); //--------- GLUTの初期化 ---------------// void GLUT_CALL_FUNCs() { glutDisplayFunc(display); glutReshapeFunc(reshape); glutTimerFunc(0,timer,17); } void myOtherInit() { glEnable(GL_DEPTH_TEST); } void GLUT_INITs(int *argcp, char **argv) { glutInit(argcp,argv); glutInitDisplayMode(GLUT_RGBA| GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(TextureWH.first,TextureWH.second); glutCreateWindow("render to texture"); GLUT_CALL_FUNCs(); myOtherInit(); } //--------- GLEWの初期設定 ------------// bool GLEW_INIT() { GLenum err; err = glewInit(); if (err != GLEW_OK){ std::cerr << glewGetErrorString(err) << "\n"; return false; } return true; } //--------- メイン関数 ---------// int main(int argc, char **argv) { GLUT_INITs(&argc,argv); if ( GLEW_INIT() == false){ return -1;} createTexture();//テクスチャ作成 createFBOandRBO();//FBO,RBOの作成 glutMainLoop(); //破棄 glDeleteTextures(1, &texID[0]); glDeleteFramebuffersEXT(1, &FboID[0]); glDeleteRenderbuffersEXT(1, &RboID[0]); return 0; } void display() { static int r = 0; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FboID[0]);//描画先の切り替え glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(static_cast<float>(r),0,1,0); glColor3f(0,1,0); glutWireTeapot(0.5); glColor3f(1,0,0); glutWireCube(0.2); glColor3f(1,1,1); glPopMatrix(); //出力先を通常のフレームバッファの戻す glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); //これ以降は通常の描画 glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texID[0]); glGenerateMipmapEXT(GL_TEXTURE_2D);//ミップマップの生成 glBindTexture(GL_TEXTURE_2D, 0); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, texID[0]); glPushMatrix(); glRotatef(static_cast<float>(r),0,1,0); glBegin(GL_QUADS); glColor3f(1,1,1); glTexCoord2f(1, 1); glVertex3f(1,1,0); glTexCoord2f(0, 1); glVertex3f(-1,1,0); glTexCoord2f(0, 0); glVertex3f(-1,-1,0); glTexCoord2f(1, 0); glVertex3f(1,-1,0); glEnd(); glPopMatrix(); glBindTexture(GL_TEXTURE_2D, 0); glutSwapBuffers(); if(++r > 360){ r = 0;} } 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); glLoadIdentity(); gluLookAt(0.0, 2.0, 4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); //視点の設定 } void timer(int value) { glutPostRedisplay(); glutTimerFunc(value,timer,17); //タイマー関数 } //---------- テクスチャオブジェクト作成 ---------// void createTexture() { glGenTextures(1,&texID[0]); glBindTexture(GL_TEXTURE_2D, texID[0]); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); //自動的なミップマップの作成 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TextureWH.first,TextureWH.second, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindTexture(GL_TEXTURE_2D, 0); } //---------- FBO,RBOの作成 ----------------// void createFBOandRBO() { //FBO作成 glGenFramebuffersEXT(1, &FboID[0]); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FboID[0]); //RBOの作成 glGenRenderbuffersEXT(1, &RboID[0]);//RGO作成 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RboID[0]);//バインド //メモリ確保 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, TextureWH.first,TextureWH.second); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);//RBOのデフォルトへバインド /* 関連付け(アタッチメント) */ //テクスチャ->FBO (GL_COLOR_ATTACHMENT0に接続) glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texID[0], 0); //RBO->FBO glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, RboID[0]); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);//FBOのデフォルトへバインド //FBOができているかのチェック if(checkFramebufferStatus() == false ){ exit(0); } } bool checkFramebufferStatus() { // check FBO status GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); switch(status) { case GL_FRAMEBUFFER_COMPLETE_EXT: std::cout << "Framebuffer complete.\n"; return true; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: std::cout << "[ERROR] Framebuffer incomplete: Attachment is NOT complete.\n"; return false; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: std::cout << "[ERROR] Framebuffer incomplete: No image is attached to FBO.\n"; return false; case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: std::cout << "[ERROR] Framebuffer incomplete: Attached images have different dimensions.\n"; return false; case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: std::cout << "[ERROR] Framebuffer incomplete: Color attached images have different internal formats.\n"; return false; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: std::cout << "[ERROR] Framebuffer incomplete: Draw buffer.\n" ; return false; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: std::cout << "[ERROR] Framebuffer incomplete: Read buffer.\n"; return false; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: std::cout << "[ERROR] Unsupported by FBO implementation.\n"; return false; default: std::cout << "[ERROR] Unknow error.\n"; return false; } }