/// <summary>
 /// 描画時に呼び出される3D処理
 /// </summary>
 /// <param name="immediateContext"></param>
 /// <param name="totalTime">アプリケーションが開始してからの経過時間 (秒単位) です。</param>
 /// <param name="elapsedTime">最後のフレームからの経過時間 (秒単位) です。</param>
 /// <param name="oldPriority">1つ前のプライオリティ</param>
 /// <param name="priority">プライオリティ</param>
 /// <param name="cbd"></param>
 /// <param name="callNum">レンダーが呼ばれた回数 0~</param>
 /// <param name="passCount">エフェクトパス 0~</param>
 /// <returns></returns>
 internal abstract int CallDraw3D(
     DeviceContext immediateContext,
     double totalTime,
     float elapsedTime,
     MCDrawCommandPriority oldPriority,
     MCDrawCommandPriority priority,
     MCCallBatchDrawing cbd,
     int callNum,
     int passCount
     );
Exemple #2
0
        /// <summary>
        /// 描画コマンドを解読し、描画処理を開始する
        /// </summary>
        /// <param name="device">レンダリングに使われる D3D11Device デバイス</param>
        /// <param name="immediateContext">描画対象</param>
        /// <param name="totalTime">アプリケーションが開始してからの経過時間 (秒単位) です。</param>
        /// <param name="elapsedTime">最後のフレームからの経過時間 (秒単位) です。</param>
        /// <returns>通常、エラーが発生しなかった場合は 0 を返す。</returns>
        public int AllDrawing(SharpDX.Direct3D11.Device device, DeviceContext immediateContext, double totalTime, float elapsedTime)
        {
            int hr = 0;

            MCCallBatchDrawing callBathDraw;
            int             i, j, nowCnt;
            int             targetMax, targetCnt, translucence;
            int             passCnt;
            float           fZ;
            int             maxPassNum;
            int             cameraSameCheckFlg;
            MCDrawingEffect de;
            IMCEffect       effect;

            if (m_drawingEffectGroup == null)
            {
                goto GOTO_END;
            }
            // エフェクトグループの更新
            m_drawingEffectGroup.OnUpdate(totalTime, elapsedTime);

            // 描画処理を開始したことを知らせるフラグを立てる
            StartAllDrawing();

            m_oldDCRegNum = m_DCRegNum;

            // 実行された描画コマンドのリセット
            m_DCommandRunNum = 0;

            //=============================
            // 描画コマンドをソートする
            //=============================
            Sorting();


            //####################################################
            //# 登録されている対象とするMCDrawingEffectで派生された
            //# クラスの数だけ繰り返す
            //####################################################
            nowCnt = 0;

            foreach (var nowNDEI in m_drawingEffectGroup.GetNoDrawEffectIndexPtr())
            {
                targetMax    = 0;
                translucence = 0;

                // MCDrawingEffectポインタ
                de = nowNDEI.Value;
                //
                callBathDraw = de; Debug.Assert(callBathDraw != null);
                effect       = callBathDraw.GetEffect(); Debug.Assert(effect != null);
                // 前回のカメラの視錘台の値をそのまま使うかチェックフラグ取得
                cameraSameCheckFlg = de.GetCameraSameCheckFlg();


                if (de.IsSimpleProcess && de.RegistrationCount == 0)
                {
                    //==============================//
                    // 単体でもエフェクト処理をする //
                    //==============================//

                    for (i = 0; i < de.CallRenderCount; ++i)
                    {
                        //###############
                        //# レンダー開始
                        hr = de.OnRenderStart(device, immediateContext, totalTime, elapsedTime, i);
                        {
                            if (hr != 0)
                            {
                                de.OnRenderEnd(device, immediateContext, i);
                                Debug.Assert(false);
                                goto GOTO_END;
                            }
                            effect.GetPass(out maxPassNum);

                            for (passCnt = 0; passCnt < maxPassNum; ++passCnt)
                            {
                                effect.SetPass(passCnt);
                                if (de.OnRenderBetweenBefore(device, immediateContext, totalTime, elapsedTime, i, 0) != 0)
                                {
                                    hr = -1;
                                    de.OnRenderEnd(device, immediateContext, i);
                                    Debug.Assert(false);
                                    goto GOTO_END;
                                }
                                if (de.OnRenderBetweenAfter(device, immediateContext, totalTime, elapsedTime, i, 0) != 0)
                                {
                                    hr = -1;
                                    de.OnRenderEnd(device, immediateContext, i);
                                    Debug.Assert(false);
                                    goto GOTO_END;
                                }
                            }
                        }
                        de.OnRenderEnd(device, immediateContext, i);
                        //# レンダー終了
                        //###############
                    }
                }
                else if (de.RegistrationCount > 0)
                {
                    //==============================//
                    //    描画コマンドが存在した    //
                    //==============================//
                    for (i = 0; i < de.CallRenderCount; ++i)
                    {
                        //###############
                        //# レンダー開始
                        hr = de.OnRenderStart(device, immediateContext, totalTime, elapsedTime, i);
                        {
                            if (hr != 0)
                            {
                                de.OnRenderEnd(device, immediateContext, i);
                                Debug.Assert(false);
                                goto GOTO_END;
                            }


                            //=========================
                            // 視錘台の衝突判定チェック
                            //=========================
                            if ((cameraSameCheckFlg & 0x00000001) == 0)
                            {
                                targetMax    = 0;
                                translucence = 0;
                                for (j = 0; j < de.RegistrationCount; ++j)
                                {
                                    MCDrawBase tmpDC = m_aDrawCommand[nowCnt + j];
                                    //-----------------------------------------------------------
                                    // 視錘台と描画対象の衝突チェック
                                    // 場合によっては、ここで対象オブジェクトを半透明化しても良い
                                    //-----------------------------------------------------------

                                    if (
                                        tmpDC.CameraCollison(
                                            de.GetCurrentCamera(),
                                            out fZ)
                                        )
                                    {
                                        //---------------------------------------
                                        // 視錘台内にオブジェクトがあったので登録
                                        //---------------------------------------
                                        // カメラ位置からのZ値をセット
                                        tmpDC.SetZValueFromCamera(fZ);
                                        // そしてターゲット登録
                                        if (!tmpDC.DrawCommandPriority.D3Translucent)
                                        {
                                            // 不透明
                                            m_aDrawComandTarget[targetMax++] = tmpDC;
                                        }
                                        else
                                        {
                                            // 半透明
                                            m_aDCTmp00[translucence++] = tmpDC;
                                        }
                                        ++m_DCommandRunNum;
                                    }
                                }
                                if (translucence > 0)
                                {
                                    //--------------------------
                                    // 半透明オブジェクトソート
                                    //--------------------------
                                    TranslucenceSorting(translucence, ref m_aDCTmp00);
                                    targetMax += translucence;
                                    for (int cnt = 0; cnt < translucence; ++cnt)
                                    {
                                        m_aDrawComandTarget[targetMax + cnt] = m_aDCTmp00[cnt];
                                    }
                                    ResetDCTmp00(translucence);
                                }
                                else
                                {
                                }
                            }
                            cameraSameCheckFlg >>= 1;


                            //=====================
                            // エフェクト
                            //=====================
                            MCDrawCommandPriority priorityTmp, priorityOld = new MCDrawCommandPriority();
                            int targetOffset = 0;
                            //BYTE bNowD3Type;

                            targetCnt = 0;
                            do
                            {
                                // MCDrawCommandPriorityのパラメータを元にテクニックの変更
                                de.OnCheckChangeTechnique(m_aDrawComandTarget[targetCnt]);

                                effect.GetPass(out maxPassNum);
                                for (passCnt = 0; passCnt < maxPassNum; ++passCnt)
                                {
                                    effect.SetPass(passCnt);
                                    if (de.OnRenderBetweenBefore(device, immediateContext, totalTime, elapsedTime, i, passCnt) != 0)
                                    {
                                        hr = -1;
                                        de.OnRenderEnd(device, immediateContext, i);
                                        Debug.Assert(false);
                                        goto GOTO_END;
                                    }

                                    // 最初の一回は前回の物が存在しないため
                                    // 初期化
                                    priorityOld.Init();

                                    for (targetCnt = targetOffset; targetCnt < targetMax; ++targetCnt)
                                    {
                                        //--------------------------
                                        // 描画ターゲットの呼び出し
                                        //--------------------------
                                        priorityTmp = m_aDrawComandTarget[targetCnt].DrawCommandPriority;

                                        if (priorityTmp.D3)
                                        {
                                            //-------------
                                            // 3D属性である
                                            //-------------
                                            if (de.IsCurrentPassCallDraw2D3D)
                                            {
                                                hr = m_aDrawComandTarget[targetCnt].CallDraw3D(
                                                    immediateContext,
                                                    totalTime,
                                                    elapsedTime,
                                                    priorityOld,
                                                    priorityTmp,
                                                    callBathDraw,
                                                    i,
                                                    passCnt
                                                    );
                                            }
                                            if ((targetCnt + 1) < targetMax)
                                            {
                                                if (priorityTmp.D3TypeFlags != m_aDrawComandTarget[targetCnt + 1].DrawCommandPriority.D3TypeFlags ||
                                                    priorityTmp.Technique != m_aDrawComandTarget[targetCnt + 1].DrawCommandPriority.Technique)
                                                {
                                                    // タイプが変わった(例:通常からボーンに変わったとか)
                                                    if (passCnt == (maxPassNum - 1))
                                                    {
                                                        // タイプが変わった所から開始するための処理
                                                        targetOffset = ++targetCnt;
                                                    }
                                                    break;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            // ISprite
                                            if (de.IsCurrentPassCallDraw2D3D)
                                            {
                                                de.SetSpriteTypeNo((int)priorityTmp.D2RenderType);

                                                hr = m_aDrawComandTarget[targetCnt].CallDrawingSprite(
                                                    totalTime,
                                                    elapsedTime,
                                                    de.GetSpriteRenderType(),
                                                    callBathDraw
                                                    );
                                            }
                                            if ((targetCnt + 1) < targetMax)
                                            {
                                                if (priorityTmp.D2RenderType != m_aDrawComandTarget[targetCnt + 1].DrawCommandPriority.D2RenderType ||
                                                    priorityTmp.Technique != m_aDrawComandTarget[targetCnt + 1].DrawCommandPriority.Technique)
                                                {
                                                    // スプライト処理タイプが変わった または
                                                    // テクニックが変わった
                                                    if (passCnt == (maxPassNum - 1))
                                                    {
                                                        // タイプが変わった所から開始するための処理
                                                        targetOffset = ++targetCnt;
                                                    }
                                                    break;
                                                }
                                            }
                                            //-------------
                                        }

                                        // MCDrawCommandPriorityの保存
                                        priorityOld = m_aDrawComandTarget[targetCnt].DrawCommandPriority;
                                    }
                                    if (hr != 0)
                                    {
                                        de.OnRenderEnd(device, immediateContext, i);
                                        Debug.Assert(false);
                                        goto GOTO_END;
                                    }
                                    if (de.OnRenderBetweenAfter(device, immediateContext, totalTime, elapsedTime, i, passCnt) != 0)
                                    {
                                        hr = -1;
                                        de.OnRenderEnd(device, immediateContext, i);
                                        Debug.Assert(false);
                                        goto GOTO_END;
                                    }
                                }
                            } while (targetCnt < targetMax);
                        }
                        de.OnRenderEnd(device, immediateContext, i);
                        //# レンダー終了
                        //###############
                    }
                    // m_paDCRegの位置を移動させるために加算
                    nowCnt += de.RegistrationCount;
                }
                else
                {
                    //==============================//
                    //     単体の場合処理しない     //
                    //==============================//
                }
            }


GOTO_END:

            //=====================================
            // リセットする
            //=====================================
            AllDrawingReset();

            // 描画処理を終了したことを知らせるフラグを立てる
            EndAllDrawing();


            return(hr);
        }