Skip to content

kenrio/scop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

70 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

scop (3D model viewer)

3Dモデルビューアデモ


C++とOpenGLで.obj形式の3Dモデルをリアルタイム描画するビューア

OBJパースから頂点データの構築、GPUへの転送、シェーダによる描画までのレンダリングパイプラインを、外部ライブラリ(GLM / stb_image / Assimp)を使用せずに実装し、低レイヤーからレンダリングパイプラインを理解することを目的として構築した。

また、ImGuiによるUIを導入し、モデル・テクスチャの切り替えや描画状態(テクスチャ・ライティング・UV)の制御をリアルタイムで行えるインタラクティブなビューアとした。

機能:

  • OBJモデル表示
  • OpenGLによるラスタライズ描画
  • テクスチャマッピング(平面マッピング / OBJ UV)
  • ワイヤーフレーム / ライティング / 法線ベクトル可視化トグル
  • キーボード・マウス入力

実行環境

  • macOS (Apple Silicon)
  • C++17対応コンパイラ
  • OpenGL 3.3以降
  • GLFW

ImGuiおよびgladはリポジトリ内に同梱しているため、別途インストールは不要

実行方法

ライブラリのインストール:

$ brew install glfw

ビルド:

$ make

実行:

$ ./scop						# デフォルトモデルを表示
$ ./scop <path/to/model.obj>	# 指定したOBJモデルを表示

操作方法

  • キーボード:

    • WASD / QE:モデル移動
    • T:テクスチャ表示トグル
    • L:ライティングトグル
    • U:平面マッピング / OBJ UVトグル
    • F:ワイヤーフレームトグル
    • N:法線ベクトルトグル
    • Space:自動回転トグル
    • R:ビューリセット
    • Esc:終了
  • マウス:

    • 左ドラッグ:回転
    • 右ドラッグ:パン
    • スクロール:ズーム

苦労した点

  • BMPファイルフォーマットの仕様対応

    テクスチャ読み込みのため、stb_imageを使用せずにBMPローダーを自作した。実装当初はテクスチャが表示されない、色が反転している、画像が上下逆に表示されるといった現象が発生した。BMPファイルの仕様を調べて、以下2点に起因することを特定し対応した:

    • ピクセルデータがBGR順で格納されているため、読み込み時にRGB順に並び替える
    • BITMAPINFOHEADERのbiHeightが正の値の場合はbottom-up、負の値の場合はtop-downであるため、ヘッダ情報に合わせてピクセルデータの読み込み順を切り替える
      • src/Texture.cppTexture::loadBMP:BMPヘッダの解析、BGR → RGB変換、top-down/bottom-up反転処理

工夫・力をいれた点

  • OpenGL/GLSLによるレンダリングパイプラインの構築

    OBJファイルのテキストデータを描画可能な形式でGPUに渡すために モデルデータ頂点配列GPUバッファシェーダ処理 という処理フローに分離した。CPU側で頂点データの生成・整形、GPU(シェーダ)側で座標変換・ライティング・ピクセル処理という、OpenGLパイプラインに沿った役割分担で実装した。

    • src/ObjParser.cppparseFile(), buildVertices(), parseFace():v / vt / vn / f 行の解析、fan triangulationによる三角形分割
    • src/ModelViewer.cppsetBuffers(), renderScene():頂点データの構築、CPU→GPUへのデータ転送、描画フロー管理
    • shaders/vertex.glsl:Model / View / Projection による頂点座標変換
  • 3D数学ライブラリの自作

    GLMを使用せずに3D数学の基礎を理解するために、 Vec3 / Vec4 / Mat4 のクラスを実装。translate / rotate / perspective / lookAt 行列を含む。Mat4は内部データをfloat data[4][4]で保持し、OpenGLの列優先メモリレイアウトに合わせて格納することで、 glUniformMatrix4fv()への転送にtransposeを不要とした。

    • src/Mat4.cpptranslate, rotate, perspective, lookAt の各関数(列優先メモリレイアウトで data[col][row] へ書き込み)
  • 複数テクスチャマッピング方式を統合したシェーダ

    OBJ由来のUV座標と平面マッピング用UVの2方式を実装。フラグメントシェーダでmix()による連続補間を用い、2方式間を滑らかに切り替え可能にした。同じ方法でテクスチャ表示とライティングのトグルにも適用し、シェーダ全体で一貫した制御方式とした。

    • shaders/fragment.glsl:テクスチャ、ライティングなどの描画状態のリアルタイム切り替え
    • src/ModelViewer.cpprenderScene(), smoothTransition():シェーダへのuniform値転送と、トグル状態のスムーズな繊維

参考にしたソースファイル

About

Working repository for 42 scop project (a 3D model viewer).

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages