/// <unmanaged>HRESULT IDirect3DDevice9::GetFVF([Out] D3DFVF* pFVF)</unmanaged> public unsafe HRESULT GetFVF(out D3DFVF vertexFormat) { fixed(void *ptr = &vertexFormat) { //result = calli(System.Int32(System.Void*,System.Void*), this._nativePointer, ptr, *(*(IntPtr*)this._nativePointer + (IntPtr)90 * (IntPtr)sizeof(void*))); return((HRESULT)NativeHelper.CalliInt32(90, _nativePointer, (void *)ptr)); } }
public static D3DFVF FVF(Geometry g) { D3DFVF fvf = D3DFVF.XYZ; if ((g.Attributes & VertexAttributes.Normal) == VertexAttributes.Normal) { fvf |= D3DFVF.NORMAL; } if ((g.Attributes & VertexAttributes.Diffuse) == VertexAttributes.Diffuse) { fvf |= D3DFVF.DIFFUSE; } if ((g.Attributes & VertexAttributes.Texture2) == VertexAttributes.Texture2) { fvf |= D3DFVF.TEX2; } else if ((g.Attributes & VertexAttributes.Texture1) == VertexAttributes.Texture1) { fvf |= D3DFVF.TEX1; } return(fvf); }
/// <unmanaged>HRESULT IDirect3DDevice9::CreateVertexBuffer([In] unsigned int Length,[In] D3DUSAGE Usage,[In] D3DFVF FVF,[In] D3DPOOL Pool,[Out, Fast] IDirect3DVertexBuffer9** ppVertexBuffer,[In] void** pSharedHandle)</unmanaged> public unsafe Direct3DVertexBuffer9 CreateVertexBuffer(int length, D3DUSAGE usage, D3DFVF vertexFormat, D3DPOOL pool) { var nativePointer = IntPtr.Zero; //result = calli(System.Int32(System.Void*,System.Int32,System.Int32,System.Int32,System.Int32,System.Void*,System.Void*), this._nativePointer, length, usage, vertexFormat, pool, &zero, (void*)sharedHandleRef, *(*(IntPtr*)this._nativePointer + (IntPtr)26 * (IntPtr)sizeof(void*))); var hr = (HRESULT)NativeHelper.CalliInt32(26, _nativePointer, (int)length, (int)usage, (int)vertexFormat, (int)pool, (void *)&nativePointer, (void *)IntPtr.Zero); hr.CheckError(); if (nativePointer == IntPtr.Zero) { return(null); } return(new Direct3DVertexBuffer9(nativePointer)); }
/// <unmanaged>HRESULT IDirect3DDevice9::SetFVF([In] D3DFVF FVF)</unmanaged> public unsafe HRESULT SetFVF(D3DFVF vertexFormat) { //calli(System.Int32(System.Void*,System.Int32), this._nativePointer, vertexFormat, *(*(IntPtr*)this._nativePointer + (IntPtr)89 * (IntPtr)sizeof(void*))).CheckError(); return((HRESULT)NativeHelper.CalliInt32(89, _nativePointer, (int)vertexFormat)); }
public void Read(byte[] data) { int pos = 0; // read the data header CmpParser.ParseUInt32(data, ref pos); //MeshType CmpParser.ParseUInt32(data, ref pos); //SurfaceType MeshCount = CmpParser.ParseUInt16(data, ref pos); NumRefVertices = CmpParser.ParseUInt16(data, ref pos); FlexibleVertexFormat = (D3DFVF)CmpParser.ParseUInt16(data, ref pos); VertexCount = CmpParser.ParseUInt16(data, ref pos); // the FVF defines what fields are included for each vertex /*switch (FlexibleVertexFormat) * { * case D3DFVF.XYZ: * case D3DFVF.XYZ | D3DFVF.NORMAL: * case D3DFVF.XYZ | D3DFVF.TEX1: * case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX1: * case D3DFVF.XYZ | D3DFVF.DIFFUSE | D3DFVF.TEX1: * case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.DIFFUSE | D3DFVF.TEX1: * case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX2: * case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.DIFFUSE | D3DFVF.TEX2: * break; * default: * throw new Exception(string.Format("FVF 0x{0:X} not supported.", FlexibleVertexFormat)); * }*/ // read the mesh headers int triangleStartOffset = 0; Meshes = new TMeshHeader[MeshCount]; for (int i = 0; i < MeshCount; ++i) { TMeshHeader mesh = new TMeshHeader(); CmpParser.ParseUInt32(data, ref pos); //MaterialId mesh.StartVertex = CmpParser.ParseUInt16(data, ref pos); mesh.EndVertex = CmpParser.ParseUInt16(data, ref pos); mesh.NumRefVertices = CmpParser.ParseUInt16(data, ref pos); CmpParser.ParseUInt16(data, ref pos); //Padding mesh.TriangleStart = triangleStartOffset; triangleStartOffset += mesh.NumRefVertices; Meshes[i] = mesh; } // read the triangle data int triangleCount = NumRefVertices / 3; Triangles = new TTriangle[triangleCount]; for (int i = 0; i < triangleCount; ++i) { TTriangle triangle = new TTriangle(); triangle.Vertex1 = CmpParser.ParseUInt16(data, ref pos); triangle.Vertex3 = CmpParser.ParseUInt16(data, ref pos); triangle.Vertex2 = CmpParser.ParseUInt16(data, ref pos); Triangles[i] = triangle; } // read the vertex data try { Vertices = new TVertex[VertexCount]; for (int i = 0; i < VertexCount; ++i) { TVertex vertex = new TVertex(); vertex.FVF = FlexibleVertexFormat; vertex.Position = CmpParser.ParsePoint3D(data, ref pos); if ((FlexibleVertexFormat & D3DFVF.Normal) == D3DFVF.Normal) { vertex.Normal = CmpParser.ParseVector3D(data, ref pos); } if ((FlexibleVertexFormat & D3DFVF.Diffuse) == D3DFVF.Diffuse) { CmpParser.ParseUInt32(data, ref pos); //Diffuse } if ((FlexibleVertexFormat & D3DFVF.Tex1) == D3DFVF.Tex1) { CmpParser.ParseFloat(data, ref pos); //S CmpParser.ParseFloat(data, ref pos); //T } if ((FlexibleVertexFormat & D3DFVF.Tex2) == D3DFVF.Tex2) { CmpParser.ParseFloat(data, ref pos); //S CmpParser.ParseFloat(data, ref pos); //T CmpParser.ParseFloat(data, ref pos); //U CmpParser.ParseFloat(data, ref pos); //V } if ((FlexibleVertexFormat & D3DFVF.Tex4) == D3DFVF.Tex4) { CmpParser.ParseFloat(data, ref pos); //S CmpParser.ParseFloat(data, ref pos); //T CmpParser.ParseFloat(data, ref pos); //TangentX CmpParser.ParseFloat(data, ref pos); //TangentY CmpParser.ParseFloat(data, ref pos); //TangentZ CmpParser.ParseFloat(data, ref pos); //BinormalX CmpParser.ParseFloat(data, ref pos); //BinormalY CmpParser.ParseFloat(data, ref pos); //BinormalZ } if ((FlexibleVertexFormat & D3DFVF.Tex5) == D3DFVF.Tex5) { CmpParser.ParseFloat(data, ref pos); //S CmpParser.ParseFloat(data, ref pos); //T CmpParser.ParseFloat(data, ref pos); //U CmpParser.ParseFloat(data, ref pos); //V CmpParser.ParseFloat(data, ref pos); //TangentX CmpParser.ParseFloat(data, ref pos); //TangentY CmpParser.ParseFloat(data, ref pos); //TangentZ CmpParser.ParseFloat(data, ref pos); //BinormalX CmpParser.ParseFloat(data, ref pos); //BinormalY CmpParser.ParseFloat(data, ref pos); //BinormalZ } Vertices[i] = vertex; } } catch { //MessageBox.Show("Header has more vertices then data", "Error"); } }
public static byte[] VMeshData(Geometry g) { using (var stream = new MemoryStream()) { var writer = new BinaryWriter(stream); writer.Write((uint)0x01); //MeshType writer.Write((uint)0x04); //SurfaceType writer.Write((ushort)(g.Groups.Length)); //MeshCount writer.Write((ushort)(g.Indices.Length)); //IndexCount D3DFVF fvf = FVF(g); writer.Write((ushort)fvf); //FVF writer.Write((ushort)g.Vertices.Length); //VertexCount int startTri = 0; foreach (var dc in g.Groups) { //drawcalls must be sequential (start index isn't in VMeshData) //this error shouldn't ever throw if (startTri != dc.StartIndex) { throw new Exception("Invalid start index"); } //write TMeshHeader var crc = dc.Material != null?CrcTool.FLModelCrc(dc.Material.Name) : 0; writer.Write(crc); writer.Write((ushort)dc.BaseVertex); int max = 0; for (int i = 0; i < dc.IndexCount; i++) { max = Math.Max(max, g.Indices.Indices16[i + dc.StartIndex]); } max += dc.BaseVertex; writer.Write((ushort)max); writer.Write((ushort)dc.IndexCount); //NumRefVertices writer.Write((ushort)0); //Padding //validation startTri += dc.IndexCount; } foreach (var idx in g.Indices.Indices16) { writer.Write(idx); } foreach (var v in g.Vertices) { writer.Write(v.Position.X); writer.Write(v.Position.Y); writer.Write(v.Position.Z); if ((fvf & D3DFVF.NORMAL) == D3DFVF.NORMAL) { writer.Write(v.Normal.X); writer.Write(v.Normal.Y); writer.Write(v.Normal.Z); } if ((fvf & D3DFVF.DIFFUSE) == D3DFVF.DIFFUSE) { writer.Write(((Color4)v.Diffuse).ToAbgr()); } //Librelancer stores texture coordinates flipped internally if ((fvf & D3DFVF.TEX2) == D3DFVF.TEX2) { writer.Write(v.Texture1.X); writer.Write(1 - v.Texture1.Y); writer.Write(v.Texture2.X); writer.Write(1 - v.Texture2.Y); } else if ((fvf & D3DFVF.TEX1) == D3DFVF.TEX1) { writer.Write(v.Texture1.X); writer.Write(1 - v.Texture1.Y); } } return(stream.ToArray()); } }