OBJファイルをOpenGLで表示することを試みました。
ネットにはいくつかの方法が示されていますが、(私の環境:Win7)VC++2010Expressですんないり動いたのは次のサイトでした。
http://asura.iaigiri.com/OpenGL/gl15.html
ただ、ここで提供されているものはマウスで自在に視点を変えられるものです。私が必要としているものは、視点は自分のプログラムで制御するので、表示だけをやってくれるものです。
そこで、上記のプログラムを出来るだけ手をかけずに利用する方法を考えました。(同サイトでは新旧2つの方式が示されています。私は古い方を使いました)
その結果をまとめておきます。(VC++2010Expressを前提とします)
ステップ1:上のサイトの下の方にあるダウンロードからOBLMesh.lzhをダウンロードする。
ステップ2:OBJMesh.lzhを解凍し、OBJMeshフォルダーの中にあるOBJMeshフォルダーの中からOBJLoader.cppとOBJLoader.hを拝借する。
ステップ3:自分で作ったOpenGLのメインとなるcppファイルとOBJLoader.cppとOBJLoader.hをVC++2010の一つのプロジェクトに入れる。
ステップ3:自分メインプログラムを、OBJファイルを読み込むために6点修正する。
自分で作るOpenGLのメインプログラムの例を2つ示す。6つの修正点は、①から⑥に示す。
読み込むOBJファイルとmtlファイルは、cppファイルのあるフォルダーの中のMeshというフォルダーに入っているとしている。(④で指定)
プログラム1(上記サイトのメインを単純化したもの)
// include
#include //①
#include <GL/glut.h>
#include “OBJLoader.h”//②
// global
int WindowWidth = 512;
int WindowHeight = 512;
char WindowTitle[] = “OBJファイルの読み込み画像”;
GLfloat lightColor[4] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat lightPosition[4] = { 0.0, 100.0, 0.0, 0.0 };
OBJMesh mesh; //③
//————————————————————-
// SetLighting ライティング
//————————————————————-
void SetLighting() {
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
glLightfv(GL_LIGHT0, GL_AMBIENT, lightColor);
}
//————————————————————-
// Initialize 初期化処理
//————————————————————-
void Initialize() {
glClearColor(0.3, 0.3, 1.0, 1.0); // 塗りつぶし色
glEnable(GL_DEPTH_TEST); // 深度テスト有効
SetLighting();
mesh.Load(“Mesh/box.obj”); // ④ OBJファイルの読み込み
}
//————————————————————-
// Display ウィンドウへの描画
//————————————————————-
void Display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, WindowWidth, WindowHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0, (double)WindowWidth/(double)WindowHeight, 0.1, 1000.0);
gluLookAt(5.5,5.0,5.3,0.0,0.0,0.0,0.0,1.0,0.0);⑤視点を直接指定
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// glPushMatrix();
mesh.Render(1.0); // ⑥ OBJファイルを描画(数値は大きさ)
// glPopMatrix();
glutSwapBuffers(); // ダブルバッファ
}
//——————————————————-
// Idle アイドリング時の処理
//——————————————————-
void Idle() {
glutPostRedisplay();
}
//———————————————————
// Reshape サイズ変更
//———————————————————
void Reshape(int x, int y) {
WindowWidth = x;
WindowHeight = y;
if ( WindowWidth < 1 ) WindowWidth = 1;
if ( WindowHeight < 1 ) WindowHeight = 1;
}
//——————————————————-
// main
//——————————————————-
int main( int argc, char **argv ) {
glutInit(&argc, argv);
glutInitWindowSize(WindowWidth, WindowHeight);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutCreateWindow(WindowTitle);
glutDisplayFunc(Display);
glutReshapeFunc(Reshape);
glutIdleFunc(Idle);
Initialize();
glutMainLoop();
return 0;
}
//——————————————————-
プログラム2:これはz_buffer(デプスバッファ)の値を表示するプログラムである。
(//z_buffer表示begin….//z_buffer表示endを、はずせば普通の表示になる)
#include <iostream>//①
#include <GL/glut.h>
#include “OBJLoader.h”//②
OBJMesh mesh; //③
void disp(void ) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
// glPushMatrix();
mesh.Render(1.0); // ⑥ OBJファイルを描画(数値は大きさ)
// z_buffer 表示begin
float *data = new float[500*500];//z_buff read read data
glReadPixels(0, 0, 500,500,GL_DEPTH_COMPONENT,GL_FLOAT,data);
unsigned char bimage[500][500][3];//z_buff write data
for(int b=0 ; b<500 ; b++){
for(int a=0 ; a<500 ; a++){
bimage[b][a][0] = bimage[b][a][1] = bimage[b][a][2]=(unsigned char)(data[b*500+a]*255);
}
}
glDrawPixels(500, 500, GL_RGB, GL_UNSIGNED_BYTE, &bimage[0][0][0]);
// z_buffer 表示end
glDisable(GL_DEPTH_TEST);
// glPopMatrix();
glutSwapBuffers();
}
void resize(int w,int h){
glViewport(0,0,w,h);
glLoadIdentity();
glOrtho(-2.0,2.0,-2.0,2.0,-2.0,2.0);⑤正射影を使用
}
int main(int argc , char ** argv) {
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow(“OBJfile”);
mesh.Load(“Mesh/dosei.obj”); // ④ OBJファイルの読み込み
glutDisplayFunc(disp);
glutReshapeFunc(resize);
glutMainLoop();
return 0;
}
左が(上記サイトの)オリジナル、右がz(デプス)バッファを表示したものです(手前ほど黒くなっています)。
==OBJファイルのサンプル(ネットから拾った)
box.objとbox.mtl
===box.obj
# Created by Metasequoia
mtllib box.mtl
v -100.000000 100.000000 100.000000
v -100.000000 -100.000000 100.000000
v 100.000000 100.000000 100.000000
v 100.000000 -100.000000 100.000000
v 100.000000 100.000000 -100.000000
v 100.000000 -100.000000 -100.000000
v -100.000000 100.000000 -100.000000
v -100.000000 -100.000000 -100.000000
# 8 vertices
vt 0.00000 0.00000
vt 1.00000 0.00000
vt 1.00000 1.00000
vt 0.00000 1.00000
# 4 texture vertices
vn 0.00000 0.00000 1.00000
vn 1.00000 0.00000 0.00000
vn 0.00000 0.00000 -1.00000
vn -1.00000 0.00000 0.00000
vn 0.00000 1.00000 0.00000
vn 0.00000 -1.00000 0.00000
# 6 normal vertices
usemtl default
f 2/4/1 4/3/1 3/2/1 1/1/1
f 4/4/2 6/3/2 5/2/2 3/1/2
f 6/4/3 8/3/3 7/2/3 5/1/3
f 8/4/4 2/3/4 1/2/4 7/1/4
f 1/4/5 3/3/5 5/2/5 7/1/5
f 8/4/6 6/3/6 4/2/6 2/1/6
# 6 elements
===
====boxmtl
# Created by Metasequoia
newmtl default
Ka 0.60000 0.60000 0.60000
Kd 0.80000 0.80000 0.80000
Ks 0.00000 0.00000 0.00000
Ns 5.00000
========
(objとmtlの行の開始部にスペースが入っているとダメ)