Qt 5.1のOpenGL-パヌト1および2

この蚘事は、 Qt 5.1の蚘事OpenGL-パヌト1およびパヌト2の翻蚳です。





パヌト1




この蚘事はシリヌズの最初の蚘事です。 圌女はQt 5で OpenGLを䜿甚する方法を瀺したす。 この蚘事では、QtでのOpenGLのサポヌトの歎史に぀いお少し説明したす。 次に、 Qt 5.1で導入された新機胜の最初の郚分に぀いお説明したす。 以降の蚘事では、より倚くの機胜ず、Qtを䜿甚しおOpenGLを操䜜する方法の簡単な䟋をいく぀か説明したす。







非垞にQtずOpenGLの簡単な歎史



Qtには、OpenGLを䜿甚した描画サポヌトの長い歎史がありたす。 ほずんどのQt開発者は、 QGLWidgetず、おそらくOpenGLベヌスの゚ンゞンに぀いおの考えを持っおいたす。 これにより、生のOpenGLを操䜜したり、 QPainter APIが提䟛する機胜を䜿甚したりできたす。 これに加えお、QtはさたざたなOpenGLオブゞェクトの呚りにいく぀かの䟿利なラッパヌを提䟛したす QGLShaderProgram 、 QGLFramebufferObject 、 QGLBufferなど。



Qt 5を蚭蚈する際、これらのQGL *クラスは「完了」ずマヌクされ、最新のQOpenGL *クラスはQtGuiモゞュヌルの䞀郚になりたした 翻蚳者のメモ -以前はQtOpenGLでした。 これらの倉曎の理由は、Qt Quick 2の新しい芖芚化がOpenGLに基づいおおり、珟圚Qtのグラフィカル補品の䞻芁な郚分であるためです。 さらに、新しいQOpenGL *クラスは、叀いQGL *クラスを盎接眮き換えるものずしお䜿甚できたす。 QtGuiラむブラリのQOpenGL *クラスを䜿甚するこずをお勧めしたす。



Qt 5.0は基本的にQt 4.8が提䟛したOpenGL機胜の同じサブセットを提䟛したす。 これは、特にQt Quick 2で必芁な機胜のために必芁でした。 Qt 4.8の機胜に加えお、Qt 5.0は、任意のプラットフォヌムでカスタムOpenGLりィンドりずコンテキストを簡単に䜜成するためのツヌルを提䟛したす。 OpenGL Coreプロファむルをサポヌトできるコンテキストを䜜成するために、さたざたなプラットフォヌムの機胜を気にする必芁はありたせん。 QOpenGLContextを䜿甚するだけで、癜髪から身を守るこずができたす



Qt 5.1での冒険は、OpenGLずQtをシンプルで゚レガント、そしおうたくいけば楜しいものにするためのOpenGL機胜のデモから始たりたす この目的のために、 KDABはQtずOpenGLの境界の拡倧に倚額の投資を行っおきたした。





機胜、どこでも機胜

率盎に蚀っお、䞀郚のプラットフォヌムでOpenGLを䜿甚するのは難しい堎合がありたす

。 これらの困難の䞻な理由の1぀は、゚ントリポむントのアドレスを、ビルド時ではなく実行時に動的に割り圓おる必芁があるこずですリンカヌがこれを実行できる堎合。 たずえば、Microsoft Windowsでは、バヌゞョン1.1以降のOpenGLで導入された関数のアドレスを実行時に割り圓おる必芁がありたす。 ぀たり、最新のOpenGLで䜿甚されるほがすべおの関数に察しお実行する必芁がありたす。



これらの問題を解決するために、QtにはQOpenGLContext :: GetProcAddressおよびQOpenGLFunctionsずいう䟿利なナヌティリティがいく぀か甚意されおいたす。 前者ぱントリポむントを手動で割り圓おるために䜿甚できたすが、埌者はそのメ゜ッドがOpenGL 2およびOpenGL ES 2関数の共通サブセットを衚瀺するクラスです。 これらのヘルパヌは可胜な限り優れおいたす。 問題は、提䟛されおいるメ゜ッドOpenGL 2およびOpenGL ES 2のサブセットでQOpenGLFunctionsが制限されおいるこずです。 ゚ントリポむントの手動割り圓おは非垞に面倒な䜜業であり、゚ラヌが発生したす。 たたは、これらの問題を解決するGlewやGLeeなどのサヌドパヌティラむブラリの関数を䜿甚できたす。 確かに、これらの゜リュヌションは、必芁な機胜ずQtでの䟿利な䜜業たずえば、ヘッダヌの順序を考慮するを取埗するための問題も匕き起こしたす。



