質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
GLFW

GLFWは、OpenGLを使用してアプリ開発を行うためのフレームワークです。Macにも対応しているマルチプラットフォームであることが特徴。ウィンドウ管理、解像度切り替え、入力管理などの機能を持ちます。

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

1598閲覧

tinyobjloaderによって読み込んだ情報で描画する方法

ShiiTakumi

総合スコア15

GLFW

GLFWは、OpenGLを使用してアプリ開発を行うためのフレームワークです。Macにも対応しているマルチプラットフォームであることが特徴。ウィンドウ管理、解像度切り替え、入力管理などの機能を持ちます。

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2018/09/24 07:35

3DCGモデル(WavefrontOBJ/.obj)をOpenGLによって読み込んで描画をしたいのですが、そのモデルを描画するための実装に詰んでいるところです。

読み込みはhttps://github.com/syoyo/tinyobjloader/blob/master/tiny_obj_loader.h
のtinyobjloader.hと、
https://github.com/syoyo/tinyobjloader/blob/master/examples/callback_api/main.cc
のmain.ccを使っています。
(言語はC++です。)

読み込みが出来たのは良いのですが、ここから
1.windowを生成(GLFWを利用して実現)
2.投資投影手法で描画
と取り組みたいのですが、2を実現するためのコーディングに詰んでおります。

現状の私の手元のコードは上記のmain.ccそのままです。
読み取った頂点座標情報等をどう上手く利用して描画に持ち込めばいいのか…。

調べても作業が進まず、C++やOpenGLに関して勉強不足を大変痛感しております。
基礎から学んでいる途中でもあり、1週間経っても進まなかったので助言を賜りたく投稿いたしました。

超初心者ですがご教授のほど、よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

obj ファイルに入っている情報は、各ポリゴンの各頂点ごとの「座標 (x, y, z)」「法線 (x, y, z)」「色 (r, g, b)」「テクスチャ座標 (x, y)」です。

基本的にこのポリゴンは三角形であり、複雑なオブジェクトも三角形が集まってできています。

なので、まずは以下のコードを作成してみて、それを objloader で取得できた三角形分繰り返すようにあとで変更すればいいかと思います。

  • 三角形のポリゴンを描画する OpenGL のコード
  • 三角形のポリゴンにテクスチャを適用して描画する OpenGL のコード
  • 透視投影変換やライトの設定

tinyobjloader で各ポリゴンの情報を取得する例

1つの頂点は複数の面で共有されているため、各頂点の情報にはインデックス経由でアクセスします。
(同じ頂点でも面ごとに情報を持つようにすると、重複して無駄なため、obj ファイルフォーマットではそうなっている。)

cpp

1tinyobj::attrib_t attrib; 2std::vector<tinyobj::shape_t> shapes; 3std::vector<tinyobj::material_t> materials; 4std::string error; 5 6bool ret = tinyobj::LoadObj( 7 &attrib, 8 &shapes, 9 &materials, 10 &error, 11 R"(test.obj)"); 12 13if (!error.empty()) 14 std::cerr << error << std::endl; 15 16if (!ret) 17 exit(1); 18 19for (const auto &shape : shapes) { 20 // shape の名前 21 std::cout << shape.name << std::endl; 22 23 size_t index_offset = 0; // インデントのオフセット 24 for (size_t f = 0; f < shape.mesh.num_face_vertices.size(); f++) { 25 // 面 f を構成sする頂点の数 26 int num_vertices = shape.mesh.num_face_vertices[f]; 27 28 glBegin(GL_TRIANGLES); 29 for (size_t v = 0; v < num_vertices; v++) { 30 // access to vertex 31 tinyobj::index_t idx = shape.mesh.indices[index_offset + v]; 32 33 // 頂点の座標 34 float vx = attrib.vertices[3 * idx.vertex_index + 0]; 35 float vy = attrib.vertices[3 * idx.vertex_index + 1]; 36 float vz = attrib.vertices[3 * idx.vertex_index + 2]; 37 38 // 頂点の法線 39 float nx = attrib.normals[3 * idx.normal_index + 0]; 40 float ny = attrib.normals[3 * idx.normal_index + 1]; 41 float nz = attrib.normals[3 * idx.normal_index + 2]; 42 43 // 頂点のテクスチャ座標 44 tinyobj::real_t tx = 45 attrib.texcoords[2 * idx.texcoord_index + 0]; 46 tinyobj::real_t ty = 47 attrib.texcoords[2 * idx.texcoord_index + 1]; 48 49 // 頂点の色 50 float red = attrib.colors[3 * idx.vertex_index + 0]; 51 float green = attrib.colors[3 * idx.vertex_index + 1]; 52 float blue = attrib.colors[3 * idx.vertex_index + 2]; 53 } 54 index_offset += num_vertices; 55 56 // per-face material 57 shape.mesh.material_ids[f]; 58 } 59}

投稿2018/09/24 11:18

tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問