private void InitializeVertices() { Vector3 position; Vector2 textureCoordinates; vertices = new VertexPositionNormalTangentTexture[4]; //top left position = new Vector3(-100, 100, 0); textureCoordinates = new Vector2(0, 0); vertices[0] = new VertexPositionNormalTangentTexture( position, Vector3.Forward, Vector3.Left, textureCoordinates); //bottom right position = new Vector3(100, -100, 0); textureCoordinates = new Vector2(1, 1); vertices[1] = new VertexPositionNormalTangentTexture( position, Vector3.Forward, Vector3.Left, textureCoordinates); //bottom left position = new Vector3(-100, -100, 0); textureCoordinates = new Vector2(0, 1); vertices[2] = new VertexPositionNormalTangentTexture( position, Vector3.Forward, Vector3.Left, textureCoordinates); //top right position = new Vector3(100, 100, 0); textureCoordinates = new Vector2(1, 0); vertices[3] = new VertexPositionNormalTangentTexture( position, Vector3.Forward, Vector3.Left, textureCoordinates); }
public static void Quad(int size, out List <VertexPositionNormalTangentTexture> vertexData, out List <ushort> indexData, bool uvHorizontalFlip = false, bool uvVerticalFlip = false, float uTileFactor = 1, float vTileFactor = 1) { VertexPositionNormalTangentTexture[] vertices = new VertexPositionNormalTangentTexture[] { // Indexed Quad new VertexPositionNormalTangentTexture(new Vector3(-size, 0, -size), Vector3.UnitY, Vector3.Zero, Vector2.Zero), new VertexPositionNormalTangentTexture(new Vector3(size, 0, -size), Vector3.UnitY, Vector3.Zero, Vector2.Zero), new VertexPositionNormalTangentTexture(new Vector3(size, 0, size), Vector3.UnitY, Vector3.Zero, Vector2.Zero), new VertexPositionNormalTangentTexture(new Vector3(-size, 0, size), Vector3.UnitY, Vector3.Zero, Vector2.Zero), }; vertexData = vertices.ToList(); var indices = new ushort[] { 0, 1, 2, 0, 2, 3 }; indexData = indices.ToList(); }
private void InitializeVertices() { Vector3 position; Vector2 textureCoordinates; vertices = new VertexPositionNormalTangentTexture[4]; //top left position = new Vector3(-1, 1, 0); textureCoordinates = new Vector2(0, 0); vertices[0] = new VertexPositionNormalTangentTexture(position, Vector3.Forward, Vector3.Left, textureCoordinates); //bottom right position = new Vector3(1, -1, 0); textureCoordinates = new Vector2(1, 1); vertices[1] = new VertexPositionNormalTangentTexture(position, Vector3.Forward, Vector3.Left, textureCoordinates); //bottom left position = new Vector3(-1, -1, 0); textureCoordinates = new Vector2(0, 1); vertices[2] = new VertexPositionNormalTangentTexture(position, Vector3.Forward, Vector3.Left, textureCoordinates); //top right position = new Vector3(1, 1, 0); textureCoordinates = new Vector2(1, 0); vertices[3] = new VertexPositionNormalTangentTexture(position, Vector3.Forward, Vector3.Left, textureCoordinates); vertexBuffer = new VertexBuffer(graphics.GraphicsDevice, typeof(VertexPositionNormalTangentTexture), vertices.Length, BufferUsage.WriteOnly); vertexBuffer.SetData <VertexPositionNormalTangentTexture>(vertices); }
public unsafe void LoadGLTF(string filePath, ID3D12Device5 pDevice, out ID3D12Resource vertexBuffer, out uint vertexCount, out ID3D12Resource indexBuffer, out uint indexCount) { using (var stream = File.OpenRead(filePath)) { if (stream == null || !stream.CanRead) { throw new ArgumentException("Invalid parameter. Stream must be readable", "imageStream"); } var model = Interface.LoadModel(stream); // read all buffers int numBuffers = model.Buffers.Length; var buffers = new BufferInfo[numBuffers]; for (int i = 0; i < numBuffers; ++i) { var bufferBytes = model.LoadBinaryBuffer(i, filePath); buffers[i] = new BufferInfo(bufferBytes); } // Read only first mesh and first primitive var mesh = model.Meshes[0]; var primitive = mesh.Primitives[0]; // Create Vertex Buffer var attributes = primitive.Attributes.ToArray(); Vector3[] positions = new Vector3[0]; Vector3[] normals = new Vector3[0]; Vector2[] texcoords = new Vector2[0]; Vector3[] tangents = new Vector3[0]; for (int i = 0; i < attributes.Length; i++) { var attributeAccessor = model.Accessors[attributes[i].Value]; var attributebufferView = model.BufferViews[attributeAccessor.BufferView.Value]; IntPtr attributePointer = buffers[attributebufferView.Buffer].bufferPointer + attributebufferView.ByteOffset + attributeAccessor.ByteOffset; string attributeKey = attributes[i].Key; if (attributeKey.Contains("POSITION")) { this.AttributeCopyData(ref positions, attributeAccessor.Count * Unsafe.SizeOf <Vector3>(), attributePointer); } else if (attributeKey.Contains("NORMAL")) { this.AttributeCopyData(ref normals, attributeAccessor.Count * Unsafe.SizeOf <Vector3>(), attributePointer); } else if (attributeKey.Contains("TANGENT")) { this.AttributeCopyData(ref tangents, attributeAccessor.Count * Unsafe.SizeOf <Vector3>(), attributePointer); } else if (attributeKey.Contains("TEXCOORD")) { this.AttributeCopyData(ref texcoords, attributeAccessor.Count * Unsafe.SizeOf <Vector2>(), attributePointer); } } VertexPositionNormalTangentTexture[] vertexData = new VertexPositionNormalTangentTexture[positions.Length]; for (int i = 0; i < vertexData.Length; i++) { Vector3 position = positions[i]; Vector3 normal = (normals.Length > i) ? normals[i] : Vector3.Zero; Vector2 texcoord = (texcoords.Length > i) ? texcoords[i] : Vector2.Zero; Vector3 tangent = (tangents.Length > i) ? tangents[i] : Vector3.Zero; vertexData[i] = new VertexPositionNormalTangentTexture(position, normal, tangent, texcoord); } vertexCount = (uint)vertexData.Length; vertexBuffer = CreateBuffer(pDevice, (uint)(Unsafe.SizeOf <VertexPositionNormalTangentTexture>() * vertexData.Length), ResourceFlags.None, ResourceStates.GenericRead, kUploadHeapProps); IntPtr pData = vertexBuffer.Map(0, null); Helpers.MemCpy(pData, vertexData, (uint)(Unsafe.SizeOf <VertexPositionNormalTangentTexture>() * vertexData.Length)); vertexBuffer.Unmap(0, null); // Create Index buffer var indicesAccessor = model.Accessors[primitive.Indices.Value]; var indicesbufferView = model.BufferViews[indicesAccessor.BufferView.Value]; IntPtr indicesPointer = buffers[indicesbufferView.Buffer].bufferPointer + indicesbufferView.ByteOffset + indicesAccessor.ByteOffset; indexCount = (uint)indicesAccessor.Count; indexBuffer = CreateBuffer(pDevice, (uint)indicesAccessor.Count * sizeof(ushort), ResourceFlags.None, ResourceStates.GenericRead, kUploadHeapProps); IntPtr pIB = indexBuffer.Map(0, null); Unsafe.CopyBlock((void *)pIB, (void *)indicesPointer, (uint)indicesAccessor.Count * sizeof(ushort)); indexBuffer.Unmap(0, null); for (int i = 0; i < numBuffers; ++i) { buffers[i].Dispose(); } buffers = null; } }
/// <summary> /// Add a model mesh to the combined mesh. /// </summary> /// <param name="mesh">Mesh to add.</param> /// <param name="transform">World transformations.</param> /// <param name="material">Optional material to use instead of the mesh default materials.</param> public void AddModelMesh(ModelMesh mesh, Matrix transform, Materials.MaterialAPI material = null) { // sanity check - if build was called assert if (_wasBuilt) { throw new Exceptions.InvalidActionException("Cannot add meshes to Combined Mesh Entity after it was built!"); } // did we get material override to set? bool externalMaterial = material != null; // iterate mesh parts foreach (var meshPart in mesh.MeshParts) { // if we didn't get external material to use, get material from mesh part. if (!externalMaterial) { material = meshPart.GetMaterial(); } // get the combined chunk to add this meshpart to CombinedMeshesPart combinedPart = GetCombinedPart(material); // make sure its not readonly if (meshPart.VertexBuffer.BufferUsage == BufferUsage.WriteOnly || meshPart.IndexBuffer.BufferUsage == BufferUsage.WriteOnly) { throw new Exceptions.InvalidValueException("Cannot add mesh with write-only buffers to Combined Mesh!"); } // make sure vertex buffer uses position-normal-texture if (meshPart.VertexBuffer.VertexDeclaration.VertexStride < 8) { throw new Exceptions.InvalidValueException("Combined meshes can only use vertex buffers with position, normal and texture!"); } // get vertex buffer parameters int vertexStride = meshPart.VertexBuffer.VertexDeclaration.VertexStride; int vertexBufferSize = meshPart.NumVertices * vertexStride; // get vertex data as float float[] vertexData = new float[vertexBufferSize / sizeof(float)]; meshPart.VertexBuffer.GetData <float>(vertexData); // iterate through vertices and add them int verticesInPart = 0; for (int i = 0; i < vertexBufferSize / sizeof(float); i += vertexStride / sizeof(float)) { // get curr position with transformations Vector3 currPosition = Vector3.Transform(new Vector3(vertexData[i], vertexData[i + 1], vertexData[i + 2]), transform); // get other vertex properties based on type and add to vertices buffer switch (_vtype) { case VertexTypes.VertexPosition: { // add to buffer var vertexToAdd = new VertexPosition(currPosition); combinedPart.Vertices.Add(ToVertexType(vertexToAdd)); break; } case VertexTypes.VertexPositionColor: { // get color Color currColor = new Color(vertexData[i + 3], vertexData[i + 4], vertexData[i + 5], vertexData[i + 6]); // add to buffer var vertexToAdd = new VertexPositionColor(currPosition, currColor); combinedPart.Vertices.Add(ToVertexType(vertexToAdd)); break; } case VertexTypes.VertexPositionNormalTexture: { // get normal Vector3 normal = new Vector3(vertexData[i + 3], vertexData[i + 4], vertexData[i + 5]); normal = Vector3.Normalize(Vector3.TransformNormal(normal, transform)); // get texture coords Vector2 textcoords = new Vector2(vertexData[i + 6], vertexData[i + 7]); // add to buffer var vertexToAdd = new VertexPositionNormalTexture(currPosition, normal, textcoords); combinedPart.Vertices.Add(ToVertexType(vertexToAdd)); break; } case VertexTypes.VertexPositionNormalTangentTexture: { // get normal Vector3 normal = new Vector3(vertexData[i + 3], vertexData[i + 4], vertexData[i + 5]); normal = Vector3.Normalize(Vector3.TransformNormal(normal, transform)); // get tangent Vector3 tangent = new Vector3(vertexData[i + 6], vertexData[i + 7], vertexData[i + 8]); // get binormal Vector3 binormal = new Vector3(vertexData[i + 9], vertexData[i + 10], vertexData[i + 11]); // get texture coords Vector2 textcoords = new Vector2(vertexData[i + 12], vertexData[i + 13]); // add to buffer var vertexToAdd = new VertexPositionNormalTangentTexture(currPosition, normal, textcoords, tangent, binormal); combinedPart.Vertices.Add(ToVertexType(vertexToAdd)); break; } case VertexTypes.VertexPositionTexture: { // get texture coords Vector2 textcoords = new Vector2(vertexData[i + 3], vertexData[i + 4]); // add to buffer var vertexToAdd = new VertexPositionTexture(currPosition, textcoords); combinedPart.Vertices.Add(ToVertexType(vertexToAdd)); break; } default: throw new Exceptions.InternalError("Forgot to implement type support?"); } // add to temp list of all points and increase vertices count _allPoints.Add(currPosition); verticesInPart++; } // set indexes ushort[] drawOrder = new ushort[meshPart.IndexBuffer.IndexCount]; meshPart.IndexBuffer.GetData <ushort>(drawOrder); combinedPart.PushIndexes(drawOrder); // increase indexes offset combinedPart.IndexOffset += verticesInPart; // increase primitives count combinedPart.PrimitiveCount += meshPart.PrimitiveCount; } }