/// <summary> /// The device exists, but may have just been Reset(). Resources /// and any other device state that persists during /// rendering should be set here. Render states, matrices, textures, /// etc., that don't change during rendering can be set once here to /// avoid redundant state setting during Render() or FrameMove(). /// </summary> public void RestoreDeviceObjects(object obj, EventArgs eventg) { string[] textureFilenames = null; meshValue = MeshLoader.LoadMesh(device, embeddedResourceAssembly.GetManifestResourceStream( resourcePrefix + meshName), MeshFlags.SystemMemory, out meshMaterials, out textureFilenames); meshTextures = new Texture[meshMaterials.Length]; for (int i = 0; i < meshMaterials.Length; i++) { // Set the ambient color for the material // (D3DX does not do this) meshMaterials[i].Ambient = meshMaterials[i].Diffuse; // Create the texture if (textureFilenames[i] != null) { meshTextures[i] = TextureLoader.FromStream(device, embeddedResourceAssembly.GetManifestResourceStream( resourcePrefix + textureFilenames[i])); } } // if the mesh was not loaded in the desired vertex format // it can be changed here if ((vf != meshValue.VertexFormat) && vfSet) { Mesh temp = meshValue.Clone(0, vf, meshValue.Device); meshValue.Dispose(); meshValue = temp; } }
/// <summary> /// Handles device reset events /// </summary> /// <param name="sender">The device which sent the event</param> /// <param name="e">Ignored</param> void OnResetDevice(object sender, EventArgs e) { string[] textureFilenames = null; Device dev = (Device)sender; // Turn on the zbuffer dev.RenderState.ZBufferEnable = true; // Turn on ambient lighting dev.RenderState.Ambient = System.Drawing.Color.White; // Turn on perspective correction for textures // This provides a more accurate visual at the cost // of a small performance overhead dev.RenderState.TexturePerspective = true; // Load the mesh from the specified file mesh = MeshLoader.LoadMesh(device, Assembly.GetExecutingAssembly().GetManifestResourceStream( "Meshes.Content.tiger.md3dm"), MeshFlags.SystemMemory, out meshMaterials, out textureFilenames); // Extract the material properties and texture names meshTextures = new Texture[meshMaterials.Length]; for (int i = 0; i < meshMaterials.Length; i++) { // Set the ambient color for the material // (D3DX does not do this) meshMaterials[i].Ambient = meshMaterials[i].Diffuse; // Create the texture meshTextures[i] = TextureLoader.FromStream(dev, Assembly.GetExecutingAssembly().GetManifestResourceStream( "Meshes.Content." + textureFilenames[i])); } }
/// <summary> /// The main entry point for the application. /// </summary> static void Main(string[] args) { // the D3D render device Device device = null; // stores the materials and texture filenames for the mesh ExtendedMaterial [] exmat = null; // The D3D materials extracted from the mesh Material [] mat = null; // The texture filenames extracted from the mesh String [] tex = null; // the mesh to be converted Mesh mesh = null; // Some usage help if there are inappropriate command line // arguments if (args.Length != 2) { System.Console.Write("Usage: MeshConverter <input_mesh> " + "<output_mesh>\n" + "This program converts .X files into a smaller " + "binary format\n"); return; } try { // create the D3D device PresentParameters presentParams = new PresentParameters(); presentParams.SwapEffect = SwapEffect.Discard; presentParams.Windowed = true; device = new Device(0, DeviceType.NullReference, new Form(), CreateFlags.SoftwareVertexProcessing, presentParams); } catch (Exception e) { // handle any errors System.Console.WriteLine( String.Format(CultureInfo.CurrentCulture, "Error initializing D3D: {0}", e.Message)); return; } // load the mesh try { mesh = Mesh.FromFile(args[0], MeshFlags.Dynamic, device, out exmat); } catch (Exception e) { System.Console.WriteLine( String.Format(CultureInfo.CurrentCulture, "Error loading the mesh: {0}", e.Message)); return; } try { // optimize the mesh GraphicsStream gx = null; mesh.OptimizeInPlace(MeshFlags.OptimizeDeviceIndependent | MeshFlags.OptimizeAttributeSort | MeshFlags.OptimizeCompact, gx); // extract the materials and texture filenames mat = new Material[exmat.Length]; tex = new string[exmat.Length]; for (int i = 0; i < exmat.Length; i++) { mat[i] = exmat[i].Material3D; tex[i] = exmat[i].TextureFilename; } } catch (Exception e) { // handle any errors System.Console.WriteLine( String.Format(CultureInfo.CurrentCulture, "Error optimizing the mesh: {0}", e.Message)); } try { // save the mesh FileStream fstream = new FileStream(args[1], FileMode.Create); MeshLoader.SaveMesh(fstream, mesh, mat, tex); fstream.Close(); } catch (Exception e) { // handle any errors System.Console.WriteLine( String.Format(CultureInfo.CurrentCulture, "Error saving the mesh: {0}", e.Message)); } }
/// <summary> /// Saves a mesh to the custom serialized format /// </summary> /// <param name="stream">The stream to which to serialize</param> /// <param name="mesh">The mesh to be serialized</param> /// <param name="materials">The materials for subparts of the mesh /// </param> /// <param name="textures">The filenames for the textures on /// subparts of the mesh</param> public static void SaveMesh(Stream stream, Mesh mesh, Material [] materials, string [] textures) { int flexibleVertexFormat; int numberVertices; byte [] vertices; int numberIndices; byte [] indices; AttributeRange [] attributeRanges; VertexFormats sourceVertexFormat; VertexFormats sourceFormat; IDisposable tempMesh; tempMesh = null; try { // Managed Direct3D mobile uses different Fvf defines than // managed Direct3D for the desktop // when this code is linked against the desktop version // this will convert the Fvf to match MD3DM constants // when this code is linked against MD3DM this section will // not have changed anything. // determine the necessary Fvf sourceVertexFormat = mesh.VertexFormat; int textureCount; sourceFormat = VertexFormats.Position; flexibleVertexFormat = 0; if ((sourceVertexFormat & VertexFormats.Normal) != 0) { flexibleVertexFormat |= md3dmFvfNormal; sourceFormat |= VertexFormats.Normal; } if ((sourceVertexFormat & VertexFormats.Diffuse) != 0) { flexibleVertexFormat |= md3dmFvfDiffuse; sourceFormat |= VertexFormats.Diffuse; } if ((sourceVertexFormat & VertexFormats.Specular) != 0) { flexibleVertexFormat |= md3dmFvfDiffuse; sourceFormat |= VertexFormats.Specular; } // determine number of textures textureCount = (int)(sourceVertexFormat & VertexFormats.TextureCountMask) >> (int)VertexFormats.TextureCountShift; //limit to 4 textures if (textureCount > 4) { textureCount = 4; } // continue setting up necessary fvf sourceFormat |= (VertexFormats)(textureCount << (int)VertexFormats.TextureCountShift); flexibleVertexFormat |= (textureCount << md3dmFvfTextureCountShift); if (sourceFormat != sourceVertexFormat) { mesh = mesh.Clone(mesh.Options.Value, sourceFormat, mesh.Device); tempMesh = (IDisposable)mesh; } attributeRanges = mesh.GetAttributeTable(); if (attributeRanges == null) { throw new MeshSerializationException( "No Attribute table present"); } // determine number of vertices and create buffer numberVertices = mesh.NumberVertices; vertices = new byte[numberVertices * VertexInformation.GetFormatSize(sourceFormat)]; // copy vertices to buffer mesh.VertexBuffer.Lock(0, vertices.Length, LockFlags.None).Read(vertices, 0, vertices.Length); mesh.VertexBuffer.Unlock(); // determine number of indices numberIndices = mesh.NumberFaces * 3; // create index data buffer indices = new byte[numberIndices * (mesh.Options.Use32Bit ? 4 : 2)]; // fill index data into buffer mesh.IndexBuffer.Lock(0, indices.Length, LockFlags.None).Read(indices, 0, indices.Length); mesh.IndexBuffer.Unlock(); // write the data out to file MeshLoader.SaveMeshData(stream, flexibleVertexFormat, numberVertices, vertices, numberIndices, indices, attributeRanges, materials, textures); } finally { if (tempMesh != null) { tempMesh.Dispose(); } } }