Beispiel #1
0
        public void renderSubWindow(int minXChunk, int minZChunk, int maxXChunk, int maxZChunk)
        {
            int numXNodes = (int)(TerrainGlobals.getTerrain().mNumXVerts / BTerrainQuadNodeDesc.cMaxWidth);

            minXChunk = (int)(BMathLib.Clamp(minXChunk, 0, numXNodes - 1));
            minZChunk = (int)(BMathLib.Clamp(minZChunk, 0, numXNodes - 1));
            maxXChunk = (int)(BMathLib.Clamp(maxXChunk, 0, numXNodes - 1));
            maxZChunk = (int)(BMathLib.Clamp(maxZChunk, 0, numXNodes - 1));

            //set LOD Level
            mTerrainGPUShader.mShader.SetValue(mShaderChunkScaleHandle, TerrainGlobals.getTerrain().mTileScale);
            BRenderDevice.getDevice().SetStreamSource(0, mVB, 0);

            mTerrainGPUShader.mShader.BeginPass((int)mPassNum);

            BTerrainQuadNodeDesc[] mNodes = TerrainGlobals.getTerrain().mQuadNodeDescArray;

            for (int i = minXChunk; i < maxXChunk; i++)
            {
                for (int j = minZChunk; j < maxZChunk; j++)
                {
                    int indx = i * numXNodes + j;
                    renderLeafNode(mNodes[indx]);
                }
            }

            mTerrainGPUShader.mShader.EndPass();
        }
Beispiel #2
0
 void renderTerrain()
 {
     TerrainGlobals.getTerrainExportRender().setPassNum(0);
     TerrainGlobals.getTerrainExportRender().preRenderSetup();
     TerrainGlobals.getTerrainExportRender().renderAll();
     TerrainGlobals.getTerrainExportRender().postRender();
 }
Beispiel #3
0
        public void init()
        {
            TerrainGlobals.getLODVB().getLODVB(ref mVB, ref mNumVerts, 0);
            mNumPrims = (uint)((mNumVerts) / 3);

            mPositionsTexture = TerrainGlobals.getTerrain().giveEntireTerrainInTexture();

            loadShader();
        }
Beispiel #4
0
        void renderLeafNode(BTerrainQuadNodeDesc desc)
        {
            int     lod      = (int)BTerrainVisualLODData.eLODLevel.cLOD0;
            float   scale    = TerrainGlobals.getTerrain().mTileScale *((int)Math.Pow(2, lod));
            Vector4 DataVals = new Vector4(2 * (BTerrainQuadNodeDesc.cMaxWidth >> lod), scale, desc.mMinXVert, desc.mMinZVert);

            mTerrainGPUShader.mShader.SetValue(mShaderDataValsHandle, DataVals);
            mTerrainGPUShader.mShader.CommitChanges();
            BRenderDevice.getDevice().DrawPrimitives(PrimitiveType.TriangleList, 0, (int)mNumPrims);
        }
Beispiel #5
0
        void blackoutAO()
        {
            int count = (int)(TerrainGlobals.getTerrain().mNumXVerts *TerrainGlobals.getTerrain().mNumZVerts);

            float[] mAmbientOcclusionValues = TerrainGlobals.getTerrain().mTerrainAOVals;
            for (int i = 0; i < count; i++)
            {
                mAmbientOcclusionValues[i] = 0.0f;
            }
        }
