Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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;
        }
Esempio n. 3
0
        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;
        }