OpenGL Framebufferのオブジェクト化


Open GELのフレームバッファ要素をどのようにオブジェクト化するかを常に考えています.
実際、レンダリングプログラミングを行う場合、フレームバッファは
チュートリアルでたまに見るフレームバッファの作成部分がすべてです.
この时間は対象化されていないのではないかと思います.ハハ.
しかし、ゲームを作るときにフレームバッファの概念をよく使う.
オブジェクト化する必要があります!
こうしてオブジェクト化された.
まず,フレームバッファの基本概念を以下のリンクで置き換える.
  • LeanOpenGL Framebufferチュートリアル
  • LeanOpenGL Render to textureチュートリアルソース
  • 1.オブジェクト化の方法


    Unityのレンダリングテクスチャの概念を参考にして作成することにしました.
    レンダーテクスチャもフレームバッファ自体だから!
    次に、次のルールを作成して符号化することにしました.
  • フレームバッファ(レンダリングテクスチャ)は、リソースの概念です.
  • カメラにはフレームバッファがあります.
  • レンダリング順序は광원 그림자 깊이버퍼 → 서브 프레임버퍼 → 메인 프레임버퍼です.
  • これらのルールを制定する理由は簡単です.
    Unityを参考にゲームエンジンを作る過程で、Unityを使ってオブジェクト化概念を捉えるのは便利です.
    「UNITYは嫌いだ!Unityとは違うものを作りたいけど.
    最終的にはunityのようなデザインが一番便利になりましたハハハ
    こうして第1条第2条のルールが決定された.
    最後のレンダリング順は本当に悩んでいます
    レンダリングキューとシェーダに基づいてレンダリング順序を決定したためです.
    ここでは大きな意味で順番を決めるべきだと思いますから.
    そして私は以上の方法を考えました.
    フィードバックをもらえる場所がないので急いで決めた順番がちょっともったいないううう
    このスレにフィードバックしてくれるとありがたいですが
    とりあえずこのままやってましたハハ

    2.設計によるコード作成


    実際、コードの作成は、チュートリアルのクラスに基づいてコードを作成するだけです.
    もしあなたが完全なコードがほしいならば、私のGitの上で確認することができて、ほほほ

    framebufferクラス

    class SFrameBuffer : public STexture {
        public:
            enum BufferType {
                RENDER = 0, DEPTH = 1, STENCIL = 2,
            };
        public:
            SFrameBuffer();
            ~SFrameBuffer();
    
            void InitFrameBuffer(BufferType type, int width, int height);
            void AttachFrameBuffer(int index = 0, int level = 0) const;
            void DetachFrameBuffer() const;
    };
    まず、フレームバッファはテクスチャを継承して動作するように設計されています.
    フレームバッファとテクスチャはそれぞれ異なる概念ですが...
    大型バッファではなく、テクスチャに描かれたすべてなので、テクスチャに継承します.
    特殊なテクスチャレベル!
    いつの間にかUnityと差が少ない!なんてことだ!

    CameraComponentクラス

    class SFrameBuffer;
    
    class CameraComponent : public SComponent, public CameraBase {
    public:
        
        ...
        
        SFrameBuffer* GetFrameBuffer() const override;
        void SetFrameBuffer(SFrameBuffer* frameBuffer);
        
    private:
        SFrameBuffer* m_frameBuffer = nullptr;
        ...
        
    };
    うん.カメラ構成部品の最後は、既存の構成部品で作成したばかりのフレームバッファクラスを入れることです.
    でも大事なポイントなので短くしましたへへへ

    RenderMgr::Render()関数

    
    void RenderMgr::Render() const {
        // Render Order : Depth Buffers -> Render Buffers -> Main Render Buffer
    
        // 1. Render depth buffer for shadows.
        const auto& lightObjects = lightMgr->GetAll();
        const auto& shadowObjects = lightMgr->GetShadowObject();
        const auto& shadowEnvironment = m_environmentMgr->GetShadowEnvironment();
        for (const auto& light : lightObjects) {
            if(light->m_disableShadow) continue;
            RenderShadowInstance(*light, *shadowEnvironment, shadowObjects);
        }
        lightMgr->RefreshShadowCount();
    
        const auto& cameraObjects = cameraMgr->GetAll();
        const auto& mainCamera = cameraMgr->GetCurrentCamera();
    
        // 2. Render active sub cameras.
        for (const auto& camera : cameraObjects) {
            if(!camera->GetIsEnable() || camera == mainCamera || camera->GetFrameBuffer() == nullptr) continue;
            RenderInstance(*camera);
        }
    
        if(mainCamera == nullptr) return;
        // 3. Main Render Buffer
        RenderInstance(*mainCamera);
    
    }
    ここでは私が言ったレンダリング順に先にバーコードで打ってみました
    今まで、これが一番いい方法だと思います.ほほほ
    もちろん、ジッタレンダリングを実施する場合、反転する確率は100%です.
    まず今このように編んでから私は自分で修正します!
    がんばって未来の私!
    本題に戻る.
    その関数で最も書きにくいのは光源シャドウバッファです.
    厄介な原因は以下の通りです.
  • シャドウをレンダーするかどうかは、Render Componentによって決定されます.
    既存のレンダリングキューとは異なる方法でコードを記述してこそ、効率が向上します.
  • シャドウは、カメラではなく光源に基づいています.
  • シャドウの識別範囲は異なる.
  • 単独レンダリングは好きではありません...ブラック
  • だから最終的には...CameraBaseというインタフェースを作成し、カメラと光源にすべて継承します.
    レンダーには、既定のレンダーとシャドウレンダーがあります.

    3.実施完了!


    少し気分が悪くなりましたが基本的な実現は終わりました
    フレームバッファをオブジェクト化することで、レンダリングでレンダリングできます.
    反射、シャドウ、奥行きに関するレンダリングも便利になります!
    OpenVRでvrレンダリングできるようになりました!
    問題が発生したら...未来の私はここで新しいリンクを通じて解決策を提供します!
    未来の私に感謝します!
    📣 関連項目Gitアドレス:https://github.com/ounols/CSEngine