Beispiel #6
0
        void finalGatherSingleThreaded(gatherWorkerData wd)
        {
            {
                float[]   AOVals      = TerrainGlobals.getTerrain().mTerrainAOVals;
                Vector3[] normals     = TerrainGlobals.getTerrain().mTerrainNormals;
                int       numXVerts   = (int)TerrainGlobals.getTerrain().mNumXVerts;
                int       numZVerts   = (int)TerrainGlobals.getTerrain().mNumZVerts;
                Matrix    worldToProj = wd.workdToProj;

                for (int x = 0; x < numXVerts; x++)
                {
                    for (int z = 0; z < numZVerts; z++)
                    {
                        int index = z + x * numXVerts;

                        //only cast rays towards the light..
                        Vector3 nrm = -normals[index];
                        if (BMathLib.Dot(ref nrm, ref wd.rayDir) < 0)
                        {
                            continue;
                        }


                        Vector3 pos  = TerrainGlobals.getTerrain().getPos(x, z);
                        Vector4 vPos = new Vector4(pos.X, pos.Y, pos.Z, 1);
                        Vector4 rPos = BMathLib.vec4Transform(ref vPos, ref worldToProj);
                        rPos = rPos * (1.0f / rPos.W);
                        float depth = rPos.Z;// +0.07f;//CLM this matches the shader...

                        if (rPos.X < -1 || rPos.X >= 1 || rPos.Y < -1 || rPos.Y >= 1)
                        {
                            continue;
                        }

                        //grab our location in the depthGrid (screen space)
                        float xPos = BMathLib.Clamp(0.5f * rPos.Y + 0.5f, 0, 1);
                        float yPos = BMathLib.Clamp(0.5f * rPos.X + 0.5f, 0, 1);


                        int xGridLoc = (int)((wd.imgWidth - 1) * (1 - xPos));
                        int yGridLoc = (int)((wd.imgHeight - 1) * (yPos));

                        if (!wd.fragList[xGridLoc, yGridLoc].anyValueSmaller(depth))
                        {
                            AOVals[index] += wd.rcpNumSamples;
                            Debug.Assert(AOVals[index] <= 1);
                        }
                    }
                }
            }
        }
Beispiel #7
0
        void finalGatherWorker(object workerObjectDat)
        {
            gatherWorkerData workerDat = workerObjectDat as gatherWorkerData;
            int    numXVerts           = (int)TerrainGlobals.getTerrain().mNumXVerts;
            Matrix worldToProj         = workerDat.workdToProj;

            for (int x = workerDat.minXVert; x < workerDat.maxXVert; x++)
            {
                for (int z = workerDat.minZVert; z < workerDat.maxZVert; z++)
                {
                    //only cast rays towards the light..
                    Vector3 nrm = -TerrainGlobals.getTerrain().getNormal(x, z);
                    if (BMathLib.Dot(ref nrm, ref workerDat.rayDir) < 0)
                    {
                        continue;
                    }


                    Vector3 pos  = TerrainGlobals.getTerrain().getPos(x, z);
                    Vector4 vPos = new Vector4(pos.X, pos.Y, pos.Z, 1);
                    Vector4 rPos = BMathLib.vec4Transform(ref vPos, ref worldToProj);
                    rPos = rPos * (1.0f / rPos.W);
                    float depth = rPos.Z;

                    if (rPos.X < -1 || rPos.X >= 1 || rPos.Y < -1 || rPos.Y >= 1)
                    {
                        continue;
                    }

                    //grab our location in the depthGrid (screen space)
                    float xPos     = BMathLib.Clamp(0.5f * rPos.Y + 0.5f, 0, 1);
                    float yPos     = BMathLib.Clamp(0.5f * rPos.X + 0.5f, 0, 1);
                    int   xGridLoc = (int)((workerDat.imgWidth - 1) * (1 - xPos));
                    int   yGridLoc = (int)((workerDat.imgHeight - 1) * (yPos));

                    if (workerDat.fragList[xGridLoc, yGridLoc] != null && !workerDat.fragList[xGridLoc, yGridLoc].anyValueSmaller(depth))
                    {
                        int index = z + x * numXVerts;
                        Interlocked.Increment(ref AmbientOcclusion.AOIncrements[index]);
                    }
                }
            }
            Interlocked.Increment(ref AmbientOcclusion.IncrementCount);

            workerDat.destroy();
            workerDat       = null;
            workerObjectDat = null;
        }
Beispiel #8
0
        public void renderAll()
        {
            //set LOD Level
            mTerrainGPUShader.mShader.SetValue(mShaderChunkScaleHandle, TerrainGlobals.getTerrain().mTileScale);
            BRenderDevice.getDevice().SetStreamSource(0, mVB, 0);

            mTerrainGPUShader.mShader.BeginPass((int)mPassNum);

            BTerrainQuadNodeDesc[] mNodes = TerrainGlobals.getTerrain().mQuadNodeDescArray;
            for (int i = 0; i < mNodes.Length; i++)
            {
                renderLeafNode(mNodes[i]);
            }

            mTerrainGPUShader.mShader.EndPass();
        }
