public void Draw(RenderContext11 renderContext) { renderContext.devContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList; renderContext.devContext.InputAssembler.SetVertexBuffers(0, vertexBufferBinding); renderContext.devContext.InputAssembler.SetIndexBuffer(indexBuffer, SharpDX.DXGI.Format.R32_UInt, 0); renderContext.SunPosition = new Vector3d(500, 500, 0.0); renderContext.SunlightColor = System.Drawing.Color.White; renderContext.AmbientLightColor = System.Drawing.Color.DarkGray; renderContext.SetupBasicEffect(BasicEffect.TextureOnly, 1.0f, System.Drawing.Color.White); renderContext.MainTexture = texture; renderContext.PreDraw(); if (layout == null) { layout = new SharpDX.Direct3D11.InputLayout(renderContext.Device, renderContext.Shader.InputSignature, new[] { new SharpDX.Direct3D11.InputElement("POSITION", 0, SharpDX.DXGI.Format.R32G32B32_Float, 0, 0), new SharpDX.Direct3D11.InputElement("TEXCOORD", 0, SharpDX.DXGI.Format.R32G32_Float, 16, 0), }); renderContext.Device.ImmediateContext.InputAssembler.InputLayout = layout; } // Draw the cube renderContext.devContext.DrawIndexed(triangleCount * 3, 0, 0); }
public void Draw(RenderContext11 renderContext, float Opacity, Color drawColor) { if (glyphCache == null || glyphCache.Version > glyphVersion) { PrepareBatch(); } //todo11 Use Shader renderContext.SetupBasicEffect(BasicEffect.TextureColorOpacity, Opacity, drawColor); renderContext.MainTexture = glyphCache.Texture; renderContext.devContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList; renderContext.PreDraw(); if (layout == null) { layout = new SharpDX.Direct3D11.InputLayout(renderContext.Device, renderContext.Shader.InputSignature, new[] { new SharpDX.Direct3D11.InputElement("POSITION", 0, SharpDX.DXGI.Format.R32G32B32_Float, 0, 0), new SharpDX.Direct3D11.InputElement("TEXCOORD", 0, SharpDX.DXGI.Format.R32G32_Float, 12, 0), }); } renderContext.Device.ImmediateContext.InputAssembler.InputLayout = layout; renderContext.SetVertexBuffer(vertexBuffer); renderContext.devContext.Draw(vertexBuffer.Count, 0); }
public override bool Draw3D(RenderContext11 renderContext, float transparancy, Tile parent) { InViewFrustum = true; transparancy = transparancy / 100; if (transparancy > 1f) { transparancy = 1.0f; } if (transparancy < 0f) { transparancy = 0; } if (!ReadyToRender) { TileCache.AddTileToQueue(this); if (texture == null) { return false; } } if (!CreateGeometry(renderContext, true)) { return false; } renderContext.MainTexture = texture; renderContext.SetVertexBuffer(vertexBuffer); renderContext.SetIndexBuffer(indexBuffer); renderContext.PreDraw(); renderContext.devContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; renderContext.devContext.DrawIndexed(6, 0, 0); return true; }
public void Render(RenderContext11 renderContext, float opacity) { if (dirty && !(ISSLayer)) { Reload(); } Matrix3d oldWorld = renderContext.World; Vector3 offset = mesh.BoundingSphere.Center; float unitScale = 1.0f; if (mesh.BoundingSphere.Radius > 0.0f) { unitScale = 1.0f / mesh.BoundingSphere.Radius; } renderContext.World = Matrix3d.Translation(-offset.X, -offset.Y, -offset.Z) * Matrix3d.Scaling(unitScale, unitScale, unitScale) * oldWorld; Matrix3d worldView = renderContext.World * renderContext.View; Vector3d v = worldView.Transform(Vector3d.Empty); double scaleFactor = Math.Sqrt(worldView.M11 * worldView.M11 + worldView.M22 * worldView.M22 + worldView.M33 * worldView.M33) / unitScale; double dist = v.Length(); double radius = scaleFactor; // Calculate pixelsPerUnit which is the number of pixels covered // by an object 1 AU at the distance of the planet center from // the camera. This calculation works regardless of the projection // type. int viewportHeight = (int)renderContext.ViewPort.Height; double p11 = renderContext.Projection.M11; double p34 = renderContext.Projection.M34; double p44 = renderContext.Projection.M44; double w = Math.Abs(p34) * dist + p44; float pixelsPerUnit = (float)(p11 / w) * viewportHeight; float radiusInPixels = (float)(radius * pixelsPerUnit); if (radiusInPixels < 0.5f) { // Too small to be visible; skip rendering return; } // These colors can be modified by shadows, distance from planet, etc. Restore // the original values after rendering. var savedSunlightColor = renderContext.SunlightColor; var savedReflectedColor = renderContext.ReflectedLightColor; var savedHemiColor = renderContext.HemisphereLightColor; if (Properties.Settings.Default.SolarSystemLighting) { SetupLighting(renderContext); renderContext.AmbientLightColor = System.Drawing.Color.FromArgb(11, 11, 11); } else { // No lighting: set ambient light to white and turn off all other light sources renderContext.SunlightColor = System.Drawing.Color.Black; renderContext.ReflectedLightColor = System.Drawing.Color.Black; renderContext.HemisphereLightColor = System.Drawing.Color.Black; renderContext.AmbientLightColor = System.Drawing.Color.White; } SharpDX.Direct3D11.Device device = renderContext.Device; if (mesh == null) { return; } //Object3dLayer.sketch.DrawLines(renderContext, 1.0f, System.Drawing.Color.Red); renderContext.DepthStencilMode = DepthStencilMode.ZReadWrite; renderContext.BlendMode = BlendMode.Alpha; int count = meshMaterials.Count; mesh.beginDrawing(renderContext); if (count > 0) { for (int i = 0; i < meshMaterials.Count; i++) { if (meshMaterials[i].Default) { Material mat = meshMaterials[i]; mat.Diffuse = Color; mat.Ambient = Color; meshMaterials[i] = mat; } // Set the material and texture for this subset renderContext.SetMaterial(meshMaterials[i], meshTextures[i], meshSpecularTextures[i], meshNormalMaps[i], opacity); renderContext.PreDraw(); renderContext.setSamplerState(0, renderContext.WrapSampler); mesh.drawSubset(renderContext, i); } } else { renderContext.PreDraw(); for (int i = 0; i < meshTextures.Count; i++) { var key = new PlanetShaderKey(PlanetSurfaceStyle.Diffuse, false, 0); renderContext.SetupPlanetSurfaceEffect(key, 1.0f); if (meshTextures[i] != null) { renderContext.MainTexture = meshTextures[i]; } renderContext.PreDraw(); mesh.drawSubset(renderContext, i); } } renderContext.setSamplerState(0, renderContext.ClampSampler); renderContext.setRasterizerState(TriangleCullMode.CullClockwise); renderContext.World = oldWorld; renderContext.SunlightColor = savedSunlightColor; renderContext.ReflectedLightColor = savedReflectedColor; renderContext.HemisphereLightColor = savedHemiColor; renderContext.AmbientLightColor = System.Drawing.Color.Black; }
public virtual bool Draw3D(RenderContext11 renderContext, float opacity, Tile parent) { RenderedGeneration = CurrentRenderGeneration; TilesTouched++; AccessCount = TileCache.AccessID++; if (errored) { return false; } int xMax = 2; InViewFrustum = true; if (!ReadyToRender) { if (fastLoad) { TextureReady = true; DemReady = true; if (!CreateGeometry(renderContext, false)) { TextureReady = false; DemReady = false; TileCache.AddTileToQueue(this); return false; } } else { TileCache.AddTileToQueue(this); return false; } } int childIndex = 0; int yOffset = 0; if (dataset.Mercator || dataset.BottomsUp ) { yOffset = 1; } int xOffset = 0; if (PurgeRefresh) { PurgeTextureAndDemFiles(); } Matrix3d savedWorld = renderContext.World; Matrix3d savedView = renderContext.View; bool usingLocalCenter = false; if (localCenter != Vector3d.Empty) { usingLocalCenter = true; Vector3d temp = localCenter; renderContext.World = Matrix3d.Translation(temp) * renderContext.WorldBase * Matrix3d.Translation(-renderContext.CameraPosition); renderContext.View = Matrix3d.Translation(renderContext.CameraPosition) * renderContext.ViewBase; } try { bool anythingToRender = false; bool childRendered = false; for (int y1 = 0; y1 < 2; y1++) { for (int x1 = 0; x1 < xMax; x1++) { // if (level < (demEnabled ? 12 : dataset.Levels)) if (level < dataset.Levels) { Tile child = TileCache.GetTile(level + 1, x * 2 + ((x1 + xOffset) % 2), y * 2 + ((y1 + yOffset) % 2), dataset, this); childrenId[childIndex] = child.Key; if (child.IsTileInFrustum(renderContext.Frustum)) { InViewFrustum = true; if (child.IsTileBigEnough(renderContext)) { renderPart[childIndex].TargetState = !child.Draw3D(renderContext, opacity, this); if (renderPart[childIndex].TargetState) { childRendered = true; } } else { renderPart[childIndex].TargetState = true; } } else { renderPart[childIndex].TargetState = renderPart[childIndex].State = false; } if (renderPart[childIndex].TargetState == true || !blendMode) { renderPart[childIndex].State = renderPart[childIndex].TargetState; } } else { renderPart[childIndex].State = true; } if (renderPart[childIndex].State == true) { anythingToRender = true; } childIndex++; } } if (childRendered || anythingToRender) { RenderedAtOrBelowGeneration = CurrentRenderGeneration; if (parent != null) { parent.RenderedAtOrBelowGeneration = RenderedAtOrBelowGeneration; } } if (!anythingToRender) { return true; } if (!CreateGeometry(renderContext, true)) { return false; } TilesInView++; if ( wireFrame) { renderContext.MainTexture = null; } else { renderContext.MainTexture = texture; } renderContext.SetVertexBuffer(vertexBuffer); accomidation = ComputeAccomidation(); for (int i = 0; i < 4; i++) { if (blendMode) //|| ShowElevation == false) { if ((renderPart[i].State && opacity == 1.0) || renderPart[i].TargetState) { renderContext.LocalCenter = localCenter; renderContext.PreDraw(); if (dataset.DataSetType == ImageSetType.Sky) { HDRPixelShader.constants.opacity = renderPart[i].Opacity * opacity; HDRPixelShader.Use(renderContext.devContext); } RenderPart(renderContext, i, renderPart[i].Opacity * opacity, false); } } else { if (renderPart[i].TargetState) { renderContext.LocalCenter = localCenter; renderContext.PreDraw(); if (dataset.DataSetType == ImageSetType.Sky) { HDRPixelShader.constants.opacity = opacity; HDRPixelShader.Use(renderContext.devContext); } RenderPart(renderContext, i, opacity, false); } } } } finally { if (usingLocalCenter) { renderContext.World = savedWorld; renderContext.View = savedView; } } return true; }
public static void DrawFixedResolutionSphere(RenderContext11 renderContext, int sphereIndex) { if (sphereVertexBuffers != null && sphereVertexBuffers[sphereIndex] != null) { renderContext.Device.ImmediateContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; renderContext.Device.ImmediateContext.InputAssembler.InputLayout = renderContext.Shader.inputLayout(PlanetShader11.StandardVertexLayout.PositionNormalTex2); renderContext.PreDraw(); renderContext.SetVertexBuffer(sphereVertexBuffers[sphereIndex]); renderContext.SetIndexBuffer(sphereIndexBuffers[sphereIndex]); renderContext.devContext.DrawIndexed(sphereIndexBuffers[sphereIndex].Count, 0, 0); } }
static void DrawSphere(RenderContext11 renderContext, Texture11 texture, int planetID, int sphereIndex, bool noMultires, bool drawLayers, PlanetShaderKey shaderKey) { var useMultires = Settings.Active.SolarSystemMultiRes && !noMultires; // Let an override layer take the place of the standard layer IImageSet defaultLayer = null; var defaultLayerColor = Color.White; if (drawLayers) { var referenceFrameName = Enum.GetName(typeof(SolarSystemObjects), (SolarSystemObjects)planetID); foreach (var layer in LayerManager.AllMaps[referenceFrameName].Layers) { if (layer.Enabled && layer is ImageSetLayer) { if (((ImageSetLayer)layer).OverrideDefaultLayer) { defaultLayer = ((ImageSetLayer)layer).ImageSet; defaultLayerColor = layer.Color; useMultires = true; break; } } } } if (useMultires) { renderContext.DepthStencilMode = DepthStencilMode.ZReadWrite; if (sphereIndex < 4) { IImageSet planet = null; if (defaultLayer != null) { planet = defaultLayer; } else { var planetName = GetNameFrom3dId(planetID); var imageSetName = planetName == "Mars" ? "Visible Imagery" : planetName; planet = Earth3d.MainWindow.GetImagesetByName(imageSetName); } if (planet != null) { var normColor = new Vector4(defaultLayerColor.R, defaultLayerColor.G, defaultLayerColor.B, defaultLayerColor.A) * (1.0f / 255.0f); if (RenderContext11.sRGB) { normColor.X = (float) Math.Pow(normColor.X, 2.2); normColor.Y = (float)Math.Pow(normColor.Y, 2.2); normColor.Z = (float)Math.Pow(normColor.Z, 2.2); } renderContext.Shader.DiffuseColor = normColor; renderContext.setRasterizerState(TriangleCullMode.CullClockwise); Earth3d.MainWindow.DrawTiledSphere(planet, 100, Color.White); if (planetID == (int)SolarSystemObjects.Earth && Settings.Active.ShowClouds) { if (CloudTexture != null) { var cloudShaderKey = new PlanetShaderKey(PlanetSurfaceStyle.Diffuse, Settings.Active.ShowEarthSky, 0); cloudShaderKey.eclipseShadowCount = shaderKey.eclipseShadowCount; cloudShaderKey.HasAtmosphere = shaderKey.HasAtmosphere; if (!Settings.Active.SolarSystemLighting) { cloudShaderKey.style = PlanetSurfaceStyle.Emissive; } SetupPlanetSurfaceEffect(renderContext, cloudShaderKey, 1.0f); SetAtmosphereConstants(renderContext, planetID, 1.0f, CalcSkyGeometryHeight(planetID)); renderContext.MainTexture = CloudTexture; var savedWorld = renderContext.World; var cloudScale = 1.0 + (EarthCloudHeightMeters) / 6378100.0; renderContext.World = Matrix3d.Scaling(cloudScale, cloudScale, cloudScale) * renderContext.World; renderContext.setRasterizerState(TriangleCullMode.CullCounterClockwise); renderContext.DepthStencilMode = DepthStencilMode.Off; renderContext.BlendMode = BlendMode.Alpha; DrawFixedResolutionSphere(renderContext, sphereIndex); renderContext.World = savedWorld; renderContext.DepthStencilMode = DepthStencilMode.ZReadWrite; renderContext.BlendMode = BlendMode.None; } } return; } } } renderContext.MainTexture = texture; renderContext.Device.ImmediateContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; renderContext.Device.ImmediateContext.InputAssembler.InputLayout = renderContext.Shader.inputLayout(PlanetShader11.StandardVertexLayout.PositionNormalTex2); renderContext.PreDraw(); renderContext.SetVertexBuffer(sphereVertexBuffers[sphereIndex]); renderContext.SetIndexBuffer(sphereIndexBuffers[sphereIndex]); renderContext.devContext.DrawIndexed(sphereIndexBuffers[sphereIndex].Count, 0, 0); }
// Various input layouts used in 3D solar system mode // TODO Replace with an input layout cache static void DrawRings(RenderContext11 renderContext) { renderContext.setRasterizerState(TriangleCullMode.Off); var ringsKey = new PlanetShaderKey(PlanetSurfaceStyle.PlanetaryRings, false, 0); SetupPlanetSurfaceEffect(renderContext, ringsKey, 1.0f); renderContext.Shader.MainTexture = RingsMap.ResourceView; renderContext.devContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip; renderContext.Device.ImmediateContext.InputAssembler.InputLayout = renderContext.Shader.inputLayout(PlanetShader11.StandardVertexLayout.PositionNormalTex); renderContext.PreDraw(); renderContext.SetVertexBuffer(ringsVertexBuffer); renderContext.devContext.Draw((triangleCountRings+2), 0); renderContext.setRasterizerState(TriangleCullMode.CullCounterClockwise); }
private static void DrawPlanet3d(RenderContext11 renderContext, int planetID, Vector3d centerPoint, float opacity) { // Assume that KML is only used for Earth KmlLabels kmlMarkers = null; if (planetID == (int)SolarSystemObjects.Earth) { kmlMarkers = Earth3d.MainWindow.KmlMarkers; if (kmlMarkers != null) { kmlMarkers.ClearGroundOverlays(); } } var matOld = renderContext.World; var matOldBase = renderContext.WorldBase; var matOldNonRotating = renderContext.WorldBaseNonRotating; var radius = GetAdjustedPlanetRadius(planetID); SetupPlanetMatrix(renderContext, planetID, centerPoint, true); LayerManager.PreDraw(renderContext, 1.0f, false, Enum.GetName(typeof(SolarSystemObjects), (SolarSystemObjects)planetID), true); float planetWidth = 1; if (planetID == (int)SolarSystemObjects.Saturn) { planetWidth = 3; } if (IsPlanetInFrustum(renderContext, planetWidth)) { // Save all matrices modified by SetupMatrix... var matOld2 = renderContext.World; var matOldBase2 = renderContext.WorldBase; var matOldNonRotating2 = renderContext.WorldBaseNonRotating; renderContext.World = matOld; renderContext.WorldBase = matOldBase; renderContext.WorldBaseNonRotating = matOldNonRotating; SetupMatrixForPlanetGeometry(renderContext, planetID, centerPoint, true); var loc = planet3dLocations[planetID] - centerPoint; loc.Subtract(renderContext.CameraPosition); var dist = loc.Length(); var sizeIndexParam = (2 * Math.Atan(.5 * (radius / dist))) / Math.PI * 180; // Calculate pixelsPerUnit which is the number of pixels covered // by an object 1 AU at the distance of the planet center from // the camera. This calculation works regardless of the projection // type. var viewportHeight = renderContext.ViewPort.Height; var p11 = renderContext.Projection.M11; var p34 = renderContext.Projection.M34; var p44 = renderContext.Projection.M44; var w = Math.Abs(p34) * dist + p44; var pixelsPerUnit = (float)(p11 / w) * viewportHeight; var planetRadiusInPixels = (float)(radius * pixelsPerUnit); var sizeIndex = 0; if (sizeIndexParam > 10.5) { sizeIndex = 0; } else if (sizeIndexParam > 3.9) { sizeIndex = 1; } else if (sizeIndexParam > .72) { sizeIndex = 2; } else if (sizeIndexParam > 0.057) { sizeIndex = 3; } else { sizeIndex = 4; } var eclipseShadowCount = 0; var hasRingShadowsOnPlanet = false; // No shadows should be drawn if Solar System Lighting is OFF if (Settings.Active.SolarSystemLighting) { // Eclipse shadow setup for Earth if (planetID == (int)SolarSystemObjects.Earth) { if (sizeIndex < 2) { var width = Settings.Active.SolarSystemScale * .00001f; SetupShadow(renderContext, centerPoint, width, SolarSystemObjects.Moon, 0); eclipseShadowCount = 1; } } // Eclipse shadow setup for Jupiter // Shadow widths based only on moon diameter in relation to Moon diameter if (planetID == (int)SolarSystemObjects.Jupiter && sizeIndex < 3) { var p = 0; float width; if (planetLocations[(int)SolarSystemObjects.Callisto].Shadow) { width = Settings.Active.SolarSystemScale * .0000139f; SetupShadow(renderContext, centerPoint, width, SolarSystemObjects.Callisto, p++); } if (planetLocations[(int)SolarSystemObjects.Ganymede].Shadow) { width = Settings.Active.SolarSystemScale * .0000152f; SetupShadow(renderContext, centerPoint, width, SolarSystemObjects.Ganymede, p++); } if (planetLocations[(int)SolarSystemObjects.Io].Shadow) { width = Settings.Active.SolarSystemScale * .0000105f; SetupShadow(renderContext, centerPoint, width, SolarSystemObjects.Io, p++); } if (planetLocations[(int)SolarSystemObjects.Europa].Shadow) { width = Settings.Active.SolarSystemScale * .000009f; SetupShadow(renderContext, centerPoint, width, SolarSystemObjects.Europa, p++); } eclipseShadowCount = p; } // Ring shadows on Saturn if (planetID == (int)SolarSystemObjects.Saturn && Settings.Active.SolarSystemLighting) { hasRingShadowsOnPlanet = true; } //ShadowStuff end } // Get the position of the Sun relative to the planet center; the position is // in the world coordinate frame. var sunPosition = (planet3dLocations[0] - planet3dLocations[planetID]); renderContext.SunPosition = sunPosition; if (sizeIndex < 4) { var atmosphereOn = (planetID == 19 || planetID == 3) && Settings.Active.ShowEarthSky; if (planetID == 0 && sizeIndex > 1) { //todo11 //device.RenderState.Clipping = false; DrawPointPlanet(renderContext, new Vector3d(0, 0, 0), (float)Math.Min(1.6, sizeIndexParam) * 2, planetColors[planetID], true, opacity); //todo11 //device.RenderState.Clipping = true; } var surfaceStyle = PlanetSurfaceStyle.Diffuse; if (planetID == (int)SolarSystemObjects.Sun || !Settings.Active.SolarSystemLighting) { surfaceStyle = PlanetSurfaceStyle.Emissive; } else if (planetID == (int)SolarSystemObjects.Moon || planetID == (int)SolarSystemObjects.Mercury) { // Use Lommel-Seeliger photometric model for regolith covered bodies // surfaceStyle = PlanetSurfaceStyle.LommelSeeliger; } var skyGeometryHeight = CalcSkyGeometryHeight(planetID); var shaderKey = new PlanetShaderKey(surfaceStyle, atmosphereOn, eclipseShadowCount); shaderKey.HasRingShadows = hasRingShadowsOnPlanet; if (kmlMarkers != null) { shaderKey.overlayTextureCount = Math.Min(kmlMarkers.GroundOverlayCount, PlanetShader11.MaxOverlayTextures); } SetupPlanetSurfaceEffect(renderContext, shaderKey, opacity); renderContext.LocalCenter = Vector3d.Empty; // Set up any overlay textures if (shaderKey.overlayTextureCount > 0) { if (renderContext.ShadersEnabled) { kmlMarkers.SetupGroundOverlays(renderContext); } } if (shaderKey.eclipseShadowCount > 0) { renderContext.Shader.EclipseTexture = PlanetShadow.ResourceView; } if (shaderKey.HasRingShadows) { renderContext.Shader.RingTexture = RingsMap.ResourceView; } if (atmosphereOn) { SetAtmosphereConstants(renderContext, planetID, 1.0f, skyGeometryHeight); } // Disable overlays after we're done rendering the planet surface (i.e. we don't want // them on any rings, sky shell, or cloud layer.) shaderKey.overlayTextureCount = 0; renderContext.setRasterizerState(TriangleCullMode.CullCounterClockwise); if (planetID == 19 && !Settings.Active.SolarSystemMultiRes && Settings.Active.SolarSystemLighting) { shaderKey.style = PlanetSurfaceStyle.DiffuseAndNight; SetupPlanetSurfaceEffect(renderContext, shaderKey, opacity); if (atmosphereOn) { SetAtmosphereConstants(renderContext, planetID, 1.0f, skyGeometryHeight); } // Set eclipse constants var eclipseShadowWidth = Settings.Active.SolarSystemScale * .00001f; if (shaderKey.eclipseShadowCount > 0) { SetupShadow(renderContext, centerPoint, eclipseShadowWidth, SolarSystemObjects.Moon, 0); renderContext.Shader.EclipseTexture = PlanetShadow.ResourceView; } renderContext.Shader.NightTexture = planetTexturesMaps[20].ResourceView; renderContext.BlendMode = BlendMode.None; DrawSphere(renderContext, planetTexturesMaps[planetID], planetID, sizeIndex, false, false, shaderKey); // Set up for rendering specular pass shaderKey.style = PlanetSurfaceStyle.SpecularPass; SetupPlanetSurfaceEffect(renderContext, shaderKey, opacity); if (shaderKey.eclipseShadowCount > 0) { SetupShadow(renderContext, centerPoint, eclipseShadowWidth, SolarSystemObjects.Moon, 0); renderContext.Shader.EclipseTexture = PlanetShadow.ResourceView; } if (atmosphereOn) { SetAtmosphereConstants(renderContext, planetID, 1.0f, skyGeometryHeight); } // Set up specular properties; this should eventually be abstracted by RenderContext renderContext.Shader.SpecularPower = 50.0f; renderContext.Shader.SpecularColor = new Vector4(0.5f, 0.5f, 0.5f, 0.0f); renderContext.BlendMode = BlendMode.Additive; DrawSphere(renderContext, planetTexturesMaps[21], planetID, sizeIndex, false, true, shaderKey); renderContext.BlendMode = BlendMode.None; } else { renderContext.DepthStencilMode = DepthStencilMode.ZReadWrite; renderContext.PreDraw(); DrawSphere(renderContext, planetTexturesMaps[planetID], planetID, sizeIndex, false, true, shaderKey); } // Render the sky geometry. This is a sphere slightly larger than the planet where the // only light is from atmospheric scattering. We'll render inside of the sphere only. if (atmosphereOn) { // The sky geometry needs to be slightly larger than the planet itself, so adjust the // world matrix by a scale factor a bit greater than 1.0 var savedWorld = renderContext.World; var world = renderContext.World; var skyRadius = skyGeometryHeight + 1.0f; world.ScalePrepend(new Vector3d(skyRadius, skyRadius, skyRadius)); renderContext.World = world; shaderKey.style = PlanetSurfaceStyle.Sky; var atmosphereShader = SetupPlanetSurfaceEffect(renderContext, shaderKey, 1.0f); renderContext.Shader = atmosphereShader; // Set the shadow texture if there's an eclipse if (shaderKey.eclipseShadowCount > 0) { atmosphereShader.EclipseTexture = PlanetShadow.ResourceView; } // Atmosphere height is relative to the size of the sphere being rendered. Since we're // actually rendering the shell geometry here, we just use a value of 0 for the height // and a lower value for the zero height. SetAtmosphereConstants(renderContext, planetID, 1.0f + skyGeometryHeight, 0.0f); // We're rendering just the atmosphere; there's no contribution from a surface, so set the // diffuse color to black. atmosphereShader.DiffuseColor = new Vector4(0.0f, 0.0f, 0.0f, 0.0f); atmosphereShader.Opacity = 0.0f; //renderContext.BlendMode = BlendMode.Alpha; // Fade out the sky geometry as its screen size gets thin; this prevents terrible // aliasing that occurs. var skyShellPixels = (float)(skyGeometryHeight * radius * pixelsPerUnit); var blendFactor = Math.Min(3.0f, skyShellPixels) / 3.0f; renderContext.BlendMode = BlendMode.BlendFactorInverseAlpha; renderContext.BlendFactor = new Color4(blendFactor, blendFactor, blendFactor, 1.0f); renderContext.DepthStencilMode = DepthStencilMode.ZReadOnly; //Render the _inside_ of the sphere. No need for multires or layers when drawing the sky renderContext.setRasterizerState(TriangleCullMode.CullClockwise); DrawSphere(renderContext, planetTexturesMaps[planetID], planetID, 0/*sizeIndex*/, true, false, shaderKey); // Reset device state renderContext.setRasterizerState(TriangleCullMode.CullCounterClockwise); renderContext.DepthStencilMode = DepthStencilMode.ZReadWrite; renderContext.BlendMode = BlendMode.None; // Restore the world matrix renderContext.World = savedWorld; } RestoreDefaultMaterialState(renderContext); if (planetID == 5) { var ringsKey = new PlanetShaderKey(PlanetSurfaceStyle.PlanetaryRings, false, 0); SetupPlanetSurfaceEffect(renderContext, ringsKey, 1.0f); DrawRings(renderContext); RestoreDefaultMaterialState(renderContext); } } else { if (planetID == 0) { DrawPointPlanet(renderContext, new Vector3d(0, 0, 0), (float)(10 * planetDiameters[planetID]), planetColors[planetID], true, opacity); } else if (planetID < (int)SolarSystemObjects.Moon || planetID == (int)SolarSystemObjects.Earth) { var size = (float)(800 * planetDiameters[planetID]); DrawPointPlanet(renderContext, new Vector3d(0, 0, 0), (float)Math.Max(.05, Math.Min(.1f, size)), planetColors[planetID], true, opacity); } else if (sizeIndexParam > .002) { var size = (float)(800 * planetDiameters[planetID]); DrawPointPlanet(renderContext, new Vector3d(0, 0, 0), (float)Math.Max(.05, Math.Min(.1f, size)), planetColors[planetID], true, opacity); } } // Restore all matrices modified by SetupMatrix... renderContext.World = matOld2; renderContext.WorldBase = matOldBase2; renderContext.WorldBaseNonRotating = matOldNonRotating2; } { var sunPosition = (planet3dLocations[0] - centerPoint); var planetPosition = planet3dLocations[planetID] - centerPoint; renderContext.SunPosition = sunPosition; renderContext.ReflectedLightPosition = planetPosition; if (planetID == (int)SolarSystemObjects.Earth) { renderContext.ReflectedLightColor = Color.FromArgb(50, 70, 90); renderContext.HemisphereLightColor = Color.FromArgb(100, 100, 100); } else { renderContext.ReflectedLightColor = Color.Black; renderContext.HemisphereLightColor = Color.Black; } renderContext.OccludingPlanetPosition = planetPosition; renderContext.OccludingPlanetRadius = planetDiameters[planetID] / 2.0; } LayerManager.Draw(renderContext, 1.0f, false, Enum.GetName(typeof(SolarSystemObjects), (SolarSystemObjects)planetID), true, false); // Reset render context state renderContext.ReflectedLightColor = Color.Black; renderContext.HemisphereLightColor = Color.Black; renderContext.World = matOld; Earth3d.MainWindow.MakeFrustum(); RestoreDefaultMaterialState(renderContext); renderContext.setRasterizerState(TriangleCullMode.CullClockwise); }