「マルチサンプリング」をいれるも、機能しなかった。。。
--
#include
#include
#include
#pragma comment(lib,"glext.lib")
#include
#include
//------------ 各種外部変数 ------------//
const std::string filename = "..\\..\\..\\data\\image\\桜咲く.jpg";
GLuint tex_image;
std::pair TextureWH(512, 512);
unsigned int texID[1];
#define TEX_RATIO 5
#define TEX_WIDTH 320*TEX_RATIO
#define TEX_HEIGHT 180*TEX_RATIO
#define WIN_WIDTH 320*5
#define WIN_HEIGHT 180*5
#define ZOOM_RATIO 1
//FBO用ID
unsigned int FboID[1];
//RBO用ID
unsigned int RboID[1];
int GLframe = 0; //フレーム数
int GLtimenow = 0;//経過時間
int GLtimebase = 0;//計測開始時間
//---------- 各種プロトタイプ -----------//
void display();
void reshape(int w, int h);
void timer(int value);
void idle(void);
void Keyboard(unsigned char key, int x, int y);
void createTexture();
void createFBOandRBO();
bool checkFramebufferStatus();
void createImageTexture(void);
void drawImageTexture(int ratio = 1);
#define _TEST
//--------- メイン関数 ---------//
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitWindowSize(WIN_WIDTH, WIN_HEIGHT);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH| GLUT_MULTISAMPLE);
/* マルチサンプリングの状態の確認 */
GLint bufs, samples;
glGetIntegerv(GL_SAMPLE_BUFFERS, &bufs);
glGetIntegerv(GL_SAMPLES, &samples);
glutCreateWindow("render to texture");
/*http://miffysora.wikidot.com/ja:multisample*/
if (bufs > 0 && samples > 1) {
/* マルチサンプリングを有効にする */
glEnable(GL_MULTISAMPLE);
/* アルファ値をサンプルの被覆率にする */
glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
glSampleCoverage(0.5, GL_FALSE);
}
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutTimerFunc(0, timer, 17);
glutIdleFunc(idle);
glutKeyboardFunc(Keyboard);
glClearColor(1.0, 1.0, 1.0, 1.0);
glEnable(GL_DEPTH_TEST);
createTexture();//テクスチャ作成
createFBOandRBO();//FBO,RBOの作成
createImageTexture();
glutMainLoop();
//破棄
glDeleteTextures(1, &texID[0]);
glDeleteFramebuffersEXT(1, &FboID[0]);
glDeleteRenderbuffersEXT(1, &RboID[0]);
glDeleteTextures(1, &tex_image );
return 0;
}
void display(void)
{
static int r = 0;
#ifdef _TEST
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FboID[0]);//描画先の切り替え
glViewport( 0, 0, TEX_WIDTH*0.2, TEX_HEIGHT*0.2); //ビューポートの設定
glPushMatrix();
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_BLEND);
// glEnable(GL_CULL_FACE);//陰面消去しておくとより顕著にわかりやすく見えるのでEnableにした
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);//back-to-front
// GL_LINE_SMOOTH_HINT, GL_POINT_SMOOTH_HINT, GL_POLYGON_SMOOTH_HINT
// GL_NICEST,GL_FASTEST,GL_DONT_CASE
glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
glEnable(GL_POLYGON_SMOOTH);
#if 1// 0:画像 / 1:ティーポット
glRotatef(static_cast(r), 0, 1, 0);
glColor3f(0, 1, 0);
/* ティーポットを描く */
glutWireTeapot(0.5);
glColor3f(1, 0, 0);
glutWireCube(0.2);
glColor3f(0, 0, 1);
glTranslatef(0, 0, -1);
glutSolidSphere(1.0, 20, 20);
glColor3f(1, 1, 1);
#else
glViewport(0, 0, 320 * 5, 180 * 5); //ビューポートの設定
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex_image);
glBegin(GL_QUADS);
int ratio = 5;
glTexCoord2d(1.0*ratio, 1.0*ratio); glVertex2d(1, 1);
glTexCoord2d(0.0*ratio, 1.0*ratio); glVertex2d(-1, 1);
glTexCoord2d(0.0*ratio, 0.0*ratio); glVertex2d(-1, -1);
glTexCoord2d(1.0*ratio, 0.0*ratio); glVertex2d(1, -1);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
#endif
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);
#endif
glViewport(0, 0, WIN_WIDTH, WIN_HEIGHT); //ビューポートの設定
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glPushMatrix();
#ifdef _TEST
glBindTexture(GL_TEXTURE_2D, texID[0]);
#else
glBindTexture(GL_TEXTURE_2D, tex_image);
#endif
glRotatef(static_cast(r), 0, 1, 0);
glBegin(GL_POLYGON);
glTexCoord2d(0.0, 1.0); glVertex2d(-1, 1);
glTexCoord2d(0.0, 0.0); glVertex2d(-1, -1);
glTexCoord2d(1.0, 0.0); glVertex2d( 1, -1);
glTexCoord2d(1.0, 1.0); glVertex2d( 1, 1);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glFlush();
glutSwapBuffers();
// if (++r > 360) { r = 0; }
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h); //ビューポートの設定
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
#if 0
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); //視点の設定
#else
glOrtho( -1, 1, -1, 1, -1, 100 );
glMatrixMode(GL_MODELVIEW);
#endif
}
void timer(int value)
{
glutPostRedisplay();
glutTimerFunc(value, timer, 17); //タイマー関数
}
void idle(void)
{
GLframe++; //フレーム数を+1
GLtimenow = glutGet(GLUT_ELAPSED_TIME);//経過時間を取得
if (GLtimenow - GLtimebase > 1000) //1秒以上たったらfpsを出力
{
printf("fps:%f\r", GLframe*1000.0 / (GLtimenow - GLtimebase));
GLtimebase = GLtimenow;//基準時間を設定
GLframe = 0;//フレーム数をリセット
}
}
void Keyboard(unsigned char key, int x, int y) {
switch (key)
{
case 'Q':
case 'q':
case 0x1B:
exit(0);
break;
default:
break;
}
}
//---------- テクスチャオブジェクト作成 ---------//
void createTexture()
{
glGenTextures(1, &texID[0]);
glBindTexture(GL_TEXTURE_2D, texID[0]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
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, TEX_WIDTH, TEX_HEIGHT, 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_COMPONENT24, TEX_WIDTH, TEX_HEIGHT);
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;
}
}
void createImageTexture( void )
{
cv::Mat image = cv::imread(filename);
if (image.empty()) {
exit(0);
}
cv::flip(image, image, 0);
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &tex_image);
glBindTexture(GL_TEXTURE_2D, tex_image);
glTexImage2D(
GL_TEXTURE_2D, 0, 3, image.cols, image.rows,
0, GL_BGR, GL_UNSIGNED_BYTE, image.data );
/*
GL_NEAREST(最近傍法)
GL_LINEAR(双線形補間)
*/
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //拡大フィルタ
/*
GL_NEAREST(最近傍法)
GL_LINEAR(双線形補間)
GL_NEAREST_MIPMAP_NEAREST
GL_NEAREST_MIPMAP_LINEAR
GL_LINEAR_MIPMAP_NEAREST
GL_LINEAR_MIPMAP_LINEAR
*/
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //縮小フィルタ
/*
GL_REPEAT → 画像が繰り返されているとするとして画像の色を拾う
GL_CLAMP → 0~1の範囲に固定
GL_CLAMP_TO_EDGE → 画像の端のピクセルの色を使う。
GL_CLAMP_TO_BORDER → 境界の色を設定してそれを使う。(OpenGL 1.3以上)
GL_MIRRORED_REPEAT → 繰り返すとき画像を反転させる (OpenGL 1.4 以上)
*/
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);//左右端
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);//上下端
glBindTexture(GL_TEXTURE_2D, 0);
image.release();
}