Beispiel #9
0
        public void preRenderSetup()
        {
            BRenderDevice.getDevice().VertexDeclaration = VertexTypes.Pos.vertDecl;

            Matrix g_matView;
            Matrix g_matProj;

            g_matView = BRenderDevice.getDevice().Transform.View;
            g_matProj = BRenderDevice.getDevice().Transform.Projection;
            Matrix worldViewProjection = g_matView * g_matProj;

            mTerrainGPUShader.mShader.SetValue(mShaderWVPHandle, worldViewProjection);
            mTerrainGPUShader.mShader.SetValue(mShaderPositionsTexHandle, mPositionsTexture);
            mTerrainGPUShader.mShader.SetValue(mShaderNumWorldXVertsHandle, TerrainGlobals.getTerrain().mNumXVerts);
            BRenderDevice.getDevice().SetRenderState(RenderStates.CullMode, (int)Cull.None);

            mTerrainGPUShader.mShader.Begin(0);
        }
Beispiel #10
0
            void generateNextDepthLayer(bool renderWorldObjects)
            {
                //CLM this provides accurate depth peeling results (in ISO view...)
                BRenderDevice.getDevice().Clear(ClearFlags.ZBuffer | ClearFlags.Target, (unchecked ((int)0x00000000)), 0, 0);

                TerrainGlobals.getTerrainExportRender().mTerrainGPUShader.mShader.SetValue(mShaderPrevDepthTexture, mDepthBufferC);
                BRenderDevice.getDevice().SetRenderState(RenderStates.ZBufferFunction, (int)Compare.Greater);

                mOC.Issue(IssueFlags.Begin);

                renderTerrain();
                if (renderWorldObjects)
                {
                    renderWoldObjects();
                }

                mOC.Issue(IssueFlags.End);
            }
Beispiel #11
0
        void calculateWorldBounds(ref Vector3 mWorldMin, ref Vector3 mWorldMax, ref BBoundingBox worldBounds, bool renderWorldObjects)
        {
            float tileScale = TerrainGlobals.getTerrain().mTileScale;

            mWorldMin    = TerrainGlobals.getTerrain().mTerrainBBMin; // -new Vector3(tileScale, tileScale, tileScale);
            mWorldMax    = TerrainGlobals.getTerrain().mTerrainBBMax; // +new Vector3(tileScale, tileScale, tileScale);
            mWorldMin.Y -= 1.0f;
            mWorldMax.Y += 1.0f;
            mWorldMin.X  = (float)Math.Floor(mWorldMin.X);
            mWorldMin.Y  = (float)Math.Floor(mWorldMin.Y);
            mWorldMin.Z  = (float)Math.Floor(mWorldMin.Z);
            mWorldMax.X  = (float)Math.Ceiling(mWorldMax.X);
            mWorldMax.Y  = (float)Math.Ceiling(mWorldMax.Y);
            mWorldMax.Z  = (float)Math.Ceiling(mWorldMax.Z);

            worldBounds.min    = mWorldMin;
            worldBounds.min.Y -= 2;
            worldBounds.max    = mWorldMax;
            worldBounds.max.Y += 2;
        }
Beispiel #12
0
        public static void Main(string[] args)
        {
            Xceed.Zip.Licenser.LicenseKey = "ZIN23-BUSZZ-NND31-7WBA";

            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("======Networked AO Gen client V" + cVersion + "=========");
            Console.ForegroundColor = ConsoleColor.White;



            if (!networkAOInterface.networkAccessAvailable())
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("ERROR : access to esfile\\phoenix not available");
                Console.ForegroundColor = ConsoleColor.White;
                return;
            }


            TerrainGlobals.mGameDir = computeGameDir();


            //create D3D as a static function
            PictureBox dumControl = new PictureBox();

            if (!BRenderDevice.createDevice(/*this*/ dumControl, 512, 512, false))
            {
                return;
            }

            TerrainGlobals.getLODVB().init();


            Console.WriteLine("Polling for work");

            //CLM General TRY-CATCH block here to grab anything else I've missed
            try
            {
                while (mStayAlive)
                {
                    pollManagerForAvailableJobs();
                    Thread.Sleep(1000);
                }
            }catch (Exception e)
            {
                //we've died somewhere. Write a crashlog with the exception and time.
                if (!Directory.Exists(AppDomain.CurrentDomain.BaseDirectory + "crashlogs"))
                {
                    Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + "crashlogs");
                }

                string       errorLogName = AppDomain.CurrentDomain.BaseDirectory + "crashlogs\\" + Guid.NewGuid().ToString() + ".txt";
                StreamWriter w            = new StreamWriter(errorLogName, true);
                w.WriteLine(DateTime.Now.ToString());
                w.WriteLine(e.ToString());
                w.Close();

                //send an e-mail to COLT MCANLIS
                sendCrashEmail(errorLogName);

                //now, respawn our app
                Process proc = new Process();
                proc.StartInfo.FileName = AppDomain.CurrentDomain.BaseDirectory + "DistributedLightingClient.exe";
                proc.Start();

                // proc.WaitForExit(60000);
            }

            //another try block here, incase we can't shutdown..
            try
            {
                TerrainGlobals.getLODVB().destroy();
                BRenderDevice.destroyDevice();
            }catch (Exception e)
            {
            }
        }
