Пример #1
0
        /// <summary>
        /// This callback function will be called immediately after the Direct3D device has
        /// been destroyed, which generally happens as a result of application termination or
        /// windowed/full screen toggles. Resources created in the OnCreateDevice callback
        /// should be released here, which generally includes all Pool.Managed resources.
        /// </summary>
        private void OnDestroyDevice(object sender, EventArgs e)
        {
            meshTextures  = null;
            meshMaterials = null;

            if (fullMesh != null)
            {
                fullMesh.Dispose();
            }

            if ((meshes != null) && (meshes.Length > 0))
            {
                for (int i = 0; i < meshes.Length; i++)
                {
                    if (meshes[i] != null)
                    {
                        meshes[i].Dispose();
                    }
                }
            }
            meshes = null;
        }
Пример #2
0
        private void CreateLod()
        {
            ProgressiveMesh pPMesh           = null;
            int             cVerticesMin     = 0;
            int             cVerticesMax     = 0;
            int             cVerticesPerMesh = 0;

            pPMesh = new ProgressiveMesh(m_mesh, m_adj, null, 1, MeshFlags.SimplifyVertex);

            cVerticesMin = pPMesh.MinVertices;
            cVerticesMax = pPMesh.MaxVertices;

            if (m_pMeshes != null)
            {
                for (int iPMesh = 0; iPMesh < m_pMeshes.Length; iPMesh++)
                {
                    m_pMeshes[iPMesh].Dispose();
                }
            }

            cVerticesPerMesh = (cVerticesMax - cVerticesMin) / m_nNumLOD;
            m_pMeshes        = new ProgressiveMesh[m_nNumLOD];

            // clone all the separate m_pMeshes
            for (int iPMesh = 0; iPMesh < m_pMeshes.Length; iPMesh++)
            {
                m_pMeshes[m_pMeshes.Length - 1 - iPMesh] = pPMesh.Clone(MeshFlags.Managed | MeshFlags.VbShare, pPMesh.VertexFormat, CGameEngine.Device3D);
                // trim to appropriate space
                if (m_nNumLOD > 1)
                {
                    m_pMeshes[m_pMeshes.Length - 1 - iPMesh].TrimByVertices(cVerticesMin + cVerticesPerMesh * iPMesh, cVerticesMin + cVerticesPerMesh * (iPMesh + 1));
                }

                m_pMeshes[m_pMeshes.Length - 1 - iPMesh].OptimizeBaseLevelOfDetail(MeshFlags.OptimizeVertexCache);
            }
            m_currentPmesh = 0;
            m_pMeshes[m_currentPmesh].NumberVertices = cVerticesMax;
            pPMesh.Dispose();
        }
