OSDN Ticket Archive


Ticket #45699

macOS版 3DグラフィックスAPIをOpenGLからMetalに移行

登録: 2022-09-23 23:21 最終更新: 2022-09-28 21:48

報告者:
yknk
担当者:
yknk
チケットの種類:
サポートリクエスト
状況:
完了
コンポーネント:
MIDITrail Ver.2.x.x for macOS
マイルストーン:
Version 2.0.0 for macOS (完了済み)
優先度:
5 - 中
重要度:
5 - 中
解決法:
修正済み
ファイル:
なし

詳細

Appleは、2018年のmacOS 10.14 MojaveとiOS 12から、OpenGLを非推奨APIと宣言している。 MIDITrailは初回リリース時点からOpenGLを利用してきたが、macOS版の開発を継続するため、 OpenGLからMetalへの移行を実施する。

本修正を契機として、MIDITrailのメジャーバージョンをVer.1からVer.2に変更する。

MIDITrail Ver.1.3.6のサポート対象OSは、OS X 10.8(Mountain Lion)以降である。 MIDITrail Ver.2.0.0では、サポート対象OSをMetalが利用可能となったOS X 10.11(El Capitan)以降(*1)に変更する予定だった。 しかし10.11では、テクスチャ画像が上下反転して読み込まれる(*2)など致命的な不具合が確認されたため、 macOS 10.12(Sierra)以降をサポート対象OSとする。

  • (*1) ただしOSが10.11であっても、Metalがサポートされていない機種が存在する。
  • (*2) MTKTextureLoader:newTextureWithCGImage:options:error

チケットの履歴

2022-09-23 23:21 更新者: yknk
  • 新しいチケット "macOS版 3DグラフィックスAPIをOpenGLからMetalに移行" が作成されました
2022-09-23 23:22 更新者: yknk
コメント

対策1:プロジェクト設定

フレームワーク

フレームワークにMetalを追加してOpenGLを外す。

Targets/General/Frameworks, Libraries, and Embedded Content
 * MetalKit.framework 追加
 * OpenGL.framework 削除

デプロイターゲット

Deployment Targetを10.8から10.12に変更する。 Metalが利用できるのはMac OS X 10.11からであり、Deployment Targetは10.11にする予定だったが、 10.11はテクスチャ画像が上下反転して読み込まれるなど致命的な不具合が確認されたため、10.11の対応は見送る。

Project/Info/Deployment Target
  macOS Deployment Target: Default -> 10.12
Targets/General/Deployment Info
  Deployment Target: 10.8 -> 10.12

ビルド設定

ビルド設定のリンクにMetalKit.frameworkは自動的に追加されていたが、 ビルドすると"Undefined symbol: _MTLCreateSystemDefaultDevice"というエラーが発生する。 xxxxはMetal関連のAPI名称。これを回避するため、手動で設定を追加。

Targets/Build Phases/Link Binary With Libraries
 * Metal.framework 追加
シェーダのソースをコンパイル対象として手動で追加する。(自動で追加されなかった)
Targets/Build Phases/Compile Sources
 * OGLShaders.metal 追加

デバッグ用設定

シェーダのデバッグ機能を利用するため設定を追加する。

Projects/Build Settings/Metal Compiler - Build Options
Produce Debugging Information
  Debug   : Yes, include source code
  Release : No

(編集済, 2022-10-25 21:02 更新者: yknk)
2022-09-23 23:22 更新者: yknk
コメント

対策2:グラフィックライブラリ修正

修正方針

  • OpenGLのラッパークラスであるOGLUtilityのクラス群を、Metalのラッパークラスとして全面的に書き換える。
  • クラス名(OGLXxxxx)は変更せずに引き継ぎ、ライブラリ利用者側の修正範囲を最小限にする。
  • 外部I/Fも可能な限り維持する。
  • Windows版ソースコードを取り込む際にダミークラスとしていたOGLDeviceを、描画制御の橋渡し役として利用する。
  • OpenGLの座標は右手系だが、MetalはDirectXと同じく左手系であるため、Z軸座標のプラスマイナスを反転する。LH2RHマクロの符号反転を無効化する。
  • 左手系の変換行列を利用する。行列の記述方法は、Metal,OpenGL共に列優先(Column major order)。

シェーダ追加

  • OGLShaders.h, OGLShaders.metal を追加。

平行投影カメラクラス追加

  • OGLCameraOrthoクラスを新規追加。背景やカウンターの描画処理をシンプルにするために導入。
