/// <summary> /// Render one of the 4 quadrants with optional download indicator /// </summary> private void Render(Device device, CustomVertex.PositionNormalTextured[] verts, QuadTile child) { bool isMultitexturing = false; if (!World.Settings.EnableSunShading) { if (World.Settings.ShowDownloadIndicator && child != null) { // Check/display download activity //GeoSpatialDownloadRequest request = child.DownloadRequest; if (child.isDownloadingTerrain) { device.SetTexture(1, QuadTileSet.DownloadTerrainTexture); isMultitexturing = true; } //else if (request != null) else if (child.WaitingForDownload) { if (child.IsDownloadingImage) device.SetTexture(1, QuadTileSet.DownloadInProgressTexture); else device.SetTexture(1, QuadTileSet.DownloadQueuedTexture); isMultitexturing = true; } } } if (isMultitexturing) device.SetTextureStageState(1, TextureStageStates.ColorOperation, (int)TextureOperation.BlendTextureAlpha); if (verts != null && vertexIndexes != null) { if (quadTileSet.Effect != null) { Effect effect = quadTileSet.Effect; int tc1 = device.GetTextureStageStateInt32(1, TextureStageStates.TextureCoordinateIndex); device.SetTextureStageState(1, TextureStageStates.TextureCoordinateIndex, 1); // FIXME: just use the first technique for now effect.Technique = effect.GetTechnique(0); EffectHandle param; param = (EffectHandle)quadTileSet.EffectParameters["WorldViewProj"]; if (param != null) effect.SetValue(param, Matrix.Multiply(device.Transform.World, Matrix.Multiply(device.Transform.View, device.Transform.Projection))); try { param = (EffectHandle)quadTileSet.EffectParameters["World"]; if (param != null) effect.SetValue(param, device.Transform.World); param = (EffectHandle)quadTileSet.EffectParameters["ViewInverse"]; if (param != null) { Matrix viewInv = Matrix.Invert(device.Transform.View); effect.SetValue(param, viewInv); } // set textures as available for (int i = 0; i < textures.Length; i++) { string name = string.Format("Tex{0}", i); param = (EffectHandle)quadTileSet.EffectParameters[name]; if (param != null) { effect.SetValue(param, textures[i]); } } // brightness & opacity values param = (EffectHandle)quadTileSet.EffectParameters["Brightness"]; if (param != null) effect.SetValue(param, quadTileSet.GrayscaleBrightness); param = (EffectHandle)quadTileSet.EffectParameters["Opacity"]; if (param != null) { float opacity = (float)quadTileSet.Opacity / 255.0f; effect.SetValue(param, opacity); } param = (EffectHandle)quadTileSet.EffectParameters["LayerRadius"]; if (param != null) { effect.SetValue(param, (float)quadTileSet.LayerRadius); } param = (EffectHandle)quadTileSet.EffectParameters["TileLevel"]; if (param != null) { effect.SetValue(param, level); } param = (EffectHandle)quadTileSet.EffectParameters["LocalOrigin"]; if (param != null) { effect.SetValue(param, localOrigin.Vector4); } // sun position param = (EffectHandle)quadTileSet.EffectParameters["LightDirection"]; if (param != null) { Point3d sunPosition = SunCalculator.GetGeocentricPosition(TimeKeeper.CurrentTimeUtc); sunPosition.normalize(); Vector4 sunVector = new Vector4( (float)sunPosition.X, (float)sunPosition.Y, (float)sunPosition.Z, 0.0f); effect.SetValue(param, sunVector); } // local origin param = (EffectHandle)quadTileSet.EffectParameters["LocalFrameOrigin"]; if (param != null) { //localOrigin = BoundingBox.CalculateCenter(); Point3d centerPoint = MathEngine.SphericalToCartesian(centerLatitude, centerLongitude, quadTileSet.LayerRadius); Point3d northHalf = MathEngine.SphericalToCartesian(Angle.FromDegrees(north), centerLongitude, quadTileSet.LayerRadius); Point3d eastHalf = MathEngine.SphericalToCartesian(centerLatitude, Angle.FromDegrees(east), quadTileSet.LayerRadius); Vector4 xdir = (2 * (eastHalf - centerPoint)).Vector4; Vector4 ydir = (2 * (northHalf - centerPoint)).Vector4; // up vector is radius at center point, normalized Point3d zdir3 = centerPoint; zdir3.normalize(); Vector4 zdir = zdir3.Vector4; // local frame origin at SW corner, relative to local origin Point3d localFrameOrigin = northHalf + eastHalf - centerPoint - localOrigin; Vector4 lfoW = localFrameOrigin.Vector4; lfoW.W = 1; lfoW.Transform(device.Transform.World); effect.SetValue(param, localFrameOrigin.Vector4); // JBTODO: Should this be lfoW? param = (EffectHandle)quadTileSet.EffectParameters["LocalFrameXAxis"]; if (param != null) effect.SetValue(param, xdir); param = (EffectHandle)quadTileSet.EffectParameters["LocalFrameYAxis"]; if (param != null) effect.SetValue(param, ydir); param = (EffectHandle)quadTileSet.EffectParameters["LocalFrameZAxis"]; if (param != null) effect.SetValue(param, zdir); } } catch { } int numPasses = effect.Begin(0); for (int i = 0; i < numPasses; i++) { effect.BeginPass(i); device.DrawIndexedUserPrimitives(PrimitiveType.TriangleList, 0, verts.Length, vertexIndexes.Length / 3, vertexIndexes, true, verts); effect.EndPass(); } effect.End(); device.SetTextureStageState(1, TextureStageStates.TextureCoordinateIndex, tc1); } else { if (World.Settings.EnableSunShading) { Point3d sunPosition = SunCalculator.GetGeocentricPosition(TimeKeeper.CurrentTimeUtc); Vector3 sunVector = new Vector3( (float)sunPosition.X, (float)sunPosition.Y, (float)sunPosition.Z); device.RenderState.Lighting = true; Material material = new Material(); material.Diffuse = Color.White; material.Ambient = Color.White; device.Material = material; device.RenderState.AmbientColor = World.Settings.ShadingAmbientColor.ToArgb(); device.RenderState.NormalizeNormals = true; device.RenderState.AlphaBlendEnable = true; device.Lights[0].Enabled = true; device.Lights[0].Type = LightType.Directional; device.Lights[0].Diffuse = LightColor; device.Lights[0].Direction = sunVector; device.TextureState[0].ColorOperation = TextureOperation.Modulate; device.TextureState[0].ColorArgument1 = TextureArgument.Diffuse; device.TextureState[0].ColorArgument2 = TextureArgument.TextureColor; } else { device.RenderState.Lighting = false; device.RenderState.Ambient = World.Settings.StandardAmbientColor; } device.RenderState.TextureFactor = Color.FromArgb(m_CurrentOpacity, 255, 255, 255).ToArgb(); device.TextureState[0].AlphaOperation = TextureOperation.Modulate; device.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor; device.TextureState[0].AlphaArgument2 = TextureArgument.TFactor; device.DrawIndexedUserPrimitives(PrimitiveType.TriangleList, 0, verts.Length, vertexIndexes.Length / 3, vertexIndexes, true, verts); device.RenderState.TextureFactor = Color.FromArgb(255, 255, 255, 255).ToArgb(); } } if (isMultitexturing) device.SetTextureStageState(1, TextureStageStates.ColorOperation, (int)TextureOperation.Disable); }