public override void Render()
        {
            if (has_vertices())
            {
                //draw triangles
                Material.AmbientColor     = new Color(255, 40, 40, 40);
                Material.DiffuseColor     = new Color(255, 100, 255, 0);
                Material.SpecularColor    = new Color(255, 255, 255, 255);
                Material.EmissiveColor    = new Color(255, 0, 0, 0);
                Material.Wireframe        = false;
                Material.Lighting         = true;
                Material.BackfaceCulling  = false;
                Material.NormalizeNormals = false;

                _driver.SetMaterial(Material);
                _driver.SetTransform(TransformationState.World, AbsoluteTransformation);

                _driver.DrawMeshBuffer(get_mesh_buffer());


                //draw lines
                Material.Wireframe        = true;
                Material.Lighting         = false;
                Material.BackfaceCulling  = false;
                Material.NormalizeNormals = false;

                _driver.SetMaterial(Material);

                _driver.DrawMeshBuffer(get_mesh_buffer());
            }
        }
Ejemplo n.º 2
0
        public void Draw(bool debugDrawGenerator = false)
        {
            VideoDriver driver = device.VideoDriver;

            // draw

            driver.SetMaterial(cubeMaterial);
            foreach (GridLayer l in layers)
            {
                if (!l.MeshIsReady)
                {
                    continue;
                }

                driver.SetTransform(TransformationState.World, l.Transform);
                foreach (MeshBuffer mb in l.Mesh.MeshBuffers)
                {
                    driver.DrawMeshBuffer(mb);
                }
            }

            // draw debug info

            if (debugDrawGenerator)
            {
                foreach (GridLayer l in layers)
                {
                    if (!l.MeshIsReady)
                    {
                        continue;
                    }

                    if (l.Generation == gridGeneration - 1)
                    {
                        driver.SetMaterial(Material.IdentityRedWireframe);
                        driver.SetTransform(TransformationState.World, l.Transform);

                        Color c  = Color.SolidRed;
                        float x1 = -(CubeSize * GridDim) / 2;
                        float z1 = -(CubeSize * GridDim) / 2;
                        float x2 = x1 + (GridDim - 1) * CubeSize;
                        float z2 = z1 + (GridDim - 1) * CubeSize;

                        driver.Draw3DLine(new Line3Df(x1, 0, z1, x2, 0, z1), c);
                        driver.Draw3DLine(new Line3Df(x1, 0, z1, x1, 0, z2), c);
                        driver.Draw3DLine(new Line3Df(x2, 0, z1, x2, 0, z2), c);
                        driver.Draw3DLine(new Line3Df(x1, 0, z2, x2, 0, z2), c);

                        foreach (MeshBuffer mb in l.Mesh.MeshBuffers)
                        {
                            driver.DrawMeshBuffer(mb);
                        }

                        break;
                    }
                }
            }
        }
Ejemplo n.º 3
0
        public void Draw(uint time, Vector3Df cameraPosition)
        {
            if (time > nextUpdateAt)
            {
                // animation

                transformation.Rotation = rotationVector * time;

                // recalculate current LOD

                currentLOD = meshLODs.Count - 1;
                float distanceSQ = (transformation.Translation - cameraPosition).LengthSQ;
                for (int i = 0; i < lodDistanceSQ.Length - 1; i++)
                {
                    if (distanceSQ < lodDistanceSQ[i])
                    {
                        currentLOD = i;
                        break;
                    }
                }

                // next line assigns new time for LOD to be recalculated in future,
                // we do not use same value for all LODs here, because we don't want all the LODItems
                // to be recalculated in the same time (same frame). So we assign a value
                // which higher when current LOD is higher - which also means that for now we are
                // a distant object and it is less possible that we will need to change LOD at all;
                // but close objects (with small LOD value, like 0, 1 or 2) we need to pick quite short time.
                // This is OK if it will be really short, because these objects are too close and indeed may
                // change their LOD value very soon, however, we also understand, that in general all the objects
                // takes very large area, so in general we will have something like less than 2% with LOD level 0, 1 or 2,
                // all other will get higher LOD, and about more than 50% will have maximum LOD value -- they take more time to recalc
                // their LOD than to draw them, so we need to calc their LOD less frequent.
                // p.s.: we also use the fact, that we do not give user ability to reach oposite side of our world in 1 frame,
                // the speed at which user moves is slow in general.

                nextUpdateAt = time + updateIntervals[currentLOD];
            }

            // drawing

            // we do no set material here, because we draw all LODItems with the same material, we set material in main rendering loop

            driver.SetTransform(TransformationState.World, transformation);             // this is also very time consuming operation; we can optimize it
            // to make something like 100 calls (instead of 5000 - the number of LODItems) - we need to group LODItems all this we increase FPS up on
            // 10%, BUT it that case we will not be able to move independent LODItems, becase they will not need (and will not have) own transformation
            // matrix (only LODGroup will has it). So grouping is really greate for some completly static objects like trees, shrubs, stones, etc.

            // we draw single 16-bit meshbuffer
            driver.DrawMeshBuffer(meshLODs[currentLOD].GetMeshBuffer(0));

            if (LabelPositions != null && currentLOD <= 4)
            {
                Vector2Di p = device.SceneManager.SceneCollisionManager.GetScreenCoordinatesFrom3DPosition(transformation.Translation);

                // now we filter here results which will not be visible; we know that:
                // - GetScreenCoordinatesFrom3DPosition() returns {-10000,-10000} for behind camera 3d positions
                // - we do not need to draw out small text if its out of the screen
                // p.s.: without this filtering we will have about 200-300 labels to draw (instead of about 10-20 which are trully visible)
                if (p.X > -200 && p.X < screenSize.Width + 200 &&
                    p.Y > -100 && p.Y < screenSize.Height + 100)
                {
                    int t = meshLODs[currentLOD].GetMeshBuffer(0).IndexCount / 3;
                    int d = (int)(transformation.Translation - cameraPosition).Length;

                    LabelPositions.Add(p);
                    LabelTexts.Add(
                        "LOD: " + currentLOD.ToString() +
                        "\nTrinagles: " + t.ToString() +
                        "\nDistance: " + d.ToString());
                }
            }
        }