#include <iostream> #include <GL/glew.h> #include <GL/glut.h> //-------- 各種外部変数 ----------// struct _ImageData { int width; int height; int nChannels; }; _ImageData Screen = {256,256,4}; //PBO用ID GLuint PboId[2]; unsigned char *ColorData; //表示用カラーバッファ(glDrawPixels用) //----------- 関数プロトタイプ ----------------// void display(); void reshape(int w, int h); void timer(int value); void BuildPBO(); //----------- OpenGLの初期設定 ---------------// void GLUT_INIT() { glutInitDisplayMode(GLUT_RGBA| GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(Screen.width, Screen.height); glutCreateWindow("PBO"); } void GLUT_CALL_FUNC() { glutDisplayFunc(display); glutReshapeFunc(reshape); glutTimerFunc(0,timer,17); } void MY_INIT() { glClearColor(1.0, 1.0, 1.0, 1.0); int DataSize = Screen.height * Screen.width * Screen.nChannels; //メモリ確保と初期化 ColorData = new unsigned char[DataSize]; memset(ColorData,0,DataSize); } //--------- 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) { glutInit(&argc,argv); GLUT_INIT(); GLUT_CALL_FUNC(); MY_INIT(); if ( GLEW_INIT() == false){ return -1; } BuildPBO(); //PBO作成 glutMainLoop(); return 0; } //------------- ここから各種コールバック ------------------// void display() { static int index = 0; int nextIndex = 0; index = (index + 1) % 2; nextIndex = (index + 1) % 2; glReadBuffer(GL_FRONT); //フレームバッファの表が対象 //現在のフレームバッファからPBOにコピー glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, PboId[index]); glReadPixels(0, 0, Screen.width, Screen.height, GL_BGRA, GL_UNSIGNED_BYTE, 0); //2つ目のPBOのバッファを操作 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, PboId[nextIndex]); unsigned char *color = (unsigned char*)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB); if(color) { int *ptr = (int*)color; static int val=0; for(int y = 0; y < Screen.height ; ++y){ for(int x = 0; x < Screen.width; ++x){ *ptr = val; ++ptr; } val+=260; } ++val; memcpy(ColorData,color,Screen.height * Screen.width * Screen.nChannels); //描画用バッファにコピー glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);//マッピング解放 } glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); glDrawBuffer(GL_BACK); //後ろのバッファが対象 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //-- ここに何か描画(今回は略) --// glWindowPos2i(0,0); //描画開始位置の指定(左下原点) glDrawPixels(Screen.width, Screen.height, GL_BGRA, GL_UNSIGNED_BYTE, ColorData); 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); glLoadIdentity(); gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); //視点の設定 } void timer(int t) { glutPostRedisplay(); glutTimerFunc(t,timer,17); //タイマー関数 } void BuildPBO() { int DataSize = Screen.height * Screen.width * Screen.nChannels; glGenBuffersARB(2, PboId);//PBOを2つ作成 //1つめ glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, PboId[0]); glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, DataSize, 0, GL_STREAM_READ_ARB); //2つめ glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, PboId[1]); glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, DataSize, 0, GL_STREAM_READ_ARB); glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); }