/// <summary> /// This is where we do our rendering /// Called from UI thread = UI code safe in this function /// </summary> public override void Render(DrawArgs drawArgs) { if (!isInitialized) { return; } if (world.Name != "Earth") { return; // Earth only } // Check for update if (!isDownloading && DateTime.Now > latestTime.AddHours(refreshHours)) { if (retryCount < maxRetry && DateTime.Now > lastDownloadTime.AddSeconds(retryDelaySeconds)) { StartDownload(cachePath, "clouds_" + DateTimeStamp(DateTime.Now) + ".jpg"); } } // Camera & Device shortcuts ;) CameraBase camera = drawArgs.WorldCamera; //Device device = drawArgs.device; // Render cloud layer if (texture != null) { double cloudAlt = 20e3; // clouds altitude in meters (20 x 10e3) if (camera.Altitude < 4000e3) { return; } double sphereRadius = camera.WorldRadius + cloudAlt; // Create sphere if (layerMesh == null) { layerMesh = TexturedSphere(drawArgs.device, (float)sphereRadius, 64, 64); } // set texture drawArgs.device.SetTexture(0, texture); drawArgs.device.TextureState[0].ColorOperation = TextureOperation.Modulate; drawArgs.device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor; drawArgs.device.TextureState[0].ColorArgument2 = TextureArgument.Diffuse; drawArgs.device.TextureState[0].AlphaOperation = TextureOperation.SelectArg1; drawArgs.device.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor; drawArgs.device.VertexFormat = CustomVertex.PositionNormalTextured.Format; // save world and projection transform Matrix origWorld = drawArgs.device.Transform.World; Matrix origProjection = drawArgs.device.Transform.Projection; // Save fog status and disable fog bool origFog = drawArgs.device.RenderState.FogEnable; drawArgs.device.RenderState.FogEnable = false; // Set new projection (to avoid being clipped) - probably better ways of doing this? double aspectRatio = (double)drawArgs.device.Viewport.Width / drawArgs.device.Viewport.Height; drawArgs.device.Transform.Projection = ConvertDX.FromMatrix4d(Matrix4d.PerspectiveFovRH(camera.Fov.Radians, aspectRatio, 1, double.MaxValue)); //translate to the camera reference center drawArgs.device.Transform.World = Matrix.Translation( (float)-drawArgs.WorldCamera.ReferenceCenter.X, (float)-drawArgs.WorldCamera.ReferenceCenter.Y, (float)-drawArgs.WorldCamera.ReferenceCenter.Z ); // draw drawArgs.device.RenderState.ZBufferEnable = false; layerMesh.DrawSubset(0); // Restore device states drawArgs.device.Transform.World = origWorld; drawArgs.device.Transform.Projection = origProjection; drawArgs.device.RenderState.FogEnable = origFog; drawArgs.device.RenderState.ZBufferEnable = true; } // Render progress bar if downloading if (isDownloading) { if (progressBar == null) { progressBar = new WorldWind.VisualControl.ProgressBar(40, 4); } progressBar.Draw(drawArgs, drawArgs.screenWidth - 34, drawArgs.screenHeight - 10, ProgressPercent, downloadProgressColor); drawArgs.device.RenderState.ZBufferEnable = true; } }
/// <summary> /// This is where we do our rendering /// Called from UI thread = UI code safe in this function /// </summary> public override void Render(DrawArgs drawArgs) { if (!isInitialized || (this.world.Name == "Earth" && World.Settings.EnableAtmosphericScattering)) { return; } // Camera & Device shortcuts ;) CameraBase camera = drawArgs.WorldCamera; Device device = drawArgs.device; //if(camera.Altitude > 200e3) return; Point3d cameraPos = camera.Position; double distToCenterOfPlanet = (camera.Altitude + camera.WorldRadius); // Create or refresh SkyGradient dome if (mesh == null || lastAltitude != camera.Altitude) { // Compute distance to horizon and dome radius double tangentalDistance = Math.Sqrt(distToCenterOfPlanet * distToCenterOfPlanet - camera.WorldRadius * camera.WorldRadius); double domeRadius = tangentalDistance; // horizon latitude double horizonLat = (-Math.PI / 2 + Math.Acos(tangentalDistance / distToCenterOfPlanet)) * 180 / Math.PI; // zenith latitude double zenithLat = 90; if (camera.Altitude >= thickness) { double tangentalDistanceZenith = Math.Sqrt(distToCenterOfPlanet * distToCenterOfPlanet - (camera.WorldRadius + thickness) * (camera.WorldRadius + thickness)); zenithLat = (-Math.PI / 2 + Math.Acos(tangentalDistanceZenith / distToCenterOfPlanet)) * 180 / Math.PI; } if (camera.Altitude < thickness && camera.Altitude > thickness * 0.8) { zenithLat = (thickness - camera.Altitude) / (thickness - thickness * 0.8) * 90; } // new mesh if (mesh != null) { mesh.Dispose(); } mesh = ColoredSphere(device, domeRadius, horizonLat, zenithLat, 128, 24); lastAltitude = camera.Altitude; } // set texture to null device.SetTexture(0, null); device.TextureState[0].ColorOperation = TextureOperation.BlendCurrentAlpha; device.VertexFormat = CustomVertex.PositionColored.Format; // save world and projection transform Matrix origWorld = device.Transform.World; Matrix origProjection = device.Transform.Projection; // move SkyGradient dome Matrix4d SkyGradientTrans; Point3d cameraCoord = MathEngine.CartesianToSpherical(cameraPos.X, cameraPos.Y, cameraPos.Z); double camLat = cameraCoord.Y; double camLon = cameraCoord.Z; SkyGradientTrans = Matrix4d.Translation(0, 0, distToCenterOfPlanet); SkyGradientTrans = Matrix4d.Multiply(SkyGradientTrans, Matrix4d.RotationY(-camLat + Math.PI / 2)); SkyGradientTrans = Matrix4d.Multiply(SkyGradientTrans, Matrix4d.RotationZ(camLon)); device.Transform.World = ConvertDX.FromMatrix4d(SkyGradientTrans); // Recenter Recenter(drawArgs); // Save fog status bool origFog = device.RenderState.FogEnable; device.RenderState.FogEnable = false; // Set new one (to avoid being clipped) - probably better ways of doing this? double aspectRatio = (double)device.Viewport.Width / device.Viewport.Height; device.Transform.Projection = ConvertDX.FromMatrix4d(Matrix4d.PerspectiveFovRH(camera.Fov.Radians, aspectRatio, 1000, 30000000.0)); // draw //device.RenderState.FillMode = FillMode.WireFrame; mesh.DrawSubset(0); // Restore device states device.RenderState.FillMode = FillMode.Solid; device.Transform.World = origWorld; device.Transform.Projection = origProjection; device.RenderState.FogEnable = origFog; device.RenderState.ZBufferEnable = true; // Fog effect if (useFog) { // Compute distance to horizon and camera altitude double tangentalDistance = Math.Sqrt(distToCenterOfPlanet * distToCenterOfPlanet - camera.WorldRadius * camera.WorldRadius); double a = camera.Altitude; device.RenderState.FogEnable = true; device.RenderState.FogColor = horizonColor; device.RenderState.FogTableMode = FogMode.Linear; device.RenderState.FogStart = (float)(a * nearFactor); device.RenderState.FogEnd = (float)(tangentalDistance * farFactor); } }