/// <summary> /// prepare matrices for rendering /// TODO: Optimize calcs only when dirty /// </summary> /// <param name="viewproj"></param> /// <param name="parentmodel"></param> public void CalculateDrawMatrices(Matrix4d viewproj, Matrix4d parentmodel) { WorldTransform = transform.GetMatrix() * parentmodel; transform.WorldPosition = WorldTransform.ExtractTranslation(); mvp = MTransform.GetFloatMatrix(WorldTransform * viewproj); modelMatrix = MTransform.GetFloatMatrix(WorldTransform); }
public void PrepareGrass(MTerrainTile tile) { MTerrainTile Tile = tile; Matrix4d TreeRotation = Matrix4d.CreateFromQuaternion(Quaterniond.FromEulerAngles(tile.transform.Up())); float numxinterps = LOD0Size / Tile.x_res; float numzinterps = LOD0Size / Tile.z_res; for (int x = 0; x < LOD0Size; x++) { for (int z = 0; z < LOD0Size; z++) { Vector3d PlantingPos = new Vector3d((x / numxinterps), 0, (z / numzinterps)); //PlantingPos = Tile.GetInterpolatedPointOnSurfaceFromGrid2(PlantingPos); //double y = tile.ElevationAtPoint(x / numxinterps, z / numzinterps); //PlantingPos = new Vector3d(x, y, z); PlantingPos = Tile.GetInterpolatedPointOnSurfaceFromGrid2(PlantingPos); Matrix4d TreeScale = Matrix4d.Scale(10, 10, 10); Matrix4d TreePosition = Matrix4d.CreateTranslation(PlantingPos); Matrix4 final = MTransform.GetFloatMatrix(TreeScale * TreeRotation * TreePosition); Grassmats[x, z] = final; } } IsComplete = true; Console.WriteLine("Grass Planted:" + Tile.TileX + "," + Tile.TileY); }
public void PlantPatch(Barycentric bary, int BladeCount = 4096, double Area = 1.1, double MaxHeight = 1) { double sq2 = Math.Sqrt(BladeCount); Matrix4d TreeRotation = Matrix4d.CreateFromQuaternion(Globals.LocalUpRotation()); Matrix4d TreePosition; Matrix4 final; Matrix4d TreeScale; Vector3d PlantingPos = new Vector3d(); int bposx = (int)(Tile.x_res * (1 - bary.u)); int bposz = (int)(Tile.z_res * (bary.v)); // Tile.Biome.SetPixel(bposx, bposz, new float[] { 0, 1, 0, 1 }); for (int x = (int)-sq2; x < sq2; x++) { for (int z = (int)-sq2; z < sq2; z++) { bposx = (int)(Tile.x_res * (1 - bary.u)) - x; bposz = (int)(Tile.z_res * (bary.v)) - z; int t = Tile._biome.GetBiomeAt(bposx, bposz); if ((t != MBiome.GRASS) && (t != MBiome.TREES) && (t != MBiome.TREES2) && (t != MBiome.WATER)) { continue; } PlantingPos.X = (int)(Tile.x_res * (1 - bary.u)) - x * 0.05 * Area; PlantingPos.Y = 0; PlantingPos.Z = (int)(Tile.z_res * (bary.v)) - z * 0.05 * Area; double yv = (MPerlin.Noise(PlantingPos.X, PlantingPos.Z) * 0.4) + (MPerlin.Noise(PlantingPos.X * 1.1, PlantingPos.Z * 1.1) * 0.4) ; //if (yv < 0.01) continue; TreeScale = Matrix4d.Scale(0.05 + 0.06 * yv, 0.01 + Math.Abs(yv) * 0.15 * MaxHeight, 0.05 + 0.06 * yv); PlantingPos.X += MPerlin.Noise(PlantingPos.X * 4.0, 0, PlantingPos.Z * 2.0) * 1.1; PlantingPos.Z += MPerlin.Noise(PlantingPos.X * 4.0, 0, PlantingPos.Z * 2.0) * 1.1; PlantingPos = Tile.GetInterpolatedPointOnSurfaceFromGrid2(PlantingPos); TreePosition = Matrix4d.CreateTranslation(PlantingPos); final = MTransform.GetFloatMatrix(TreeScale * TreeRotation * TreePosition); if (TotalInstances < Settings.MaxGrassPerTerrain) { mats[TotalInstances] = final; TotalInstances++; } } } }
public void PlaceInstances(Vector3d Anchorpoint) { //DistanceThreshold = tile.DistanceThreshold; this.transform.Position = Anchorpoint; Random ran = new Random(1234); Matrix4d TreeRotation = Matrix4d.CreateFromQuaternion(Globals.LocalUpRotation()); int i = 0; for (int z = 0; z < 30; z++) { for (int x = 0; x < 30; x++) { if (i >= MaxInstances) { break; } //Vector3d pos = new Vector3d(1000 * ran.NextDouble(), 200 * ran.NextDouble(), 1000 * ran.NextDouble()); Vector3d pos = MassiveTools.RandomPointInSphere(Vector3d.Zero, 1000, ran); //Vector3d PlantingPos = planet.GetNearestPointOnSphere(SeedPos + Treepos, 0) - SeedPos; double scale = MinSize + ran.NextDouble() * (MaxSize - MinSize); Matrix4d TreeScale = Matrix4d.Scale(scale, scale, scale); Matrix4d TreePosition = Matrix4d.CreateTranslation(pos); TreeRotation = Matrix4d.CreateFromQuaternion( Quaterniond.FromEulerAngles( ran.NextDouble(), ran.NextDouble(), ran.NextDouble())); //find point at y with raycast Matrix4 final = MTransform.GetFloatMatrix(TreeScale * TreeRotation * TreePosition); mats[i] = final; i++; } } TotalInstances = i; //null out the remainder for (int j = TotalInstances; j < MaxInstances; j++) { Matrix4 final = Matrix4.Identity; mats[j] = final; } Planted = false; }
/** * During the Rendering phase all matrices are pre-multiplied (to bring coordinates back to local 32bit space) * and all offsets and set relative to the camera, to aid with shadow calculations - * */ public void Render() { GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); Globals.ShaderOverride = null; Globals.DrawCalls = 0; Globals.Index = 0; Globals.GlobalOffset = Camera.transform.Position; Globals.GlobalOffsetCalc = Camera.transform.Position; Matrix4d offsetmat = Matrix4d.CreateTranslation(-Globals.GlobalOffset); Matrix4d lightmatrix = light.GetLightSpaceMatrix(); Matrix4d view = Camera.GetViewMatrix(); Matrix4d projection = Camera.GetProjection(true); Matrix4d viewproj = view * projection; // GL.Viewport(0, 0, MScreen.Width, MScreen.Height); //============================ // Globals.GlobalOffset = Vector3d.Zero; // GL.CullFace(CullFaceMode.Back); // reset viewport // 2. render scene as normal using the generated depth/shadow map // -------------------------------------------------------------- for (int i = 0; i < MaterialRoot.Modules.Count; i++) { MMaterial mat = (MMaterial)MaterialRoot.Modules[i]; if (mat.IsUsed == false) { continue; } mat.shader.Bind(); mat.shader.SetMat4("view", MTransform.GetFloatMatrix(view)); mat.shader.SetMat4("projection", MTransform.GetFloatMatrix(projection)); mat.shader.SetVec4("Tweak", new Vector4(Settings.Tweak1, Settings.Tweak2, Settings.Tweak3, Settings.Tweak4)); // set light uniforms Fog.Bind(mat.shader); //TODO: use nearest lights mat.shader.SetInt("NumLights", LightRoot.Modules.Count); //TODO sort lights closest to furthest (because there is max lights =10 in shader) for (int il = 0; il < LightRoot.Modules.Count; il++) { if (il >= MAXLIGHTS) { continue; } //pointLightPositions[0] MPointLight p = (MPointLight)LightRoot.Modules[il]; p.Bind(mat, il); } mat.shader.SetVec3("viewPos", MTransform.GetVector3(Camera.transform.Position - Globals.GlobalOffset)); mat.shader.SetVec3("sunPos", MTransform.GetVector3(light.transform.Position - Globals.GlobalOffset)); mat.shader.SetInt("Closeup", Closeup); light.Bind(mat); } /////////////////////// DEPTH LIGHT FOR SHADOWS /////////////////////// GL.Viewport(0, 0, MScreen.Width, MScreen.Height); // GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); if (light.Shadows) { GL.Enable(EnableCap.CullFace); GL.CullFace(CullFaceMode.Back); //GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); Globals.RenderPass = Globals.eRenderPass.ShadowDepth; //============================ //render depthmap from light using depth shader light.Render(lightmatrix, offsetmat); simpleDepthShader.Bind(); Globals.ShaderOverride = simpleDepthShader; GL.DepthFunc(DepthFunction.Less); GL.Enable(EnableCap.DepthTest); //Background.Render(lightmatrix, offsetmat); //GL.Clear(ClearBufferMask.DepthBufferBit); Background2.Render(lightmatrix, offsetmat); ModelRoot.Render(lightmatrix, offsetmat); Globals.RenderPass = Globals.eRenderPass.Normal; Globals.ShaderOverride = null; } //============================ ////////////////// NORMAL RENDER //////////////////// GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); //Helper.CheckGLError(this, "Render 1"); //set FBO Renderer.Render(viewproj, offsetmat); //Helper.CheckGLError(this, "Render 1"); //load the shadow map into texture slot 4 GL.ActiveTexture(TextureUnit.Texture0 + MShader.LOCATION_SHADOWMAP); GL.BindTexture(TextureTarget.Texture2D, light.depthMap); //////////////////////////////////////////////////////// // GL.PatchParameter(PatchParameterInt.PatchVertices, 16); RenderScene(ref view, ref offsetmat, ref projection, ref viewproj); //////////// OVERLAY LAYER //////////// //============================ GL.Disable(EnableCap.DepthTest); GL.Clear(ClearBufferMask.DepthBufferBit); if (Overlay.Modules.Count > 0) { projection = Camera.GetOverlayProjection(); view = Camera.GetOverlayViewMatrix(); viewproj = view * projection; //UpdateOverlay(); Overlay.Render(viewproj, Matrix4d.Identity); } if (Stereo == true) { GL.Viewport(0, 0, MScreen.Width / 2, MScreen.Height); Vector3d original = Camera.transform.Position; Camera.transform.Position -= Camera.transform.Right(); view = Camera.GetViewMatrix(); viewproj = view * projection; GL.Viewport(MScreen.Width / 2, 0, MScreen.Width / 2, MScreen.Height); RenderScene(ref view, ref offsetmat, ref projection, ref viewproj); Camera.transform.Position = original; GL.Viewport(0, 0, MScreen.Width, MScreen.Height); } Renderer.AfterRender(); // GL.Disable(EnableCap.DepthTest); // GL.Disable(EnableCap.DepthTest); // render Depth map to quad for visual debugging // --------------------------------------------- //GL.PolygonMode(MaterialFace.Front, PolygonMode.Fill); if (Settings.DebugDepth == true) { debugQuad.Bind(); debugQuad.material.shader.SetFloat("near_plane", light.NearPlane); debugQuad.material.shader.SetFloat("far_plane", light.FarPlane); GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, light.depthMap); GL.Clear(ClearBufferMask.DepthBufferBit); debugQuad.Render(lightmatrix, Matrix4d.Identity); } ///do not reset /// Globals.GlobalOffset = Vector3d.Zero; //projection = Camera.GetProjection(true); //GUIRoot.Render(Matrix4d.Identity, Matrix4d.Identity); ErrorCode err = GL.GetError(); if (err != ErrorCode.NoError) { //Console.WriteLine("MScene Render:" + err); } }
//TODO: Make work public void Render(Matrix4d viewproj, Matrix4d parentmodel) { Vector3[] positionArray = new Vector3[lines.Count]; Vector4[] colorArray = new Vector4[lines.Count]; int i; //Random r = new Random(); if (lines.Count() == 0) { return; } for (i = 0; i < lines.Count; i++) { positionArray[i] = MassiveTools.Vector3FromVector3d(lines[i].Position - Globals.GlobalOffset); colorArray[i] = lines[i].Color; } lines.Clear(); vertexCount = positionArray.Length; //GL.ClearColor(new Color4(0, 0, 0, 0.5f)); //GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); Matrix4 mvp = MTransform.GetFloatMatrix(viewproj); Matrix4 model = MTransform.GetFloatMatrix(parentmodel); GL.UseProgram(shaderProgram); int loc = GL.GetUniformLocation(shaderProgram, "mvp"); GL.UniformMatrix4(loc, false, ref mvp); loc = GL.GetUniformLocation(shaderProgram, "model"); GL.UniformMatrix4(loc, false, ref model); lineVertexBuffer = GL.GenBuffer(); if (Globals.Avatar.Target == null) { return; } Vector3 tp = MassiveTools.Vector3FromVector3d(Globals.Avatar.Target.transform.Position); //Vector3[] lineVertices = { new Vector3(0, 0, 0), new Vector3((float)r.NextDouble(), .5f, 0.5f) - MassiveTools.FromV3d(Globals.GlobalOffset)}; //vertexCount = lineVertices.Length; GL.BindBuffer(BufferTarget.ArrayBuffer, lineVertexBuffer); GL.BufferData(BufferTarget.ArrayBuffer, System.Runtime.InteropServices.Marshal.SizeOf(positionArray[0]) * vertexCount, positionArray, BufferUsageHint.StreamDraw); vertexInfo = GL.GenVertexArray(); GL.BindVertexArray(vertexInfo); int locVPosition = GL.GetAttribLocation(shaderProgram, "vPosition"); GL.EnableVertexAttribArray(locVPosition); GL.VertexAttribPointer(locVPosition, 3, VertexAttribPointerType.Float, false, System.Runtime.InteropServices.Marshal.SizeOf(positionArray[0]), 0); //GL.BindVertexArray(0); //GL.BindBuffer(BufferTarget.ArrayBuffer, 0); //GL.UseProgram(0); //GL.ClearColor(Color4.Black); GL.Clear(ClearBufferMask.DepthBufferBit); int loca = GL.GetUniformLocation(shaderProgram, "mcolor"); if (UserColorCoding == true) { for (int ri = 0; ri <= positionArray.Count() - 2; ri += 2) { Vector4 v = colorArray[ri]; GL.Uniform4(loca, ref v); GL.DrawArrays(PrimitiveType.LineStrip, ri, 2); } } else { Vector4 v = new Vector4(1, 1, 1, 0.9f); GL.Uniform4(loca, ref v); GL.DrawArrays(PrimitiveType.LineStrip, 0, positionArray.Count()); } //GL.DrawArrays(PrimitiveType.LineStrip, ri, vertexCount); GL.BindVertexArray(0); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.UseProgram(0); }
public void PlantTrees(MAstroBody planet, MTerrainTile tile) { //DistanceThreshold = tile.DistanceThreshold; Tile = tile; if (tile.material == null) { return; } MTexture tex = Tile.Biome; if (tex == null) { return; } this.transform.Position = tile.transform.Position; Random ran = new Random(1234); Matrix4d TreeRotation = Matrix4d.CreateFromQuaternion(Globals.LocalUpRotation()); int i = 0; for (int z = 0; z < tile.z_res - 1; z++) { for (int x = 0; x < tile.x_res - 1; x++) { float[] c = tex.GetPixel(x, z); float r = c[0]; float g = c[1]; float b = c[2]; float a = c[3]; float t = 0; //if ((b > r) && (b > g)) t = g; if ((r < 0.05) && (g > 0.1) && (b < 0.05)) { t = g; } else { continue; } if (ran.NextDouble() > Settings.TreeDensity) { continue; } //if (g < 0.7) continue; //Console.WriteLine(c[0] + " " + c[1] + " " + c[2] + " " + c[3]); if (i >= Settings.MaxTreesPerTerrain) { break; } Vector3d Treepos = new Vector3d(x, 0, z); //Vector3d PlantingPos = planet.GetNearestPointOnSphere(Treepos, 0); Matrix4d TreeScale = Matrix4d.Scale(1 + ran.NextDouble(), 1 + ran.NextDouble() * 2, 1 + ran.NextDouble()); Vector3d PlantingPos = Tile.GetPointOnSurfaceFromGrid(Treepos); //; + new Vector3d(r.NextDouble()*5, r.NextDouble() * 5, r.NextDouble()*5); Matrix4d TreePosition = Matrix4d.CreateTranslation(PlantingPos); //find point at y with raycast Matrix4 final = MTransform.GetFloatMatrix(TreeScale * TreeRotation * TreePosition); mats[i] = final; i++; } } TotalInstances = i; for (int j = TotalInstances; j < Settings.MaxTreesPerTerrain; j++) { Matrix4 final = Matrix4.CreateTranslation(j, 0, 0); mats[j] = final; } //Setup(); //UploadBuffer(); Planted = false; }