Пример #3
0
        /// <summary>
        /// The device has been created.  Resources that are not lost on
        /// Reset() can be created here -- resources in Pool.Managed,
        /// Pool.Scratch, or Pool.SystemMemory.  Image surfaces created via
        /// CreateImageSurface are never lost and can be created here.  Vertex
        /// shaders and pixel shaders can also be created here as they are not
        /// lost on Reset().
        /// </summary>
        protected override void InitializeDeviceObjects()
        {
            // Initialize the font's internal textures
            font.InitializeDeviceObjects(device);

            string         path      = DXUtil.FindMediaFile(initialDirectory, meshFilename);
            Mesh           pMesh     = null;
            Mesh           pTempMesh = null;
            GraphicsStream adj       = null;

            ExtendedMaterial[] mtrl = null;
            MeshFlags          i32BitFlag;
            WeldEpsilons       Epsilons = new WeldEpsilons();
            ProgressiveMesh    pPMesh   = null;
            int cVerticesMin            = 0;
            int cVerticesMax            = 0;
            int cVerticesPerMesh        = 0;

            try
            {
                // Load the mesh from the specified file
                pMesh      = Mesh.FromFile(path, MeshFlags.Managed, device, out adj, out mtrl);
                i32BitFlag = pMesh.Options.Use32Bit ? MeshFlags.Use32Bit : 0;

                // perform simple cleansing operations on mesh
                pTempMesh = Mesh.Clean(pMesh, adj, adj);
                pMesh.Dispose();
                pMesh = pTempMesh;

                //  Perform a weld to try and remove excess vertices like the model bigship1.x in the DX9.0 SDK (current model is fixed)
                //    Weld the mesh using all epsilons of 0.0f.  A small epsilon like 1e-6 works well too
                pMesh.WeldVertices(0, Epsilons, adj, adj);
                // verify validity of mesh for simplification
                pMesh.Validate(adj);

                meshMaterials = new Direct3D.Material[mtrl.Length];
                meshTextures  = new Texture[mtrl.Length];
                for (int i = 0; i < mtrl.Length; i++)
                {
                    meshMaterials[i]         = mtrl[i].Material3D;
                    meshMaterials[i].Ambient = meshMaterials[i].Diffuse;
                    if ((mtrl[i].TextureFilename != null) && (mtrl[i].TextureFilename != ""))
                    {
                        path = DXUtil.FindMediaFile(initialDirectory, mtrl[i].TextureFilename);
                        // Find the path to the texture and create that texture
                        try
                        {
                            meshTextures[i] = TextureLoader.FromFile(device, path);
                        }
                        catch
                        {
                            meshTextures[i] = null;
                        }
                    }
                }

                // Lock the vertex buffer to generate a simple bounding sphere
                VertexBuffer   vb         = pMesh.VertexBuffer;
                GraphicsStream vertexData = vb.Lock(0, 0, LockFlags.NoSystemLock);
                objectRadius = Geometry.ComputeBoundingSphere(vertexData, pMesh.NumberVertices, pMesh.VertexFormat, out objectCenter);
                vb.Unlock();
                vb.Dispose();
                if (meshMaterials.Length == 0)
                {
                    throw new Exception();
                }

                if ((pMesh.VertexFormat & VertexFormats.Normal) == 0)
                {
                    pTempMesh = pMesh.Clone(i32BitFlag | MeshFlags.Managed, pMesh.VertexFormat | VertexFormats.Normal, device);
                    pTempMesh.ComputeNormals();
                    pMesh.Dispose();
                    pMesh = pTempMesh;
                }
                pPMesh = new ProgressiveMesh(pMesh, adj, null, 1, MeshFlags.SimplifyVertex);

                cVerticesMin = pPMesh.MinVertices;
                cVerticesMax = pPMesh.MaxVertices;

                cVerticesPerMesh = (cVerticesMax - cVerticesMin) / 10;
                pmeshes          = new ProgressiveMesh[(int)Math.Max(1, Math.Ceiling((cVerticesMax - cVerticesMin) / (float)cVerticesPerMesh))];

                // clone full size pmesh
                fullPmesh = pPMesh.Clone(MeshFlags.Managed | MeshFlags.VbShare, pPMesh.VertexFormat, device);

                // clone all the separate pmeshes
                for (int iPMesh = 0; iPMesh < pmeshes.Length; iPMesh++)
                {
                    pmeshes[iPMesh] = pPMesh.Clone(MeshFlags.Managed | MeshFlags.VbShare, pPMesh.VertexFormat, device);
                    // trim to appropriate space
                    pmeshes[iPMesh].TrimByVertices(cVerticesMin + cVerticesPerMesh * iPMesh, cVerticesMin + cVerticesPerMesh * (iPMesh + 1));

                    pmeshes[iPMesh].OptimizeBaseLevelOfDetail(MeshFlags.OptimizeVertexCache);
                }
                currentPmesh = pmeshes.Length - 1;
                pmeshes[currentPmesh].NumberVertices = cVerticesMax;
                fullPmesh.NumberVertices             = cVerticesMax;
                pPMesh.Dispose();
            }
            catch
            {
                // hide error so that device changes will not cause exit, shows blank screen instead
                return;
            }
        }