public void Render(TerrainTile tile, TerrainGlobal terrainGlobal, Matrix4 projection, Matrix4 view, Vector3 eyePos)
        {
            var boxparam = tile.GetBoxParam();

            Vector3 eyePosTileCoords = Vector4.Transform(new Vector4(eyePos, 0.0f), tile.InverseModelMatrix).Xyz;

            GL.Enable(EnableCap.CullFace);
            GL.CullFace(CullFaceMode.Front);  // we only want to render back-faces

            tile.HeightTexture.Bind(TextureUnit.Texture0);
            tile.ParamTexture.Bind(TextureUnit.Texture1);
            tile.NormalTexture.Bind(TextureUnit.Texture2);

            this.boundingBoxProgram
                .UseProgram()
                .SetUniform("projection_matrix", projection)
                .SetUniform("model_matrix", tile.ModelMatrix)
                .SetUniform("view_matrix", view)
                .SetUniform("heightTex", 0)
                .SetUniform("paramTex", 1)
                .SetUniform("normalTex", 2)
                .SetUniform("eyePos", eyePos)
                .SetUniform("nEyePos", eyePosTileCoords)
                .SetUniform("boxparam", boxparam);
            this.vertexVBO.Bind(this.boundingBoxProgram.VariableLocation("vertex"));
            this.boxcoordVBO.Bind(this.boundingBoxProgram.VariableLocation("in_boxcoord"));
            this.indexVBO.Bind();
            GL.DrawElements(BeginMode.Triangles, this.indexVBO.Length, DrawElementsType.UnsignedInt, 0);
            Sampler.Unbind(TextureUnit.Texture0);
        }
        public void Render(TerrainTile tile, TerrainGlobal terrainGlobal, Matrix4 projection, Matrix4 view, Vector3 eye)
        {
            /*
            Vector3[] box = {
                                new Vector3(0f,0f,0f),
                                new Vector3(1f,0f,0f),
                                new Vector3(0f,0f,1f),
                                new Vector3(1f,0f,1f),
                                new Vector3(0f,1f,0f),
                                new Vector3(1f,1f,0f),
                                new Vector3(0f,1f,1f),
                                new Vector3(1f,1f,1f)
                            };

            // build box
            var projbox = box
                .Select(v => new Vector4(v.X * tile.Width, tile.MinHeight + v.Y * (tile.MaxHeight - tile.MinHeight), v.Z * tile.Height, 1.0f))
                .Select(v => Vector4.Transform(Vector4.Transform(Vector4.Transform(v, tile.ModelMatrix), view), projection))
                .Select(v=> new Vector2(v.X / v.W, v.Y / v.W))
                .ToArray();

            // width on screen
            var screenWidth = projbox.Select(v => v.X).Max() - projbox.Select(v => v.X).Min();
            */

            // compute distance from tile to eye
            var centre = Vector4.Transform(new Vector4(0.5f * (float)tile.Width, 0.0f, 0.5f * (float)tile.Height, 1.0f), tile.ModelMatrix);
            var distanceToCentre = (centre.Xz - eye.Xz).Length;

            if (distanceToCentre < 500.0f)  // todo: reference to pixels
            {
                distantRenderer.Render(tile, terrainGlobal, projection, view, eye);
                return;
            }
            middleRenderer.Render(tile, terrainGlobal, projection, view, eye);
        }
        public void Render(TerrainTile tile, TerrainGlobal terrainGlobal, Matrix4 projection, Matrix4 view, Vector3 eyePos)
        {
            var boxparam = tile.GetBoxParam();

            GL.Disable(EnableCap.CullFace);
            //GL.CullFace(CullFaceMode.Back);  // we only want to render front-faces

            tile.HeightTexture.Bind(TextureUnit.Texture0);
            tile.ParamTexture.Bind(TextureUnit.Texture1);
            tile.NormalTexture.Bind(TextureUnit.Texture2);

            if (this.DetailTexture != null)
            {
                this.DetailTexture.Bind(TextureUnit.Texture3);
            }

            this.shader
                .UseProgram()
                .SetUniform("projection_matrix", projection)
                .SetUniform("model_matrix", tile.ModelMatrix)
                .SetUniform("view_matrix", view)
                .SetUniform("heightTex", 0)
                .SetUniform("paramTex", 1)
                .SetUniform("normalTex", 2)
                .SetUniform("detailTex", 3)
                .SetUniform("eyePos", eyePos)
                .SetUniform("boxparam", boxparam)
                .SetUniform("patchSize", this.Width)
                .SetUniform("scale", this.Scale)
                .SetUniform("offset", this.Offset)
                .SetUniform("detailTexScale", this.DetailTexScale);
            //this.mesh.Bind(this.shader.VariableLocation("vertex"), this.shader.VariableLocation("in_boxcoord"));
            //this.mesh.Render();
            this.vertexVBO.Bind(this.shader.VariableLocation("vertex"));
            this.boxcoordVBO.Bind(this.shader.VariableLocation("in_boxcoord"));
            this.indexVBO.Bind();

            GL.DrawElements(BeginMode.Lines, this.indexVBO.Length, DrawElementsType.UnsignedInt, 0);

            //Sampler.Unbind(TextureUnit.Texture0);
        }
        public void Render(TerrainTile tile, TerrainGlobal terrainGlobal, Matrix4 projection, Matrix4 view, Vector3 eyePos)
        {
            var boxparam = tile.GetBoxParam();

            //Matrix4 transform = projection * view * tile.ModelMatrix;
            Matrix4 transform = tile.ModelMatrix * view * projection;

            GL.Enable(EnableCap.CullFace);
            GL.CullFace(CullFaceMode.Back);  // we only want to render front-faces

            tile.HeightTexture.Bind(TextureUnit.Texture0);
            tile.ParamTexture.Bind(TextureUnit.Texture1);
            tile.NormalTexture.Bind(TextureUnit.Texture2);
            terrainGlobal.ShadeTexture.Bind(TextureUnit.Texture3);
            terrainGlobal.TerrainDetailTexture.Bind(TextureUnit.Texture4);

            this.shader
                .UseProgram()
                .SetUniform("transform_matrix", transform)
                .SetUniform("heightTex", 0)
                .SetUniform("paramTex", 1)
                .SetUniform("normalTex", 2)
                .SetUniform("shadeTex", 3)
                .SetUniform("detailTex", 4)
                .SetUniform("eyePos", eyePos)
                .SetUniform("boxparam", boxparam)
                .SetUniform("patchSize", this.Width)
                .SetUniform("scale", this.Scale)
                .SetUniform("offset", this.Offset)
                .SetUniform("detailTexScale", this.DetailTexScale);
            this.mesh.Bind(this.shader.VariableLocation("vertex"), this.shader.VariableLocation("in_boxcoord"));
            this.mesh.Render();
        }
        public void Render(TerrainTile tile, TerrainGlobal terrainGlobal, Matrix4 projection, Matrix4 view, Vector3 eye)
        {
            Vector3 xformeye = Vector4.Transform(new Vector4(eye, 0.0f), tile.InverseModelMatrix).Xyz;

            // construct our top-level quadtree node
            var root = new QuadTreeNode()
            {
                TopLeft = new QuadTreeVertex()
                {
                    Position = new Vector3(0f, 0f, 0f)
                    //Position = Vector3.Transform(new Vector3(0f, 0f, 0f), tile.ModelMatrix)
                },
                TopRight = new QuadTreeVertex()
                {
                    Position = new Vector3((float)tile.Width, 0f, 0f)
                    //Position = Vector3.Transform(new Vector3((float)tile.Width, 0f, 0f), tile.ModelMatrix)
                },
                BottomLeft = new QuadTreeVertex()
                {
                    Position = new Vector3(0f, 0f, (float)tile.Height)
                    //Position = Vector3.Transform(new Vector3(0f, 0f, (float)tile.Height), tile.ModelMatrix)
                },
                BottomRight = new QuadTreeVertex()
                {
                    Position = new Vector3((float)tile.Width, 0f, (float)tile.Height)
                    //Position = Vector3.Transform(new Vector3((float)tile.Width, 0f, (float)tile.Height), tile.ModelMatrix)
                },
                TileSize = tile.Width // assume width == height
            };

            // check to see if we're completely outside the far detail radius
            if (!root.IsViewerInDetailRange(xformeye, this.DistantTileRadius))
            {
                var distrenderer = (IPatchRenderer)fullTileDistantRenderer;

                //float distancepastdetail = (xformeye.Xz - new Vector2((float)tile.Width * 0.5f,(float)tile.Height * 0.5f)).Length - ;

                distrenderer.Width = tile.Width / 16;
                distrenderer.Height = distrenderer.Width;
                //distrenderer.DetailScale = (float)this.TileSize / (float)tileDetailRenderer.Width;
                distrenderer.Scale = 1.0f;
                distrenderer.Offset = new Vector2(0.0f, 0.0f);

                fullTileDistantRenderer.Render(tile, terrainGlobal, projection, view, eye);
            }
            else // check inner detail radius
            {
                if (!root.IsViewerInDetailRange(xformeye, this.DetailRadius))
                {
                    // HACK because we're using the same patch renderer as the detail patches and it keeps state
                    (fullTileNearRenderer as IPatchRenderer).Scale = 1.0f;
                    (fullTileNearRenderer as IPatchRenderer).Offset = Vector2.Zero;
                    (fullTileNearRenderer as IPatchRenderer).Width = tile.Width;
                    (fullTileNearRenderer as IPatchRenderer).Height = tile.Height;

                    fullTileNearRenderer.Render(tile, terrainGlobal, projection, view, eye);
                }
                else
                {
                    root.Render(tile, terrainGlobal, projection, view, eye, xformeye, this.DetailRadius, this.subTileRenderer, this.subTileDetailRenderer);
                }
            }
        }
            public void Render(TerrainTile tile, TerrainGlobal terrainGlobal, Matrix4 projection, Matrix4 view, Vector3 eye, Vector3 reye, float detailRadius, IPatchRenderer tileRenderer, IPatchRenderer tileDetailRenderer)
            {
                // can we render this tile without subdividing?

                // we can render now once we've got to a small enough tile
                if (this.TileSize <= 8)  //4
                {
                    tileDetailRenderer.Width = GetDetailTileSize(reye, detailRadius);
                    tileDetailRenderer.Height = tileDetailRenderer.Width;
                    tileDetailRenderer.DetailScale = (float)this.TileSize / (float)tileDetailRenderer.Width;
                    tileDetailRenderer.Scale = (float)this.TileSize / (float)tile.Width;
                    tileDetailRenderer.Offset = (this.TopLeft.Position.Xz / (float)tile.Width);
                    tileDetailRenderer.Render(tile, terrainGlobal, projection, view, eye);
                    return;
                }

                if (!IsViewerInDetailRange(reye, detailRadius))
                {
                    // we can if we're outside the detail radius
                    tileRenderer.Width = this.TileSize;
                    tileRenderer.Height = this.TileSize;
                    tileRenderer.Scale = (float)this.TileSize / (float)tile.Width;
                    tileRenderer.Offset = (this.TopLeft.Position.Xz / (float)tile.Width);
                    tileRenderer.Render(tile, terrainGlobal, projection, view, eye);
                    return;
                }

                // split into 4 - need centre pos
                Vector3 centre = (TopLeft.Position + BottomRight.Position) * 0.5f;

                // top left child
                new QuadTreeNode()
                {
                    TopLeft = this.TopLeft,
                    TopRight = new QuadTreeVertex() { Position = new Vector3(centre.X, 0f, this.TopLeft.Position.Z) },
                    BottomLeft = new QuadTreeVertex() { Position = new Vector3(this.TopLeft.Position.X, 0f, centre.Z) },
                    BottomRight = new QuadTreeVertex() { Position = centre },
                    TileSize = this.TileSize / 2
                }.Render(tile, terrainGlobal, projection, view, eye, reye, detailRadius, tileRenderer, tileDetailRenderer);

                // top right child
                new QuadTreeNode()
                {
                    TopLeft = new QuadTreeVertex() { Position = new Vector3(centre.X, 0f, this.TopRight.Position.Z) },
                    TopRight = this.TopRight,
                    BottomLeft = new QuadTreeVertex() { Position = centre },
                    BottomRight = new QuadTreeVertex() { Position = new Vector3(this.TopRight.Position.X, 0f, centre.Z) },
                    TileSize = this.TileSize / 2
                }.Render(tile, terrainGlobal, projection, view, eye, reye, detailRadius, tileRenderer, tileDetailRenderer);

                // bottom left child
                new QuadTreeNode()
                {
                    TopLeft = new QuadTreeVertex() { Position = new Vector3(this.BottomLeft.Position.X, 0f, centre.Z) },
                    TopRight = new QuadTreeVertex() { Position = centre },
                    BottomLeft = this.BottomLeft,
                    BottomRight = new QuadTreeVertex() { Position = new Vector3(centre.X, 0f, this.BottomLeft.Position.Z) },
                    TileSize = this.TileSize / 2
                }.Render(tile, terrainGlobal, projection, view, eye, reye, detailRadius, tileRenderer, tileDetailRenderer);

                // bottom right child
                new QuadTreeNode()
                {
                    TopLeft = new QuadTreeVertex() { Position = centre },
                    TopRight = new QuadTreeVertex() { Position = new Vector3(this.BottomRight.Position.X, 0f, centre.Z) },
                    BottomLeft = new QuadTreeVertex() { Position = new Vector3(centre.X, 0f, this.BottomRight.Position.Z) },
                    BottomRight = this.BottomRight,
                    TileSize = this.TileSize / 2
                }.Render(tile, terrainGlobal, projection, view, eye, reye, detailRadius, tileRenderer, tileDetailRenderer);
            }