2022-09-23 23:23 更新者: yknk
コメント

対策3:メインビュー修正

修正方針

  • Ver.1では、メインスレッドとは別に描画用スレッドを起動し、ディスプレイリンクを使用してレンダリングを実施していた。
  • Ver.2では、メインスレッドでレンダリング処理を実行するオーソドックスな方式に変更すると共に、ディスプレイリンクの使用を取りやめる。
  • ディスプレイリンクを使用したレンダリング処理を実装したが、突然アプリが落ちる不安定な状態になったため取りやめた。

MTMainView

  • 親クラスをNSOpenGLViewからMTKViewに変更。
  • メンバからOpenGLコンテキストとディスプレイリンクを削除。
  • メンバにMetalデバイスを追加。
  • クラス全体からOpenGLとディスプレイリンクの処理を削除。メソッド単位の修正内容は記載しない。

MTMainView:initWithFrame

  • Metal用の初期化処理を追加。

MTMainView:dealloc

  • Metalデバイスの破棄処理を追加。

MTMainView:prepareOpenGL

  • setupCVDisplayLinkに名称を変更。
  • prepareOpenGLをsetupCVDisplayLinkに名称を変更。ただしディスプレイリンクの処理は何もしない。

MTMainView:createScene:seqData

  • レンダラーのシーン初期化処理を追加。

MTMainView:scene_XXXX

  • 描画スレッド廃止に伴い、描画スレッドとのメッセージ交換処理を廃止して、シーンオブジェクトのメソッドを直接呼び出す方式に変更。
    修正対象メソッド
    scene_PlayStart
    scene_PlayEnd
    scene_Rewind
    scene_ResetViewpoint
    scene_SetViewpoint
    scene_GetViewpoint
    scene_SetEffect
    scene_OnMouseClick
    scene_OnMouseWheelWithDeltaX
    scene_OnGameControllerChanged
    

MTMainView:drawInMTKView

  • Metal描画メソッドを追加。MTKViewのデリゲートであり、自動的に呼び出される。

MTMainView:mtkView:drawableSizeWillChange

  • 画面サイズ変更通知メソッドを追加。MTKViewのデリゲートであり、自動的に呼び出される。
  • 通知を利用することはないため、処理なし。

MTMainView:thread_DrawProc

  • レンダリングクラスの引数追加対応。

MTMainWindowCtrl

  • フルスクリーン関連イベントハンドラにログ出力処理を追加。
2022-09-23 23:23 更新者: yknk
コメント

対策4:アプリケーションクラスの修正

MIDITrailAppDelegate::onPreparedOpenGL

  • メソッド名をonPreparedDisplayLinkに変更。

MIDITrailApp::OnPreparedOpenGL

  • メソッド名をOnPreparedDisplayLinkに変更。
2022-09-23 23:23 更新者: yknk
コメント

対策5:シーンクラス共通の修正

シーンクラス共通の修正 MTSceneXXXX

  • OpenGLレンダリングステート設定処理をすべて削除。Metalのレンダリングステート設定処理はOGLPrimitiveクラスに集約。
  • OGLDirLight::SetEnableLights 引数変更対応。
  • ライトON/OFFの明確化。ライトが必要なオブジェクトを描画してから、ライトOFFに切り替えてライト不要のオブジェクトを描画する。

モニタ用シーンクラス共通の修正 MTSceneXXXXLive

  • メンバにMIDI INデバイス名更新フラグm_IsUpdateMIDIINDeviceNameを追加。
  • コンストラクタにMIDI INデバイス名更新フラグの初期化処理を追加。
  • Transformメソッドにて、MIDI INデバイス名更新を検出したときデバイス名をダッシュボードに反映する処理を追加。
  • OnPlayStartメソッドにて、MIDI INデバイス名更新フラグの設定処理を追加。
2022-09-23 23:24 更新者: yknk
コメント

対策6:シーンクラスのライト調整 MTScenePianoRoll3D, MTScenePianoRoll3DLive

MTScenePianoRoll3D::_SetLightColor

  • 鏡面反射光を有効にするためパラメータを0から1に変更。

MTScenePianoRoll3D::_SetLightColor

  • 鏡面反射光を有効にするためパラメータを0から1に変更。
  • 環境光の不透明度を0から1に修正。

MTScenePianoRoll3DLive::_SetLightColor

  • 鏡面反射光を有効にするためパラメータを0から1に変更。

