ラベル OpenGL の投稿を表示しています。 すべての投稿を表示
ラベル OpenGL の投稿を表示しています。 すべての投稿を表示

2015年7月1日水曜日

CMakeList.txt の設定 (Visual studio 2013 + OpenGL & OpenCV & Eigen)

cmakeをつくるのに苦労したので、その記録。初心者だー
今作っているプログラムは、OpenGL & OpenCV & Eigenを使っています。それらのCmakeの作り方はそれぞれ違っていので、いろいろと参考になるねーってことでまとめ。また、私の環境はいろいろ制限(インストール不可+特定フォルダにアクセス不可)されているので、OpenGLはふつうはこんなことしなくてもいいかも。また、この理由によりパスは私の使っているものなので、自由に変更してほしい。変更するところだけ太字にしておく。

1.OpenCV
Windowsで自前でOpenCVをコンパイルした時にはCmakeはそのフォルダをわかってくれない。そのためOpenCV_DIRで場所をしていしてあげる。

ーーーーーCMakeList.txtの中身ーーーーー
# OpenCVインストールパスを指定
set(OpenCV_DIR "C:/dev/opencv-2.4.10/build/install")

# OpenCVのパッケージを探す
find_package(OpenCV REQUIRED)

# OpenCVが見つかった場合のみ設定を行う
if(OpenCV_FOUND)
  # インクルードパスを指定
  include_directories(${OpenCV_INCLUDE_DIRS})

  # リンクするライブラリ指定
  target_link_libraries(platform ${OpenCV_LIBS})
endif(OpenCV_FOUND)

2.Eigen
Eigenはインクルードのみで使えるライブラリなのでそのパスだけを指定してあげる。

ーーーーーCMakeList.txtの中身ーーーーー
# Eigen
include_directories("C:/dev/eigen-3.2.4")

3.OpenGL
なぜかこれをかなり苦労した。freeglutをダウンロードしてコンパイルして使っているのだが、フォルダ構成が違うせいかOpenCVと同じ方法をとっても何か上手くいかない。そのため、どうせ使うのはfreeglut.libとインクルードだけなので直接指定した。Cmakeの利点が消えている気がするがまぁいい。いつかいいことあるだろう。

ーーーーーCMakeList.txtの中身ーーーーー
# OpenCVのパッケージを探す
find_package(OpenGL REQUIRED)
include_directories("D:/twatanabe8/dev/freeglut-2.8.1/include")

target_link_libraries(platform "D:/twatanabe8/dev/freeglut-2.8.1/lib/x64/freeglut.lib")

2015年6月30日火曜日

OpenGL 取得した画像をOpenCVで処理してOpenGLで表示する。

内部でSimulationをするために、OpenGLでレンダリングし、その画像を取得しOpenCVで処理することを考えた。まぁ、一般的だと思う。そのためには、

1.OpenGLから画像情報の取得
画像情報の取得には3つ方法がある。
・OpenGLで画像を表示させ、glReadPixels を使って画像情報を取得
・ビデオメモリからWindowの画像情報を取得
・オフスクリーンレンダリング
・ダブルバッファから画像情報の取得
下の3つはまだ試していないので今後にやったらご紹介するとして、1つ目が一番簡単なのでその手法を採用した。

仮のコード(double bufferを使うコードから取得)
cv::Mat ReadDisplay;

glutSwapBuffers();
glReadPixels(0, 0, WIDTH, HEIGHT, GL_BGR_EXT, GL_UNSIGNED_BYTE, ReadDisplay.data);

2.画像を上下反転
OpenGLの座標系のY軸は上向きが正。OpenCVの座標系のY軸は下向きが正(左上が原点)。これを変換する必要がある。

cv::flip(ReadDisplay, ReadDisplay, 0);

3.なんか処理する。
特徴点抽出でもやりましょう。でも、本題でないため細かくは略します。ほしかったら連絡ください。
detector = new ORB(80, 1.25f, 4, 7, 0, 2, 0, 7);
detector->detect(img1, keypoints);
cv::drawKeypoints(img1, keypoints, output);

4.OpenCV 色の変更
なぜだかわからないけど、OpenCVはBGR らしい。そのため、BGRから RGB変更しましょう。

cv::cvtColor(output, output, CV_BGR2RGB);

これをやらないとセピア色になります。

5. 画像を上下反転
OpenGLで表示するために、また画像を上下反転します。

cv::flip(output, output, 0);

6.OpenGLのテクスチャに張り付けて、GLのWindowに画像を表示する。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrtho(0.0, WIDTH, HEIGHT, 0.0, -1.0, 1.0);

glEnable(GL_TEXTURE_2D);//テクスチャ有効
//glBindTexture(GL_TEXTURE_2D, img.data);

/* テクスチャ画像はバイト単位に詰め込まれている */
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
/* テクスチャの割り当て */
glTexImage2D(GL_TEXTURE_2D, 0, 3, img.cols, img.rows, 0, GL_RGB, GL_UNSIGNED_BYTE, img.data);
/* テクスチャを拡大・縮小する方法の指定 */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glEnable(GL_ALPHA_TEST);//アルファテスト開始
glBegin(GL_POLYGON);
glTexCoord2f(0.0f, 0.0f); glVertex2d(0, HEIGHT);//左下
glTexCoord2f(0.0f, 1.0f); glVertex2d(0, 0);//左上
glTexCoord2f(1.0f, 1.0f); glVertex2d(WIDTH, 0);//右上
glTexCoord2f(1.0f, 0.0f); glVertex2d(WIDTH, HEIGHT);//右下
glEnd();
glDisable(GL_ALPHA_TEST);//アルファテスト終了
glDisable(GL_TEXTURE_2D);//テクスチャ無効

glutSwapBuffers();

参考:
OpenGL描画→OpenCV処理→ピクチャボックス描画
http://ameblo.jp/morimoridiary/theme-10081830227.html
C++/CLI フォームアプリとOpenCVの連携(cv::Mat)
http://ameblo.jp/morimoridiary/entry-11879119909.html
【1. OpenGL画像をOpenCV画像(cv::Mat)に変換】
http://ameblo.jp/morimoridiary/entry-11879119909.html
Kinect for Windows SDKによる3次元ポイントクラウド
http://kassymemo.blogspot.com/2012/04/kinect-for-windows-sdk3.html
http://whoopsidaisies.hatenablog.com/entry/2014/08/20/200215

3Dファイルフォーマットの種類

以下のリンクからの頂き物です。



OBJ 

Wavefront OBJ形式.
  • 多くの3Dモデリング,レンダリングソフトが対応している.
  • 拡張子 : obj
  • ASCII
  • OBJ形式

3DS 

Autodesk 3D Studio(現在は3ds Max)用の形式.
  • シーン,モデリング,アニメーションなど多くのデータを扱える.
  • 多くの3Dモデリング,レンダリングソフトが対応している.
  • 拡張子 : 3ds, max
  • バイナリ
  • ID(2バイト),サイズ(4バイト),データで構成されるチャンクと呼ばれるデータ単位で記述される.チャンクは入れ子構造にできて,子チャンク,孫チャンクなどが存在する.
  • 読込/書込用のライブラリとして,lib3ds (オープンソースソフトウェア (LGPL)) がある.
  • The Labs.com - The Unofficial 3DStudio 3DS File Format
  • Wikipedia - .3ds

VRML 

Web上で使用することを前提に設計された形式
  • Virtual Reality Modeling Language
  • シーン,モデリング,アニメーションなどに加えて他のVRMLファイルへのリンクURLも記述できる.
  • 拡張子 : wrl
  • ASCII
  • Web3Dコンソーシアム

X3D 

VRMLの後継ファイル形式
  • XMLを用いて3Dシーンやオブジェクトを表現できるオープンな形式
  • 拡張子 : x3dv, x3d, x3db
  • ASCII
  • 対応ソフト : Blender
  • Web3Dコンソーシアム

DXF 

Autodesk AutoCAD用のファイル形式.
  • CGソフトだけでなくCAD系ソフトにも対応が多い形式(CAD図面の事実上の標準形式)
  • 拡張子 : dxf
  • ASCII & バイナリ
  • 仕様書
  • CAD用でもあり年々様々なデータに対応していっている.全てに対応した入出力ライブラリを作るのは大変だが, 3Dモデルだけで良いならば,ENTITIESセクションの3DFACEエンティティのみに対応していればOK.
  • 3DFACEだけに対応したDXFファイル入力ライブラリは3Dモデルファイルの入出力を参照.

STL 

3D System社の3D CADソフト用のファイル形式.
  • Standard Triangulated Language
  • 三次元形状を三角形ポリゴン(facet)の集合で表す.
  • 標準ではfacetのみの単純な構造なので,コーディングは楽.
  • 拡張子 : stl
  • ASCII,バイナリ
  • Wikipedia - STL

POV 

POV-Ray(Persistence Of Vision Raytracer)用のファイル形式
  • POV-Rayでレンダリングするシーンを記述する.
  • 拡張子 : pov, inc
  • ASCII
  • POV-Ray

COLLADA 

CGソフト間でデータをやり取りするための交換用ファイル形式
  • COLLAborative Design Activity
  • 元々はSonyがPS3,PSP用に作成した形式
  • Ver1.4よりPhysicsサポートが追加された(Bullet, ODE, PhysXなどが対応)
  • 拡張子 : dae
  • KHRONOSのCOLLADAのぺージ

FBX 

