|
OpenGLに関して freeglut†freeglutについて†GLUTはversion3.7 (1998年) を最後として,それ以降開発されていません. freeglutはGLUT(OpenGL Utility Toolkit)の代替となるオープンソースのOpenGLツールキットであり,GLUTの命令と完全に互換性を持っています. GLUTからfreeglutに乗り換えるときは,単純にインクルードするファイルを変更するだけで済みます. ダウンロードとインストール†
TIPS†平面クリップ†平面クリップを行うには,glClipPlaneを用いる. void glClipPlane(GLenum plane, const GLdouble *equation); planeにはクリップ平面番号(GL_CLIP_PLANE0, GL_CLIP_PLANE1など)を設定する. 最大数は,GL_MAX_CLIP_PLANESを参照することで調べられる. equationには平面方程式(ax+by+cz+d=0)の係数(a,b,c,d)を格納した4要素配列を指定する. ax+by+cz+d<0の範囲がクリップされる. 平面クリップのON/OFFは, glEnable(GL_CLIP_PLANE0); glDisable(GL_CLIP_PLANE0); マルチサンプリングによるアンチエリアシング†
DualViewなどでのフルスクリーン(Windows Only)†GLUT,freeglutではglutFullScreen関数で全画面表示できる. 標準ではマルチディスプレイの場合,スパン設定なら問題ないがDiualViewなどでは メイン画面上でしかフルスクリーンにならない. これは,DualViewではメインディスプレイのサイズがAPIが与える物理的な画面サイズとして用いられるためである. DualViewでは仮想的なスパン画面が設定されているので,これをglutFullScreenから参照されるようにしなければならない. freeglutのソースコードを変更する.freeglut_init.c の fghInitialize関数内の fgDisplay.ScreenWidth = GetSystemMetrics( SM_CXSCREEN ); fgDisplay.ScreenHeight = GetSystemMetrics( SM_CYSCREEN ); の部分を fgDisplay.ScreenWidth = GetSystemMetrics( SM_CXVIRTUALSCREEN ); fgDisplay.ScreenHeight = GetSystemMetrics( SM_CYVIRTUALSCREEN ); とすればよい. glutFullScreen命令を呼んだときだけ変えたいときや別の関数を使ってやりたいときは, freeglut_window.c内のglutFullScreen関数の, rect.left = 0; rect.top = 0; rect.right = fgDisplay.ScreenWidth; rect.bottom = fgDisplay.ScreenHeight; を rect.left = 0; rect.top = 0; rect.right = GetSystemMetrics(SM_CXVIRTUALSCREEN); rect.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN); などとする. また,マルチディスプレイ用のフルスクリーン命令を新たに作りたい場合は, この関数をコピーして名前を変えて,上記の変更をすればよい. 新しい関数を追加した場合(例えば,glutFullScreenMultiとする)は,
また,任意のマルチディスプレイに対応するために, 関数の宣言を void FGAPIENTRY glutFullScreenMulti( int left, int top, int right, int bottom ) として,上記の変更点を以下のようにする. if(!left && !right && !top && !bottom){
rect.left = 0;
rect.top = 0;
rect.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
rect.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
}
else{
rect.left = left;
rect.top = top;
rect.right = right;
rect.bottom = bottom;
}
関数を呼び出すときにフルスクリーンの範囲を指定する. 画像読み込み†OpenCVを利用†#pragma comment(lib, "cv120.lib")
#pragma comment(lib, "cxcore120.lib")
#pragma comment(lib, "cvaux120.lib")
#pragma comment(lib, "highgui120.lib")
#include "cv.h"
#include "cxcore.h"
#include "highgui/highgui.h"
/*!
* OpenCVで画像読込み -> OpenGLテクスチャ登録
* @param[in] fn ファイル名
* @param[inout] tex_name テクスチャ名(0なら新たに生成)
* @param[in] mipmap ミップマップ使用フラグ
* @param[in] compress テクスチャ圧縮使用フラグ
*/
static int LoadGLTexture(const string &fn, GLuint &tex_name, bool mipmap, bool compress)
{
IplImage* img = cvLoadImage(fn.c_str(), CV_LOAD_IMAGE_COLOR);
if(!img){
return 0;
}
GLuint iformat, format;
int w, h, c;
w = img->width;
h = img->height;
c = img->nChannels;
// 画像フォーマット
format = GL_BGRA;
if(c == 1){
format = GL_LUMINANCE;
}
else if(c == 3){
format = GL_BGR;
}
// OpenGL内部の格納フォーマット
if(compress){
iformat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
if(c == 1){
iformat = GL_COMPRESSED_LUMINANCE_ARB;
}
else if(c == 3){
iformat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT ;
}
}
else{
iformat = GL_RGBA;
if(c == 1){
iformat = GL_LUMINANCE;
}
else if(c == 3){
iformat = GL_RGB;
}
}
//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// テクスチャ作成
if(tex_name == 0){
glGenTextures(1, &tex_name);
glBindTexture(GL_TEXTURE_2D, tex_name);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
if(mipmap){
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 6);
}
glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, GL_UNSIGNED_BYTE, img->imageData);
if(mipmap){
glGenerateMipmapEXT(GL_TEXTURE_2D);
}
}
else{
glBindTexture(GL_TEXTURE_2D, tex_name);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, img->imageData);
if(mipmap){
glGenerateMipmapEXT(GL_TEXTURE_2D);
}
}
glBindTexture(GL_TEXTURE_2D, 0);
return 1;
}
ミップマップ作成にglGenerateMipmapEXTを使っている. これはもともとFBO拡張の一部であるが,FBOなしでも使え, ハードウェアによるアクセラレーションにも対応しているので新しめのGPUなら高速かもしれない. 代わりに, gluBuild2DMipmaps(GL_TEXTURE_2D, iformat, w, h, format, GL_UNSIGNED_BYTE, img->imageData); を用いてもよい. 描画の画像保存†bool SaveFrameBuffer(const string &fn, int w, int h)
{
int c = 3;
vector<unsigned char> img_buf(w*h*c);
int format = GL_BGRA;
if(c == 3){
format = GL_BGR;
}
glRasterPos2i(0, h);
glReadPixels(0, 0, w, h, format, GL_UNSIGNED_BYTE, &img_buf[0]);
IplImage *cvimg;
cvimg = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 3);
for(int i = 0; i < w; ++i){
for(int j = 0; j < h; ++j){
int idx = 3*(w*(h-j-1)+i);
//int idx = 3*(j*w+i);
int r, g, b;
r = img_buf[idx+0];
g = img_buf[idx+1];
b = img_buf[idx+2];
SetPixel(cvimg, i, j, r, g, b);
}
}
cvSaveImage(fn.c_str(), cvimg);
return true;
}
リンク集†リファレンスなど†
GUIライブラリ†拡張ライブラリ†3Dモデルダウンロード†
|