MTScenePianoRoll3DLive::_SetLightColor

  • 鏡面反射光を有効にするためパラメータを0から1に変更。
  • 環境光の不透明度を0から1に修正。
2022-09-23 23:24 更新者: yknk
コメント

対策7:シーンクラスのライト調整 MTScenePianoRollRain, MTScenePianoRollRainLive

ピアノキーボードの画面表示色をVer.1にできるだけ合わせようとしたが、影が黒くなりすぎる問題を解決できなかったため、 2個目のライトを追加して反対方向から照らすことにする。Piano Roll 3Dと同じ。

MTScenePianoRollRain

  • メンバに2個目のライトm_DirLight2を追加。

MTScenePianoRollRain::Create

  • 2個目のライトの初期化処理を追加。
  • ライト1,2のライト色設定処理を追加。
  • ライト1の方向を変更。鏡面反射光の効果を現れやすくするため。

MTScenePianoRollRain::_SetLightColor

  • ライト色設定メソッドを追加。

MTScenePianoRollRain::_SetLightColor2

  • ライト色設定メソッドを追加。

MTScenePianoRollRainLive

  • メンバに2個目のライトm_DirLight2を追加。

MTScenePianoRollRainLive::Create

  • 2個目のライトの初期化処理を追加。
  • ライト1,2のライト色設定処理を追加。
  • ライト1の方向を変更。鏡面反射光の効果を現れやすくするため。

MTScenePianoRollRainLive::_SetLightColor

  • ライト色設定メソッドを追加。

MTScenePianoRollRainLive::_SetLightColor2

  • ライト色設定メソッドを追加。
2022-09-23 23:25 更新者: yknk
コメント

対策8:シーンオブジェクトクラス修正

シーンブジェクト共通の修正

  • OpenGLレンダリングステート設定処理をすべて削除。Metalのレンダリングステート設定処理はOGLPrimitiveクラスに集約。
  • プリミティブオブジェクトの初期化メソッドの引数変更対応。
  • OGLUtilityのクラスのメソッド引数変更対応。
  • 左手系から右手系の座標変換行列設定 transMatrix.RegistScale の処理を削除。

MTBackgroundImage

  • メンバに平行投影カメラオブジェクトm_CameraOrthoを追加。

MTBackgroundImage::Draw

  • カメラオブジェクトの更新処理を追加。

MTDynamicCaption

  • メンバに平行投影カメラオブジェクトm_CameraOrthoを追加。

MTDynamicCaption::Draw

  • カメラオブジェクトの更新処理を追加。

MTStaticCaption

  • メンバに平行投影カメラオブジェクトm_CameraOrthoを追加。

MTStaticCaption::Draw

  • カメラオブジェクトの更新処理を追加。

MTDashboardLive::Create

  • タイトルキャプション設定処理の引数変更に対応。

MTDashboardLive::SetMIDIINDeviceName

  • タイトルキャプション設定処理の引数変更に対応。

MTNoteBox::_MakeMaterial

  • 鏡面反射光の鮮明度を40から20に変更。
  • 発光色の不透明度を0から1に変更。

MTPianoKeyboard::_MakeMaterial

  • 発光色の不透明度を0から1に変更。

MTPianoKeyboardDesign

  • テクスチャUV座標を算出するマクロTEXTURE_POINTについて、0.0-1.0の範囲で座標を算出するように変更。

MTPictBoard::_CreateVertexOfBoard

  • テクスチャUV座標を、0.0-1.0の範囲で座標を算出するように変更。

MTPictBoardRing::_CreateVertexOfBoard

  • テクスチャUV座標を、0.0-1.0の範囲で座標を算出するように変更。
2022-09-23 23:25 更新者: yknk
コメント

対策9:シーンライブラリクラス修正

MTFirstPersonCam::Initialize

  • カメラ初期化時のNearプレーン値を1.0から0.1に変更。カメラに近いポリゴンも描画対象とする。

MTFirstPersonCam::_TransformCamPosition

  • 座標が左手系に変更されたことに伴い、ゲームパッド操作(左右)反映処理のプラスマイナスを逆にする。
  • ゲームパッド操作方向(前後/左右)と、移動スピード(前後/左右)の設定が逆になっていたため、入れ替える。(m_VelocityLR, m_VelocityFB)

MTFontTexture::CreateTexture

  • テクスチャ画像最大サイズをOpenGLから取得せず、固定値に変更する。
2022-09-23 23:26 更新者: yknk
コメント