Beispiel #13
0
        public eReturnCodes generateLighting(string targetFile, string destDir, string issuingName, AmbientOcclusion.eAOQuality quality, int totalNumberOfSections, int targetSectionIndex)
        {
            mAoNumSections  = totalNumberOfSections;
            mAoSectionIndex = targetSectionIndex;
            outputDir       = destDir;

            //load our TLD file
            if (targetFile != "" && File.Exists(targetFile))
            {
                if (!loadTempDataFile(targetFile))
                {
                    return(eReturnCodes.cRC_TDL_LOAD_ERROR);
                }
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("TDL File not specified, or not available.");
                Console.ForegroundColor = ConsoleColor.White;
                return(eReturnCodes.cRC_TDL_NOT_FOUND);
            }



            ////////////////////////////////////////////////////////////////////////////////

            TerrainGlobals.getTerrainExportRender().init();
            ModelManager.init();

            // AmbientOcclusion.eAOQuality quality = AmbientOcclusion.eAOQuality.cAO_Worst;
            int numSamples        = (int)quality;
            int samplesPerSection = (int)(numSamples / mAoNumSections);
            int startSampleCount  = samplesPerSection * mAoSectionIndex;
            int endSampleCount    = startSampleCount + samplesPerSection;

            AmbientOcclusion ao         = new AmbientOcclusion();
            float            totalTime  = 0;
            float            peelTime   = 0;
            float            gatherTime = 0;

            ao.calcualteAO(quality, true, ref totalTime, ref peelTime, ref gatherTime, startSampleCount, endSampleCount);
            ao.destroy();
            ao = null;



            TerrainGlobals.getTerrainExportRender().destroy();
            ModelManager.destroy();


            //////////////////////////////////////////////////////////////////////////
            bool writingOK = true;

            {
                const int cMajik = 0xA001;

                string ouputDumpFilename = outputDir + @"\" + issuingName + ".AO" + targetSectionIndex;

                if (!Directory.Exists(outputDir))
                {
                    Directory.CreateDirectory(outputDir);
                }
                FileStream s = null;
                try
                {
                    s = File.Open(ouputDumpFilename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
                }
                catch (Exception e)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Error writing result to" + ouputDumpFilename);
                    Console.ForegroundColor = ConsoleColor.White;
                    writingOK = false;
                }

                if (writingOK)
                {
                    BinaryWriter f      = new BinaryWriter(s);
                    int          width  = (int)TerrainGlobals.getTerrain().mNumXVerts;
                    int          height = (int)TerrainGlobals.getTerrain().mNumZVerts;

                    //write our header.
                    f.Write(cMajik);
                    f.Write(mAoNumSections);
                    f.Write(mAoSectionIndex);
                    f.Write(numSamples);
                    f.Write(startSampleCount);
                    f.Write(endSampleCount);

                    f.Write(width);
                    f.Write(height);
                    for (int x = 0; x < width; x++)
                    {
                        for (int y = 0; y < height; y++)
                        {
                            float AOVal = TerrainGlobals.getTerrain().getAmbientOcclusion(x, y);
                            f.Write(AOVal);
                        }
                    }

                    f.Close();
                    s.Close();
                }
            }
            if (!writingOK)
            {
                return(eReturnCodes.cRC_OUTPUT_WRITE_ERROR);
            }


            return(eReturnCodes.cRC_OK);
        }
