public ClipmapUpdater(Context context, ClipmapLevel[] clipmapLevels) { ShaderVertexAttributeCollection vertexAttributes = new ShaderVertexAttributeCollection(); vertexAttributes.Add(new ShaderVertexAttribute("position", VertexLocations.Position, ShaderVertexAttributeType.FloatVector2, 1)); Mesh unitQuad = RectangleTessellator.Compute(new RectangleD(new Vector2D(0.0, 0.0), new Vector2D(1.0, 1.0)), 1, 1); _unitQuad = context.CreateVertexArray(unitQuad, vertexAttributes, BufferHint.StaticDraw); _unitQuadPrimitiveType = unitQuad.PrimitiveType; _sceneState = new SceneState(); _framebuffer = context.CreateFramebuffer(); _updateShader = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.ClipmapTerrain.ClipmapUpdateVS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.ClipmapTerrain.ClipmapUpdateFS.glsl")); _updateTexelOutput = _updateShader.FragmentOutputs["texelOutput"]; _updateDrawState = new DrawState(new RenderState(), _updateShader, _unitQuad); _updateDrawState.RenderState.FacetCulling.FrontFaceWindingOrder = unitQuad.FrontFaceWindingOrder; _updateDrawState.RenderState.DepthTest.Enabled = false; _updateDestinationOffset = (Uniform <Vector2F>)_updateShader.Uniforms["u_destinationOffset"]; _updateUpdateSize = (Uniform <Vector2F>)_updateShader.Uniforms["u_updateSize"]; _updateSourceOrigin = (Uniform <Vector2F>)_updateShader.Uniforms["u_sourceOrigin"]; _upsampleShader = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.ClipmapTerrain.ClipmapUpsampleVS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.ClipmapTerrain.ClipmapUpsampleFS.glsl")); _upsampleTexelOutput = _upsampleShader.FragmentOutputs["texelOutput"]; _upsampleDrawState = new DrawState(new RenderState(), _upsampleShader, _unitQuad); _upsampleDrawState.RenderState.FacetCulling.FrontFaceWindingOrder = unitQuad.FrontFaceWindingOrder; _upsampleDrawState.RenderState.DepthTest.Enabled = false; _upsampleSourceOrigin = (Uniform <Vector2F>)_upsampleShader.Uniforms["u_sourceOrigin"]; _upsampleUpdateSize = (Uniform <Vector2F>)_upsampleShader.Uniforms["u_updateSize"]; _upsampleDestinationOffset = (Uniform <Vector2F>)_upsampleShader.Uniforms["u_destinationOffset"]; _upsampleOneOverTextureSize = (Uniform <Vector2F>)_upsampleShader.Uniforms["u_oneOverTextureSize"]; _computeNormalsShader = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.ClipmapTerrain.ClipmapComputeNormalsVS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.ClipmapTerrain.ClipmapComputeNormalsFS.glsl")); _normalOutput = _computeNormalsShader.FragmentOutputs["normalOutput"]; _computeNormalsDrawState = new DrawState(new RenderState(), _computeNormalsShader, _unitQuad); _computeNormalsDrawState.RenderState.FacetCulling.FrontFaceWindingOrder = unitQuad.FrontFaceWindingOrder; _computeNormalsDrawState.RenderState.DepthTest.Enabled = false; _computeNormalsOrigin = (Uniform <Vector2F>)_computeNormalsShader.Uniforms["u_origin"]; _computeNormalsUpdateSize = (Uniform <Vector2F>)_computeNormalsShader.Uniforms["u_updateSize"]; _computeNormalsOneOverHeightMapSize = (Uniform <Vector2F>)_computeNormalsShader.Uniforms["u_oneOverHeightMapSize"]; _heightExaggeration = (Uniform <float>)_computeNormalsShader.Uniforms["u_heightExaggeration"]; _postDelta = (Uniform <float>)_computeNormalsShader.Uniforms["u_postDelta"]; HeightExaggeration = 1.0f; ClipmapLevel levelZero = clipmapLevels[0]; InitializeRequestThreads(context, _terrain, levelZero, levelZero.Terrain); InitializeRequestThreads(context, _imagery, levelZero, levelZero.Imagery); }
public VertexDisplacementMapTerrainTile(Context context, TerrainTile tile) { // // Upload height map as a one channel floating point texture // WritePixelBuffer pixelBuffer = Device.CreateWritePixelBuffer(PixelBufferHint.Stream, sizeof(float) * tile.Heights.Length); pixelBuffer.CopyFromSystemMemory(tile.Heights); _texture = Device.CreateTexture2DRectangle(new Texture2DDescription( tile.Resolution.X, tile.Resolution.Y, TextureFormat.Red32f)); _texture.CopyFromBuffer(pixelBuffer, ImageFormat.Red, ImageDatatype.Float); /////////////////////////////////////////////////////////////////// ShaderProgram spTerrain = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.VertexDisplacementMapTerrainTile.TerrainVS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.VertexDisplacementMapTerrainTile.TerrainFS.glsl")); _heightExaggerationUniform = (Uniform <float>)spTerrain.Uniforms["u_heightExaggeration"]; ((Uniform <Vector2F>)spTerrain.Uniforms["u_positionToTextureCoordinate"]).Value = new Vector2F( (float)(1.0 / (double)(tile.Resolution.X)), (float)(1.0 / (double)(tile.Resolution.Y))); ((Uniform <Vector2F>)spTerrain.Uniforms["u_positionToRepeatTextureCoordinate"]).Value = new Vector2F( (float)(4.0 / (double)tile.Resolution.X), (float)(4.0 / (double)tile.Resolution.Y)); /////////////////////////////////////////////////////////////////// ShaderProgram spNormals = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.VertexDisplacementMapTerrainTile.NormalsVS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.VertexDisplacementMapTerrainTile.NormalsGS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.VertexDisplacementMapTerrainTile.NormalsFS.glsl")); _heightExaggerationNormals = (Uniform <float>)spNormals.Uniforms["u_heightExaggeration"]; _fillDistanceNormals = (Uniform <float>)spNormals.Uniforms["u_fillDistance"]; ((Uniform <Vector3F>)spNormals.Uniforms["u_color"]).Value = Vector3F.Zero; /////////////////////////////////////////////////////////////////// ShaderProgram spWireframe = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.VertexDisplacementMapTerrainTile.WireframeVS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.VertexDisplacementMapTerrainTile.WireframeGS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.VertexDisplacementMapTerrainTile.WireframeFS.glsl")); _lineWidthWireframe = (Uniform <float>)spWireframe.Uniforms["u_halfLineWidth"]; _heightExaggerationWireframe = (Uniform <float>)spWireframe.Uniforms["u_heightExaggeration"]; ((Uniform <Vector3F>)spWireframe.Uniforms["u_color"]).Value = Vector3F.Zero; /////////////////////////////////////////////////////////////////// Mesh mesh = RectangleTessellator.Compute(new RectangleD(new Vector2D(0.5, 0.5), new Vector2D((double)tile.Resolution.X - 0.5, (double)tile.Resolution.Y - 0.5)), tile.Resolution.X - 1, tile.Resolution.Y - 1); _va = context.CreateVertexArray(mesh, spWireframe.VertexAttributes, BufferHint.StaticDraw); _primitiveType = mesh.PrimitiveType; /////////////////////////////////////////////////////////////////// RenderState rsTerrain = new RenderState(); rsTerrain.FacetCulling.FrontFaceWindingOrder = mesh.FrontFaceWindingOrder; RenderState rsWireframe = new RenderState(); rsWireframe.Blending.Enabled = true; rsWireframe.Blending.SourceRGBFactor = SourceBlendingFactor.SourceAlpha; rsWireframe.Blending.SourceAlphaFactor = SourceBlendingFactor.SourceAlpha; rsWireframe.Blending.DestinationRGBFactor = DestinationBlendingFactor.OneMinusSourceAlpha; rsWireframe.Blending.DestinationAlphaFactor = DestinationBlendingFactor.OneMinusSourceAlpha; rsWireframe.FacetCulling.FrontFaceWindingOrder = mesh.FrontFaceWindingOrder; rsWireframe.DepthTest.Function = DepthTestFunction.LessThanOrEqual; RenderState rsNormals = new RenderState(); rsNormals.FacetCulling.Enabled = false; rsNormals.Blending.Enabled = true; rsNormals.Blending.SourceRGBFactor = SourceBlendingFactor.SourceAlpha; rsNormals.Blending.SourceAlphaFactor = SourceBlendingFactor.SourceAlpha; rsNormals.Blending.DestinationRGBFactor = DestinationBlendingFactor.OneMinusSourceAlpha; rsNormals.Blending.DestinationAlphaFactor = DestinationBlendingFactor.OneMinusSourceAlpha; /////////////////////////////////////////////////////////////////// _drawStateTerrain = new DrawState(rsTerrain, spTerrain, _va); _drawStateWireframe = new DrawState(rsWireframe, spWireframe, _va); _drawStateNormals = new DrawState(rsNormals, spNormals, _va); _tileMinimumHeight = tile.MinimumHeight; _tileMaximumHeight = tile.MaximumHeight; _heightExaggeration = 1; _normalsAlgorithm = TerrainNormalsAlgorithm.ForwardDifference; _showTerrain = true; _dirty = true; }
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; }