Example #7
0
        public void Render(TerrainTile tile, TerrainGlobal terrainGlobal, Matrix4 projection, Matrix4 view, Vector3 eyePos, float angleOffset, float angleExtent, float radiusOffset, float radiusExtent)
        {
            var boxparam = tile.GetBoxParam();

            // undo view translation to centre mesh on viewer
            //Matrix4 transform = Matrix4.CreateTranslation(-eyePos.X, 0f, -eyePos.Z) * view * projection;
            Matrix4 transform = Matrix4.Identity * view * projection;

            GL.Enable(EnableCap.CullFace);
            GL.CullFace(CullFaceMode.Back);  // we only want to render front-faces

            tile.HeightTexture.Bind(TextureUnit.Texture0);
            tile.ParamTexture.Bind(TextureUnit.Texture1);
            tile.NormalTexture.Bind(TextureUnit.Texture2);
            terrainGlobal.ShadeTexture.Bind(TextureUnit.Texture3);
            terrainGlobal.TerrainDetailTexture.Bind(TextureUnit.Texture4);

            this.shader
                .UseProgram()
                .SetUniform("angleOffset", angleOffset)
                .SetUniform("angleExtent", angleExtent)
                .SetUniform("radiusOffset", radiusOffset)
                .SetUniform("radiusExtent", radiusExtent)
                .SetUniform("transform_matrix", transform)
                .SetUniform("heightTex", 0)
                .SetUniform("paramTex", 1)
                .SetUniform("normalTex", 2)
                .SetUniform("shadeTex", 3)
                .SetUniform("detailTex", 4)
                .SetUniform("eyePos", eyePos)
                .SetUniform("boxparam", boxparam)
                .SetUniform("patchSize", this.Width)
                .SetUniform("scale", this.Scale)
                .SetUniform("offset", this.Offset)
                .SetUniform("detailTexScale", this.DetailTexScale);
            this.mesh.Bind(this.shader.VariableLocation("vertex"), this.shader.VariableLocation("in_boxcoord"));
            this.mesh.Render();
        }
Example #8
0
 public void Render(TerrainTile tile, TerrainGlobal terrainGlobal, Matrix4 projection, Matrix4 view, Vector3 eyePos)
 {
     throw new InvalidOperationException("wrong render function");
 }