Beispiel #14
0
        bool loadTerrainDat(ZipArchive zip)
        {
            AbstractFile file = zip.GetFile("terrain.TDL");

            if (!file.Exists)
            {
                return(false);
            }

            try
            {
                Stream       stream = file.OpenRead();
                BinaryReader br     = new BinaryReader(stream);

                TLDHeader header = new TLDHeader();
                header.Version = br.ReadInt32();

                //TERRAIN DATA

                TerrainGlobals.getTerrain().mNumXVerts = br.ReadUInt32();
                TerrainGlobals.getTerrain().mNumZVerts = br.ReadUInt32();
                TerrainGlobals.getTerrain().mTileScale = br.ReadSingle();

                TerrainGlobals.getTerrain().mTerrainBBMin = new Vector3();
                TerrainGlobals.getTerrain().mTerrainBBMin.X = br.ReadSingle();
                TerrainGlobals.getTerrain().mTerrainBBMin.Y = br.ReadSingle();
                TerrainGlobals.getTerrain().mTerrainBBMin.Z = br.ReadSingle();

                TerrainGlobals.getTerrain().mTerrainBBMax = new Vector3();
                TerrainGlobals.getTerrain().mTerrainBBMax.X = br.ReadSingle();
                TerrainGlobals.getTerrain().mTerrainBBMax.Y = br.ReadSingle();
                TerrainGlobals.getTerrain().mTerrainBBMax.Z = br.ReadSingle();

                TerrainGlobals.getTerrain().mTerrainRelativePositions = new Vector3[TerrainGlobals.getTerrain().mNumXVerts *TerrainGlobals.getTerrain().mNumZVerts];
                TerrainGlobals.getTerrain().mTerrainNormals           = new Vector3[TerrainGlobals.getTerrain().mNumXVerts *TerrainGlobals.getTerrain().mNumZVerts];
                TerrainGlobals.getTerrain().mTerrainAOVals            = new float[TerrainGlobals.getTerrain().mNumXVerts *TerrainGlobals.getTerrain().mNumZVerts];

                //start reading terrain data
                for (int i = 0; i < TerrainGlobals.getTerrain().mNumXVerts *TerrainGlobals.getTerrain().mNumZVerts; i++)
                {
                    TerrainGlobals.getTerrain().mTerrainRelativePositions[i]   = new Vector3();
                    TerrainGlobals.getTerrain().mTerrainRelativePositions[i].X = br.ReadSingle();
                    TerrainGlobals.getTerrain().mTerrainRelativePositions[i].Y = br.ReadSingle();
                    TerrainGlobals.getTerrain().mTerrainRelativePositions[i].Z = br.ReadSingle();
                }

                for (int i = 0; i < TerrainGlobals.getTerrain().mNumXVerts *TerrainGlobals.getTerrain().mNumZVerts; i++)
                {
                    TerrainGlobals.getTerrain().mTerrainNormals[i]   = new Vector3();
                    TerrainGlobals.getTerrain().mTerrainNormals[i].X = br.ReadSingle();
                    TerrainGlobals.getTerrain().mTerrainNormals[i].Y = br.ReadSingle();
                    TerrainGlobals.getTerrain().mTerrainNormals[i].Z = br.ReadSingle();
                }


                //Read our quadNode Descriptions
                int numQuadNodes = br.ReadInt32();
                TerrainGlobals.getTerrain().mQuadNodeDescArray = new BTerrainQuadNodeDesc[numQuadNodes];
                for (int i = 0; i < numQuadNodes; i++)
                {
                    TerrainGlobals.getTerrain().mQuadNodeDescArray[i]           = new BTerrainQuadNodeDesc();
                    TerrainGlobals.getTerrain().mQuadNodeDescArray[i].mMinXVert = br.ReadInt32();
                    TerrainGlobals.getTerrain().mQuadNodeDescArray[i].mMinZVert = br.ReadInt32();
                }

                br.Close();
                stream.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine("TDL loading FAILED!!!");
                return(false);
            }
            return(true);
        }
Beispiel #15
0
            //-----------------------


            //-------------------------
            void loadShader()
            {
                //grab these values from the TerrainRender shader, so we don't clog that pipe up any more than we have to..
                mShaderPrevDepthTexture = TerrainGlobals.getTerrainExportRender().mTerrainGPUShader.getEffectParam("prevDepthTexture");
            }
