private void InitializeRequestThreads(Context context, RasterDataDetails details, ClipmapLevel clipmapLevelZero, RasterLevel rasterLevelZero) { details.WorkerWindow = Device.CreateWindow(1, 1); context.MakeCurrent(); #if !SingleThreaded Thread requestThread = new Thread(RequestThreadEntryPoint); requestThread.IsBackground = true; requestThread.Start(details); #endif // Preload the entire world at level 0 RasterTileRegion[] regions = rasterLevelZero.GetTilesInExtent(0, 0, rasterLevelZero.LongitudePosts - 1, rasterLevelZero.LatitudePosts - 1); foreach (RasterTileRegion region in regions) { RequestTileLoad(details, clipmapLevelZero, region.Tile); } }
public EsriRestImagery(Uri baseUri) { _baseUri = baseUri; _levels = new RasterLevel[NumberOfLevels]; _levelsCollection = new RasterLevelCollection(_levels); double deltaLongitude = LevelZeroDeltaLongitudeDegrees; double deltaLatitude = LevelZeroDeltaLatitudeDegrees; for (int i = 0; i < _levels.Length; ++i) { int longitudePosts = (int)Math.Round(360.0 / deltaLongitude) * TileLongitudePosts + 1; int latitudePosts = (int)Math.Round(180.0 / deltaLatitude) * TileLatitudePosts + 1; _levels[i] = new RasterLevel(this, i, _extent, longitudePosts, latitudePosts, TileLongitudePosts, TileLatitudePosts); deltaLongitude /= 2.0; deltaLatitude /= 2.0; } }
public WorldWindTerrainSource(Uri baseUri) { _baseUri = baseUri; _levels = new RasterLevel[NumberOfLevels]; _levelsCollection = new RasterLevelCollection(_levels); double deltaLongitude = LevelZeroDeltaLongitudeDegrees; double deltaLatitude = LevelZeroDeltaLatitudeDegrees; for (int i = 0; i < _levels.Length; ++i) { int longitudePosts = (int)Math.Round(360.0 / deltaLongitude) * TileLongitudePosts + 1; int latitudePosts = (int)Math.Round(180.0 / deltaLatitude) * TileLatitudePosts + 1; _levels[i] = new RasterLevel(this, i, _extent, longitudePosts, latitudePosts, TileLongitudePosts, TileLatitudePosts); deltaLongitude /= 2.0; deltaLatitude /= 2.0; } }
public GMapRestImagery() { //_baseUri = baseUri; _levels = new RasterLevel[NumberOfLevels]; _levelsCollection = new RasterLevelCollection(_levels); double deltaLongitude = LevelZeroDeltaLongitudeDegrees; double deltaLatitude = LevelZeroDeltaLatitudeDegrees; for (int i = 0; i < _levels.Length; ++i) { int longitudePosts = (int)Math.Round(360.0 / deltaLongitude) * TileLongitudePosts + 1; int latitudePosts = (int)Math.Round(180 / deltaLatitude) * TileLatitudePosts + 1; _levels[i] = new RasterLevel(this, i, _extent, longitudePosts, latitudePosts, TileLongitudePosts, TileLatitudePosts); deltaLongitude /= 2.0; deltaLatitude /= 2.0; } MainMap = new GMapControl(); MainMap.MapType = GMap.NET.MapType.GoogleSatellite; MainMap.CacheLocation = Path.GetDirectoryName(Application.ExecutablePath) + "/gmapcache/"; }
private void ApplyNewTile(Context context, RasterDataDetails details, ClipmapLevel level, RasterTile tile) { ClipmapLevel.Extent nextExtent = details.Type == RasterType.Terrain ? level.NextExtent : level.NextImageryExtent; RasterLevel rasterLevel = details.Type == RasterType.Terrain ? level.Terrain : level.Imagery; ClipmapUpdate entireLevel = new ClipmapUpdate( level, nextExtent.West, nextExtent.South, nextExtent.East, nextExtent.North); ClipmapUpdate thisTile = new ClipmapUpdate( level, tile.West - 1, tile.South - 1, tile.East + 1, tile.North + 1); ClipmapUpdate intersection = IntersectUpdates(entireLevel, thisTile); if (intersection.Width > 0 && intersection.Height > 0) { Update(context, intersection, level, details, rasterLevel); // Recurse on child tiles if they're NOT loaded. Unloaded children will use data from this tile. ClipmapLevel finer = level.FinerLevel; if (finer != null) { ApplyIfNotLoaded(context, details, finer, tile.SouthwestChild); ApplyIfNotLoaded(context, details, finer, tile.SoutheastChild); ApplyIfNotLoaded(context, details, finer, tile.NorthwestChild); ApplyIfNotLoaded(context, details, finer, tile.NortheastChild); } } }
private void Update(Context context, ClipmapUpdate update, ClipmapLevel level, RasterDataDetails details, RasterLevel rasterLevel) { ClipmapUpdate[] updates = SplitUpdateToAvoidWrapping(update, details); foreach (ClipmapUpdate nonWrappingUpdate in updates) { RasterTileRegion[] tileRegions = rasterLevel.GetTilesInExtent(nonWrappingUpdate.West, nonWrappingUpdate.South, nonWrappingUpdate.East, nonWrappingUpdate.North); foreach (RasterTileRegion region in tileRegions) { Texture2D tileTexture; bool loaded = details.LoadedTiles.TryGetValue(region.Tile.Identifier, out tileTexture); if (loaded) { RenderTileToLevelTexture(context, level, details, region, tileTexture); } else { UpsampleTileData(context, level, details, region); } } } if (details.Type == RasterType.Terrain) { // Normals at edges are incorrect, so include a one-post buffer around the update region // when updating normals in order to update normals that were previously at the edge. ClipmapUpdate updateWithBuffer = update.AddBufferWithinLevelNextExtent(); ClipmapUpdate[] normalUpdates = SplitUpdateToAvoidWrapping(updateWithBuffer, details); foreach (ClipmapUpdate normalUpdate in normalUpdates) { UpdateNormals(context, normalUpdate); } } }
private void RequestTileResidency(Context context, ClipmapLevel level, RasterDataDetails details, RasterLevel rasterLevel, ClipmapLevel.Extent nextExtent) { RasterTileRegion[] tileRegions = rasterLevel.GetTilesInExtent(nextExtent.West, nextExtent.South, nextExtent.East, nextExtent.North); foreach (RasterTileRegion region in tileRegions) { if (!details.LoadedTiles.ContainsKey(region.Tile.Identifier)) { RequestTileLoad(details, level, region.Tile); } } }
public GlobeClipmapTerrain(Context context, RasterSource terrainSource, EsriRestImagery imagery, Ellipsoid ellipsoid, int clipmapPosts) { _terrainSource = terrainSource; _ellipsoid = ellipsoid; _clipmapPosts = clipmapPosts; _clipmapSegments = _clipmapPosts - 1; int clipmapLevels = _terrainSource.Levels.Count; _clipmapLevels = new ClipmapLevel[clipmapLevels]; for (int i = 0; i < _clipmapLevels.Length; ++i) { _clipmapLevels[i] = new ClipmapLevel(); } for (int i = 0; i < _clipmapLevels.Length; ++i) { RasterLevel terrainLevel = _terrainSource.Levels[i]; _clipmapLevels[i].Terrain = terrainLevel; _clipmapLevels[i].HeightTexture = Device.CreateTexture2D(new Texture2DDescription(_clipmapPosts, _clipmapPosts, TextureFormat.Red32f)); _clipmapLevels[i].NormalTexture = Device.CreateTexture2D(new Texture2DDescription(_clipmapPosts, _clipmapPosts, TextureFormat.RedGreenBlue32f)); _clipmapLevels[i].CoarserLevel = i == 0 ? null : _clipmapLevels[i - 1]; _clipmapLevels[i].FinerLevel = i == _clipmapLevels.Length - 1 ? null : _clipmapLevels[i + 1]; // Aim for roughly one imagery texel per geometry texel. // Find the first imagery level that meets our resolution needs. double longitudeResRequired = terrainLevel.PostDeltaLongitude; double latitudeResRequired = terrainLevel.PostDeltaLatitude; RasterLevel imageryLevel = null; for (int j = 0; j < imagery.Levels.Count; ++j) { imageryLevel = imagery.Levels[j]; if (imageryLevel.PostDeltaLongitude <= longitudeResRequired && imageryLevel.PostDeltaLatitude <= latitudeResRequired) { break; } } _clipmapLevels[i].Imagery = imageryLevel; _clipmapLevels[i].ImageryWidth = (int)Math.Ceiling(_clipmapPosts * terrainLevel.PostDeltaLongitude / imageryLevel.PostDeltaLongitude); _clipmapLevels[i].ImageryHeight = (int)Math.Ceiling(_clipmapPosts * terrainLevel.PostDeltaLatitude / imageryLevel.PostDeltaLatitude); _clipmapLevels[i].ImageryTexture = Device.CreateTexture2D(new Texture2DDescription(_clipmapLevels[i].ImageryWidth, _clipmapLevels[i].ImageryHeight, TextureFormat.RedGreenBlue8, false)); } _shaderProgram = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.ClipmapTerrain.GlobeClipmapVS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.ClipmapTerrain.GlobeClipmapFS.glsl")); _fillPatchPosts = (clipmapPosts + 1) / 4; // M _fillPatchSegments = _fillPatchPosts - 1; // Create the MxM block used to fill the ring and the field. Mesh fieldBlockMesh = RectangleTessellator.Compute( new RectangleD(new Vector2D(0.0, 0.0), new Vector2D(_fillPatchSegments, _fillPatchSegments)), _fillPatchSegments, _fillPatchSegments); _fillPatch = context.CreateVertexArray(fieldBlockMesh, _shaderProgram.VertexAttributes, BufferHint.StaticDraw); // Create the Mx3 block used to fill the space between the MxM blocks in the ring Mesh ringFixupHorizontalMesh = RectangleTessellator.Compute( new RectangleD(new Vector2D(0.0, 0.0), new Vector2D(_fillPatchSegments, 2.0)), _fillPatchSegments, 2); _horizontalFixupPatch = context.CreateVertexArray(ringFixupHorizontalMesh, _shaderProgram.VertexAttributes, BufferHint.StaticDraw); // Create the 3xM block used to fill the space between the MxM blocks in the ring Mesh ringFixupVerticalMesh = RectangleTessellator.Compute( new RectangleD(new Vector2D(0.0, 0.0), new Vector2D(2.0, _fillPatchSegments)), 2, _fillPatchSegments); _verticalFixupPatch = context.CreateVertexArray(ringFixupVerticalMesh, _shaderProgram.VertexAttributes, BufferHint.StaticDraw); Mesh offsetStripHorizontalMesh = RectangleTessellator.Compute( new RectangleD(new Vector2D(0.0, 0.0), new Vector2D(2 * _fillPatchPosts, 1.0)), 2 * _fillPatchPosts, 1); _horizontalOffsetPatch = context.CreateVertexArray(offsetStripHorizontalMesh, _shaderProgram.VertexAttributes, BufferHint.StaticDraw); Mesh offsetStripVerticalMesh = RectangleTessellator.Compute( new RectangleD(new Vector2D(0.0, 0.0), new Vector2D(1.0, 2 * _fillPatchPosts - 1)), 1, 2 * _fillPatchPosts - 1); _verticalOffsetPatch = context.CreateVertexArray(offsetStripVerticalMesh, _shaderProgram.VertexAttributes, BufferHint.StaticDraw); Mesh centerMesh = RectangleTessellator.Compute(new RectangleD(new Vector2D(0.0, 0.0), new Vector2D(2.0, 2.0)), 2, 2); _centerPatch = context.CreateVertexArray(centerMesh, _shaderProgram.VertexAttributes, BufferHint.StaticDraw); Mesh degenerateTriangleMesh = CreateDegenerateTriangleMesh(); _degenerateTrianglePatch = context.CreateVertexArray(degenerateTriangleMesh, _shaderProgram.VertexAttributes, BufferHint.StaticDraw); _patchOriginInClippedLevel = (Uniform <Vector2F>)_shaderProgram.Uniforms["u_patchOriginInClippedLevel"]; _levelScaleFactor = (Uniform <Vector2F>)_shaderProgram.Uniforms["u_levelScaleFactor"]; _levelZeroWorldScaleFactor = (Uniform <Vector2F>)_shaderProgram.Uniforms["u_levelZeroWorldScaleFactor"]; _levelOffsetFromWorldOrigin = (Uniform <Vector2F>)_shaderProgram.Uniforms["u_levelOffsetFromWorldOrigin"]; _heightExaggeration = (Uniform <float>)_shaderProgram.Uniforms["u_heightExaggeration"]; _viewPosInClippedLevel = (Uniform <Vector2F>)_shaderProgram.Uniforms["u_viewPosInClippedLevel"]; _fineLevelOriginInCoarse = (Uniform <Vector2F>)_shaderProgram.Uniforms["u_fineLevelOriginInCoarse"]; _unblendedRegionSize = (Uniform <Vector2F>)_shaderProgram.Uniforms["u_unblendedRegionSize"]; _oneOverBlendedRegionSize = (Uniform <Vector2F>)_shaderProgram.Uniforms["u_oneOverBlendedRegionSize"]; _fineTextureOrigin = (Uniform <Vector2F>)_shaderProgram.Uniforms["u_fineTextureOrigin"]; _showBlendRegions = (Uniform <bool>)_shaderProgram.Uniforms["u_showBlendRegions"]; _useBlendRegions = (Uniform <bool>)_shaderProgram.Uniforms["u_useBlendRegions"]; _oneOverClipmapSize = (Uniform <float>)_shaderProgram.Uniforms["u_oneOverClipmapSize"]; _color = (Uniform <Vector3F>)_shaderProgram.Uniforms["u_color"]; _blendRegionColor = (Uniform <Vector3F>)_shaderProgram.Uniforms["u_blendRegionColor"]; _terrainToImageryResolutionRatio = (Uniform <Vector2F>)_shaderProgram.Uniforms["u_terrainToImageryResolutionRatio"]; _terrainOffsetInImagery = (Uniform <Vector2F>)_shaderProgram.Uniforms["u_terrainOffsetInImagery"]; _oneOverImagerySize = (Uniform <Vector2F>)_shaderProgram.Uniforms["u_oneOverImagerySize"]; _showImagery = (Uniform <bool>)_shaderProgram.Uniforms["u_showImagery"]; _lighting = (Uniform <bool>)_shaderProgram.Uniforms["u_shade"]; ((Uniform <Vector3F>)_shaderProgram.Uniforms["u_globeRadiiSquared"]).Value = ellipsoid.RadiiSquared.ToVector3F(); _renderState = new RenderState(); _renderState.FacetCulling.FrontFaceWindingOrder = fieldBlockMesh.FrontFaceWindingOrder; _primitiveType = fieldBlockMesh.PrimitiveType; float oneOverBlendedRegionSize = (float)(10.0 / _clipmapPosts); _oneOverBlendedRegionSize.Value = new Vector2F(oneOverBlendedRegionSize, oneOverBlendedRegionSize); float unblendedRegionSize = (float)(_clipmapSegments / 2 - _clipmapPosts / 10.0 - 1); _unblendedRegionSize.Value = new Vector2F(unblendedRegionSize, unblendedRegionSize); _useBlendRegions.Value = true; _showImagery.Value = true; _oneOverClipmapSize.Value = 1.0f / clipmapPosts; _updater = new ClipmapUpdater(context, _clipmapLevels); HeightExaggeration = 0.00001f; }