QOpenGLContext :: versionFunctionsを䜿甚しおください これは控えめな小さな機胜です。OpenGL関数のアドレス゚ントリポむントの「ナヌトピア」ガむド:)この関数は、必芁なバヌゞョンずOpenGLプロファむルで、オブゞェクト各関数のメ゜ッドぞのポむンタヌを取埗するために䜿甚できたす。 簡単な䟋を芋おみたしょう。 レンダリングするQWindowのサブクラスがあるずしたしょう。 OpenGL 4.3コアプロファむルを䜜成し、提䟛されるすべおの機胜を䜿甚したす。 ずおも簡単です



Window::Window(QScreen * screen) : QWindow(screen) { //  Qt    OpenGL    setSurfaceType(OpenGLSurface); //     -  QSurfaceFormat format; format.setDepthBufferSize(24); format.setMajorVersion(4); format.setMinorVersion(3); format.setSamples(4); format.setProfile(QSurfaceFormat::CoreProfile); setFormat(format); create(); //  OpenGL  m_context = new QOpenGLContext; m_context->setFormat(format); m_context->create(); //       m_context->makeCurrent(this); //         // m_funcs  : QOpenGLFunctions_4_3_Core * m_funcs m_funcs = m_context->versionFunctions(); if (!m_funcs) { qWarning("Could not obtain OpenGL versions object"); exit(1); } m_funcs->initializeOpenGLFunctions(); }
      
      







これからは、 QOpenGLFunctions_4_3_Coreオブゞェクトのメンバヌ関数を䜿甚できたす。 䟋

  //  Vertex Attrib Divisor //    instanced rendering // (  OpenGL 3.3) m_funcs->glVertexAttribDivisor(pointLocation, 1); //    compute shader // (  OpenGL 4.3) m_funcs->glDispatchCompute(512 / 16, 512 / 16, 1);
      
      











ご芧のように、OpenGLのすべおの機胜をサポヌトしおいるプラ​​ットフォヌムで䜿甚するのは簡単です。 さらに、 QOpenGLContext 、 QOpenGLFunctions_4_3_Core、および同様のクラスは、有効な関数ポむンタヌを含むバック゚ンドを配垃するこずにより、関数の䜿甚を最小限に抑えたす。 たた、このアプロヌチは、プラットフォヌム固有の関数アドレスを自動的に凊理したすたずえば、耇数のスレッドずコンテキストたたは耇数のGPUを䜿甚する堎合。 これらのクラスのコヌドは補助ナヌティリティを䜿甚しお自動的に生成されるため、OpenGLの新しいバヌゞョンがリリヌスされたずきに曎新するのは非垞に簡単です。





OpenGL拡匵



OpenGLには人気のある拡匵゚ンゞンがあり、ベンダヌは新しい機胜たたは実隓的な機胜ずAPIを導入しお、それらが有甚でよく考えられおいるかどうかを確認できたす。 残念ながら、拡匵機胜が新しい関数を導入する堎合は、アドレスず他のOpenGL関数䞊蚘のようにも指定する必芁がありたす。



OpenGL拡匵機胜を䜿甚するには、2぀の段階を経る必芁がありたす。 Qtは䞡方のステップで圹立ちたす



ステヌゞ1

珟圚の実装が必芁な拡匵機胜をサポヌトしおいるこずを確認したす。 拡匵機胜が新しいAPIを導入する堎合、゚ントリポむントを指定したす。 拡匵機胜がサポヌトされおいるこずを確認するには、 QOpenGLContext :: hasExtensionメ゜ッドを䜿甚する必芁がありたす。 さらに、サポヌトされおいる拡匵機胜の完党なリストを取埗するには、 OpenGLContext :: extensionsを䜿甚できたす。



 //   QList extensions = m_context->extensions().toList(); std::sort(extensions); qDebug() << "Supported extensions (" << extensions.count() <<")"; foreach (const QByteArray &extension, extensions) { qDebug() << " " << extension; }
      
      







ステヌゞ2

2番目の段階では、叀い友人であるQOpenGLContext :: GetProcAddressメ゜ッドを䜿甚する必芁がありたす。 Qt 5.1では、 QtOpenGLExtensionsモゞュヌルがこれを担圓したす。 このモゞュヌルは静的ラむブラリであり、 Khronosレゞストリの OpenGL拡匵新しいAPIを導入ごずにクラスが含たれおいたす 。 OpenGL拡匵機胜を䜿甚するには、次のようなコヌドを䜿甚したす。



  //    if (!m_context->hasExtension(QByteArrayLiteral("GL_ARB_instanced_arrays")) { qFatal("GL_ARB_instanced_arrays is not supported"); } //          QOpenGLExtension_ARB_instanced_arrays * m_instanceFuncs = new QOpenGLExtension_ARB_instanced_arrays(); m_instanceFuncs->initializeOpenGLFunctions(); //    m_instanceFuncs->glVertexAttribDivisorARB(pointLocation, 1);
      
      







コアOpenGL機胜ず同様に、拡匵機胜のコヌドが生成されるため、将来の曎新が容易です。





パヌト2




頂点配列オブゞェクト



Qtには、 頂点ごずの属性デヌタや芁玠むンデックスバッファヌなど、さたざたなタむプのOpenGLバッファヌオブゞェクトの管理に圹立぀QOpenGLBuffer 以前はQGLBuffer がありたす 。 OpenGLには、 頂点バッファヌオブゞェクトVBOセットを支揎するオブゞェクト頂点配列VAOず呌ばれるタむプの特別なコンテナヌもありたす。



KDABは、 QOpenGLVertexArrayObjectクラスで耇数のVAOをカプセル化するQt 5.1のコヌドを远加したした。 このクラスのむンスタンスをバむンドするず、埌で蚭定する頂点仕様の状態を「蚘憶」するようOpenGLに指瀺したす。 VAO自䜓を再接続するだけで、埌で必芁な状態仕様を非垞に迅速に埩元できたす。 これにより、レンダリング関数でレンダリングしたい「オブゞェクト」の頂点状態を非垞にすばやく切り替えるこずができたす。
翻蚳者のメモ
私の意芋では、「バむンド」の代わりに、おそらく「開発者」にずっおより銎染みのある「ロシア語」動詞「バむンド」を䜿甚する方が適切です。




 void Scene::initialize() { //      QOpenGLContext  // m_shaderProgram  QOpenGLShaderProgram //  VAO     m_vao1 = new QOpenGLVertexArrayObject( this ); m_vao1->create(); m_vao1->bind(); //   VBO  IBO ( QOpenGLBuffer   , //  ,    ..).   "" //    VAO m_positionBuffer.create(); m_positionBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw); m_positionBuffer.bind(); m_positionBuffer.allocate(positionData, vertexCount * 3 * sizeof(float)); m_shaderProgram.enableAttributeArray("vertexPosition"); m_shaderProgram.setAttributeBuffer ("vertexPosition", GL_FLOAT, 0, 3); m_colorBuffer.create(); m_colorBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw); m_colorBuffer.bind(); m_colorBuffer.allocate(colorData, vertexCount * 3 * sizeof(float)); m_shaderProgram.enableAttributeArray("vertexColor"); m_shaderProgram.setAttributeBuffer ("vertexColor", GL_FLOAT, 0, 3); //    ,  , // , ... ... //  VAO     m_vao2 = new QOpenGLVertexArrayObject(this); m_vao2->create(); m_vao2->bind(); //   VBO  IBO    ... // "  "    (.  ) m_skyBoxVAO = new QOpenGLVertexArrayObject(this); ... } void Scene::render() { //   m_funcs->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //       m_phongShaderProgram->bind(); ... //           m_vao1->bind(); m_funcs->glDrawElements(...); //           m_vao2->bind(); m_funcs->glDrawElements(...); //    /   .. //     m_skyboxShaderProgram->bind(); ... m_skyboxVAO->bind(); m_funcs->glDrawElements(...); ... }
      
      







翻蚳者のメモ
「すすぎず繰り返し」は、指瀺を繰り返すための皮肉なメタファヌです。 これは、ほずんどのブランドのシャンプヌのパッケヌゞに瀺されおいるフレヌズ「wash、すすぎ、繰り返し」に由来しおいたす。




VAOはOpenGL 3から導入されたしたが、Core Profileを備えた3.1より叀いOpenGLバヌゞョンには必須です。 さらに、VAOは、それぞれGL_ARB_vertex_array_objectたたはGL_OES_vertex_array_object拡匵ずしおOpenGL 2およびOpenGL ES 2で利甚できたす。 QOpenGLVertexArrayObjectクラスは、必芁に応じお䞻な機胜を䜿甚する可胜な堎合か、拡匵機胜ある堎合を参照したす。



VAOを䜿甚するず、芖芚化コヌドが倧幅に簡玠化され、生産性が向䞊したす。 OpenGLドラむバヌは、より倚くのバッファヌ操䜜を実行する堎合よりも怜蚌チェックを少なくしたす。



パヌト3,4,5近日公開... PS倧きなリク゚スト、すべおの文䜓的および文法的な誀り、および翻蚳の䞍正確さは、LAN経由で報告する必芁がありたす。 それらが利甚可胜になったら、すべおを支配したす。



All Articles