対策10:視点保存の互換性維持

座標系が右手系から左手系に変わったため、視点パラメータZ,Phiのプラスマイナスが逆になった。

しかしVer.1で保存した視点と、Ver.2で保存した視点の互換性を維持するため、 Ver.2で視点を保存するときと、保存した視点を読み出すときに、パラメータZ,Phiのプラスマイナスを逆にする。

MIDITrailApp::_LoadViewpoint

  • パラメータZ,Phiのプラスマイナスを逆にして読み取る。

MIDITrailApp::_SaveViewpoint

  • パラメータZ,Phiのプラスマイナスを逆にして保存する。

MIDITrailApp::_MoveToMyViewpoint

  • パラメータZ,Phiのプラスマイナスを逆にして読み取る。

MIDITrailApp::_SaveMyViewpoint

  • パラメータZ,Phiのプラスマイナスを逆にして保存する。
2022-09-23 23:27 更新者: yknk
コメント

対策11:シーンクラス カメラ移動方式変更 MTPianoRoll3D, MTPianoRollRing

演奏時間経過に応じて、再生面とカメラをX軸方向に移動させる方式を取りやめ、 再生面とカメラは固定してノートボックスとグリッドボックスを移動させる方式に変更する。

演奏時間が長くなると、再生面とリップルのZファイティングが発生するようになったため。

MTScenePianoRoll3D::OnRecvSequencerMsg

  • 演奏チックタイム通知受信時にチックタイムを反映するオブジェクトを変更。

MTScenePianoRoll3D::_Reset

  • グリッドボックスのリセット処理を追加。

MTScenePianoRollRing::OnRecvSequencerMsg

  • 演奏チックタイム通知受信時にチックタイムを反映するオブジェクトを変更。

MTScenePianoRollRing::_Reset

  • グリッドボックスのリセット処理を追加。

MTGridBox

  • メンバにチックタイムm_CurTickTimeを追加。

MTGridBox::MTGridBox

  • チックタイムの初期化処理を追加。

MTGridBox::Transform

  • チックタイムに応じてグリッドボックスを移動させる。

MTGridBox::SetCurTickTime

  • カレントチックタイム設定メソッドを追加。

MTGridBox::Reset

  • カレントチックタイムリセットメソッドを追加。

MTGridRing

  • メンバにチックタイムm_CurTickTimeを追加。

MTGridRing::MTGridBox

  • チックタイムの初期化処理を追加。

MTGridRing::Transform

  • チックタイムに応じてグリッドボックスを移動させる。

MTGridRing::SetCurTickTime

  • カレントチックタイム設定メソッドを追加。

MTGridRing::Reset

  • カレントチックタイムリセットメソッドを追加。

MTNoteBox::Transform

  • チックタイムに応じた移動ベクトルを取得する処理に変更。ただしチックタイムは更新しない。

MTNoteDesign::GetWorldMoveVector2

  • 世界座標配置移動ベクトル取得メソッドを追加。チックタイムに対応する座標を取得可能とする。

MTNoteDesignRing::GetWorldMoveVector2

  • 世界座標配置移動ベクトル取得メソッドを追加。チックタイムに対応する座標を取得可能とする。
2022-09-23 23:27 更新者: yknk
コメント

対策12:ビューモード設定ファイル

PianoRollRain.ini, PianoRollRainLive.ini, PianoRollRain2D.ini, PianoRollRain2DLive.ini

  • キーボードの色が白くなりすぎないように設定を変更。
    ----
    [PianoKeyboard]
    変更前
    WhiteKeyColor=FFFFFFFF
    BlackKeyColor=FFFFFFFF
    変更後
    WhiteKeyColor=EEEEEEFF
    BlackKeyColor=EEEEEEFF
    
2022-09-23 23:28 更新者: yknk
コメント

対策13:その他修正

MTGraphicCfgDlg::initPopUpButtonAntiAlias

  • OpenGLのパラメータ定義を、OGLUtilityのパラメータ定義に変更。

MTScenePianoRoll3D

  • テスト用ティーポット描画処理を追加してコメント化。

MTScenePianoRollRain

  • テスト用ティーポット描画処理を追加してコメント化。
2022-09-25 21:43 更新者: yknk
  • 詳細が更新されました
2022-09-28 21:48 更新者: yknk
  • 状況オープン から 完了 に更新されました
  • 解決法なし から 修正済み に更新されました

添付ファイルリスト

添付ファイルはありません