Beispiel #16
0
        public void calcualteAO(eAOQuality quality, bool renderWorldObjects, ref float totalTime, ref float peelTime, ref float gatherTime,
                                int startSampleIndex, int endSampleIndex)
        {
            totalTime  = 0;
            peelTime   = 0;
            gatherTime = 0;

            DateTime n = DateTime.Now;


            //should we multithread?
            if (TerrainGlobals.mProcessorInfo.NumLogicalProcessors > 1)
            {
                mUsingMultithreading            = true;
                AmbientOcclusion.IncrementCount = 0;
                AOIncrements = new int[TerrainGlobals.getTerrain().mNumXVerts *TerrainGlobals.getTerrain().mNumZVerts];
            }
            else
            {
                mUsingMultithreading = false;
            }



            int width  = 512;
            int height = 512;

            int numXSegments = 1;
            int numYSegments = 1;

            //special settings for Final mode
            if (quality == eAOQuality.cAO_Final)
            {
                numXSegments = 4; //what should these values really be?
                numYSegments = 4; // they should scale, so that huge terrain gets more segments..

                //   width = 1024;
                //  height = 1024;

                // mUsingMultithreading = false;
            }


            blackoutAO(); //so we can gather light data

            Vector3      mWorldMin   = Vector3.Empty;
            Vector3      mWorldMax   = Vector3.Empty;
            BBoundingBox worldBounds = new BBoundingBox();

            calculateWorldBounds(ref mWorldMin, ref mWorldMax, ref worldBounds, renderWorldObjects);


            mPeeler.init(width, height);

            Vector3 rayDir = -BMathLib.unitY;

            rayDir.Normalize();
            Matrix worldToView = Matrix.Identity;
            Matrix viewToProj  = Matrix.Identity;

            int numDesiredSamples = (int)Math.Sqrt((int)quality);

            int            startIndex = 0;
            int            endIndex   = numDesiredSamples;
            List <Vector3> rayDirs    = null;

            if (startSampleIndex != -1)
            {
                rayDirs    = giveStratifiedOnHemiSphere(0, numDesiredSamples, false);
                startIndex = startSampleIndex;
                endIndex   = Math.Min(endSampleIndex, rayDirs.Count);
            }
            else
            {
                rayDirs    = giveStratifiedOnHemiSphere(0, numDesiredSamples, true);
                startIndex = 0;
                endIndex   = rayDirs.Count;
            }

            float rcpNumSamples = 1.0f / (float)(rayDirs.Count - 1);


            int numSamples = endIndex - startIndex;

            //begin our peel & gather process...
            BRenderDevice.getDevice().BeginScene();
            for (int dc = startIndex; dc < endIndex; dc++)
            {
                //choose one
                rayDir = -rayDirs[dc];

                computeWorldToView(ref rayDir, ref mWorldMin, ref mWorldMax, out worldToView);
                for (int x = 0; x < numXSegments; x++)
                {
                    for (int y = 0; y < numYSegments; y++)
                    {
                        //calculate our lightspace projection matrix
                        computeViewToProj(ref rayDir, worldBounds, worldToView, out viewToProj, numXSegments, numYSegments, x, y);


                        //use worker threads..
                        gatherWorkerData wd = new gatherWorkerData(0, 0, (int)TerrainGlobals.getTerrain().mNumXVerts, (int)TerrainGlobals.getTerrain().mNumZVerts,
                                                                   width, height,
                                                                   rayDir,
                                                                   worldToView * viewToProj,
                                                                   rcpNumSamples);
                        mPeeler.mDepthArray = null;
                        mPeeler.mDepthArray = wd.fragList;



                        //create our depth layers
                        DateTime dpn = DateTime.Now;
                        mPeeler.depthPeel(ref rayDir, ref worldToView, ref viewToProj, renderWorldObjects);
                        TimeSpan dpts = DateTime.Now - dpn;
                        peelTime += (float)dpts.TotalMinutes;



                        //do final gathering (AO SPECIFIC)
                        if (mUsingMultithreading)
                        {
                            finalGatherMultiThreaded(wd);
                        }
                        else
                        {
                            DateTime fgn = DateTime.Now;
                            finalGatherSingleThreaded(wd);
                            TimeSpan fgts = DateTime.Now - fgn;
                            gatherTime += (float)fgts.TotalMinutes;
                        }
                        wd = null;
                        mPeeler.mDepthArray = null;
                    }
                }
            }



            BRenderDevice.getDevice().EndScene();
            mPeeler.destroy();



            //if we're using multithreading, wait for all our worker threads to finish.
            if (mUsingMultithreading)
            {
                while (AmbientOcclusion.IncrementCount <= numSamples - 1)
                {
                    Thread.Sleep(1);
                }

                float[] AOVals = TerrainGlobals.getTerrain().mTerrainAOVals;
                for (int i = 0; i < AOIncrements.Length; i++)
                {
                    AOVals[i] = AOIncrements[i] * rcpNumSamples;
                }
            }

            TimeSpan ts = DateTime.Now - n;

            totalTime = (float)ts.TotalMinutes;
        }