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(); }
void renderTerrain() { TerrainGlobals.getTerrainExportRender().setPassNum(0); TerrainGlobals.getTerrainExportRender().preRenderSetup(); TerrainGlobals.getTerrainExportRender().renderAll(); TerrainGlobals.getTerrainExportRender().postRender(); }
public void init() { TerrainGlobals.getLODVB().getLODVB(ref mVB, ref mNumVerts, 0); mNumPrims = (uint)((mNumVerts) / 3); mPositionsTexture = TerrainGlobals.getTerrain().giveEntireTerrainInTexture(); loadShader(); }
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); }
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; } }
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); } } } } }
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; }
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(); }
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); }
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); }
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; }
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) { } }
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); }
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); }
//----------------------- //------------------------- 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"); }
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; }