Alias社(Autodeskが買収)がオープンソースとして策定したファイル形式
  • SDKが公開されている.
  • 拡張子 : fbx
  • バイナリ
  • Autodesk FBX

LWO 

NetTek LightWave3D用のファイル形式

PLY 

Stanford Universityが公開しているレンジデータを元にしたメッシュを格納したフォーマット.
  • 拡張子 : ply
  • ASCII
  • The Stanford 3D Scanning Repository
  • 上記URLから,CG分野で有名なモデルをダウンロードできる(Stanford Bunny, Happy Buddha,
  • 対応ソフト : Blender

OFF 

Object File Format.Princeton shape benchmark で使われている.

XSI 

SoftImage XSI(現Autodesk SoftImage)社のモデリングソフトウェアSoftImage用のファイル形式

AC3D 

Inivis社の3D CG モデリング,デザインソフトウェアAC3D用のファイル形式.

C3D 

主にモーションキャプチャデータの格納,配布に用いられているフォーマット

BVH 

C3Dと同様に主にモーションキャプチャデータの格納,配布に用いられているフォーマット

2015年5月31日日曜日

glDrawPixels()とglReadPixels()コマンドが大変遅いのはなぜか?

覚書として。

http://opengl.jp/oglfaq/performance.htm

glDrawPixels()とglReadPixels()コマンドが大変遅いのはなぜか?
多くのよりハイエンドのUNIXワークステーションクラス機器でOpenGL2Dパス(その呼び出しのような)の性能が容認できる間、いくつかのインプリメンテーション(特に、ローエンド安い消費者レベルグラフィックスカード)は、決してよい2Dパス性能を持っていませんでした。 人は、それらのコストを倒すためにコーナーがこれらの機器またはデバイス・ドライバに刻みつけられたことを期待するだけで、マーケティングするそれらの時間を減少できます。 もし500ドルの下のためのグラフィックス機器を購入するならば、これが、書かれた(2000年初め)であった時に、チャンスがOpenGL2Dパス性能である 受け入れ不可能に遅い。
もしグラフィックスシステムが、きちんとした性能を持っているべきであるけれども、しないならば、性能を押し上げるために取ることができるいくつかの処置があります
第一に、すべてのglPixelTransfer()状態はそれらのデフォルト値に設定されるべきです。 また、glPixelStore()は、8に設定されるべきそのデフォルト値〈GL_PACK_ALIGNMENTおよびGL_UNPACK_ALIGNMENT(適切なものどれでも)を除いた〉に設定されるべきです。 データポインタは対応して2倍である必要があります 位置合わせされた-言葉 。
第二に、glDrawPixels()またはglReadPixels()にパラメータを試験してください。 それらはframebufferレイアウトと一致していますか? どのようにアプリケーションのためにframebufferが設定されるかについて考えてください。 例えば、もし8ビットの宛先アルファによって24ビットframebufferに与えていると知っているならば、タイプパラメータはGL_RGBAであり、フォーマットパラメータはGL_UNSIGNED_BYTEであるはずです。 もしタイプとフォーマットパラメータが、framebufferコンフィギュレーションと一致していないならば、それはたぶんあなたです それを処理している/ピクセルのため、行き当たられたパフォーマンスを被る パラメータ指定とframebufferフォーマットの間のデータを翻訳するために必要とした 。
最後に、非現実的な予想を持っていないことを確かめてください。 システムバスとメモリー帯域幅制限を知ってください。

OpenGL 複数画面の表示

OpenGLで描画した画像をOpenCVで表示したくなったので、2画面欲しくなった。とりあえず、2つの画像を表示するソースを載せる。

--------------------------------------------------------------
#include <GL/glut.h>

#define MaxWindowNum 4

// WindowID
int WindowID[MaxWindowNum];

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
void init(void)
{
glClearColor(0.0, 0.0, 1.0, 1.0);
}

int main(int argc, char* argv[])
{
glutInit(&argc, argv);

// 1st Window
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(640, 480);
glutInitWindowPosition(0, 0);
WindowID[1]=glutCreateWindow("Main Window");
glutDisplayFunc(display);
init();

// 2nd Window
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(640, 480);
glutInitWindowPosition(655, 0);
WindowID[2] = glutCreateWindow("2nd Window");
glutDisplayFunc(display);
init();

glutMainLoop();
return 0;
}

2015年5月23日土曜日

OpenGLのインストール(Visual Studio 2015 & 2013)

OpenGLは、発表されたのが古いながら強力な3DグラフィカルAPIです。Windows8 で Visual Studio 2015にインストールされた例がないことや、参考としたHPのリンクが切れていたりするので、覚書としてインストールの手順を書きます。

1.Visual Studio 2015のインストール
説明を割愛します。

2.GLUTのインストール
参考としたサイト(英語日本語)には、Nate Robins 氏のサイトを見てくださいと書いてありますが、ありません。いつのことからないんですかね?ここを開けば、DLLが手に入り簡単とありますが、ありませんので仕方ありません。コンパイルします。

2.1 ソースの入手

freeglut のソースファイル入手。Versionは、2.8.1がいいです。3.0.0は、VisualStudio用のファイルがなくなっていました。

2.2 プロジェクトファイルの実行

展開後、
VisualStudio->2012->freeglut.vcxproj
を実行。(これで良いのかわからなかったが、最新のものをとりあえず選択)
その後、「プロジェクトとソリューションの変更」をレビューが出るが無視。

2.3 ビルド

・「ビルド」のメニューにある「構成マネージャ」を開く。
・「アクティブソリューションの構成」を「Debug」から「Release」へ変更
・「アクティブ ソリューション プラットフォーム」を 32 ビット版のライブラリを作成するなら "Win32"を選択。64 ビット版のライブラリを作成するには,"x64" を選択。(とりあえず私のマシンは64Bit機なので64を選択したとし、この後を進める。)
メニューの「ビルド」から「freeglut のビルド」を選択。コンパイル開始。

2.4 コピー

<ソースのフォルダ>\freeglut-2.8.1\lib\x64
の中にある、freeglut.libfreeglut.dll というファイルを, それぞれ次の場所にコピー。

freeglut.lib:

C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x64
freeglut.dll:
C:\Windows\System32

<ソースのフォルダ>\freeglut-2.8.1\include\GL

の中にある、glut.h freeglut.h freeglut_std.h freeglut_ext.h というファイルを, 次の場所にコピー。

C:\Program Files (x86)\Windows Kits\8.1\Include\um\gl


注(20150627追記)
今回のパスは、環境変数を設定しなくても良い設定なので、freeglut.lib と freeglut.dllについては、コンパイルした場所に置いておき、3のプロジェクトの作成において「プロパティ->linker->Additional Library Directory」でそのフォルダを設定しても可。
また、同様にIncludeも直接接手しても可だが、元々Windows Kitsにglのパスが設定されているため、2重にでることになるので注意。Windows Kitsではフォルダ名がgl(小文字)だが、freeglutでは大文字のため、Visual studioでincludeを入力した時に大文字と小文字の二つがでる。まぁ、統一するために私は大文字で使っている。
(でも、Windows Kitにわざわざ最初からglのパスがある(GL.hとGLU.hしかないが)のに、ライブラリがないんだろ?どこかにあるのかな?どなたか知っていたら教えてください。)

3. プロジェクトの作成

「ファイル」->「新規作成」->「プロジェクト」
Visual C++」の中から「Win32 コンソール アプリケーション」

引用(日本語

freeglut あるいは GLUT 3.7.2 以降と Visual Studio の組合わせなら, ソースファイルで GL/glut.h を #include することで, 自動的に freeglut.lib または glut32.lib, glu32.lib, および opengl32.lib がリンクされます (山下 真 様ご教示ありがとうございました). したがって, このままビルドすれば実行ファイルができあがるはずです.もしうまくいかないようなら, プロジェクトのプロパティ (Alt+F7) を開き, 「構成プロパティ」の「リンカ」の「入力」を選んで, 「追加の依存ファイル」に freeglut.lib または glut32.lib, glu32.lib, および opengl32.lib の三つを追加してください. このほか, 「C/C++」の「プリプロセッサ」を選んで, 「プリプロセッサの定義」に WIN32 が含まれていることを確かめてください (無いことは無いと思いますが). もしなければ追加してください.

4. ウィンドウを開く(コンパイル)

・以下のソースを書いてね。

#include "stdafx.h"

#include <GL/glut.h>

void display(void)

{
}

int _tmain(int argc, _TCHAR* argv[]) // Visual C++ Style

{
glutInit(&argc, argv);
glutCreateWindow(argv[0]);
glutDisplayFunc(display);
glutMainLoop();
return 0;

}

・コンパイル前に「ビルド」のメニューにある「構成マネージャ」を開き、「アクティブ ソリューション プラットフォーム」を"x64" を選択。(ライブラリにX64を選択したので、こうしないと動かない。)

・コンパイル&起動
「デバック」->「デバックの開始」

画面が無事出たら成功!

追記:
コンソール画面がでて嫌なら下記コードを追加

#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")

・Window/Linux共用アプリのために、
コンソール画面が嫌になった上記のコードを追加すると、Linuxでは意味がないので、ifdefを使って分離する。また、main関数を変える(参考)。

#include "stdafx.h"
#include <GL/glut.h>

#ifdef __linux__
//linux code goes here
#elif _WIN32
// windows code goes here
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
#endif

void display(void)
{
}

int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutCreateWindow(argv[0]);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}