public virtual VertexArray CreateVertexArray(MeshBuffers meshBuffers) { VertexArray va = CreateVertexArray(); va.DisposeBuffers = true; va.IndexBuffer = meshBuffers.IndexBuffer; for (int i = 0; i < meshBuffers.Attributes.MaximumCount; ++i) { va.Attributes[i] = meshBuffers.Attributes[i]; } return(va); }
public virtual VertexArray CreateVertexArray(MeshBuffers meshBuffers) { VertexArray va = CreateVertexArray(); va.DisposeBuffers = true; va.IndexBuffer = meshBuffers.IndexBuffer; for (int i = 0; i < meshBuffers.Attributes.MaximumCount; ++i) { va.Attributes[i] = meshBuffers.Attributes[i]; } return va; }
public static MeshBuffers CreateMeshBuffers(Mesh mesh, ShaderVertexAttributeCollection shaderAttributes, BufferHint usageHint) { if (mesh == null) { throw new ArgumentNullException("mesh"); } if (shaderAttributes == null) { throw new ArgumentNullException("shaderAttributes"); } MeshBuffers meshBuffers = new MeshBuffers(); if (mesh.Indices != null) { if (mesh.Indices.Datatype == IndicesType.UnsignedShort) { IList <ushort> meshIndices = ((IndicesUnsignedShort)mesh.Indices).Values; ushort[] indices = new ushort[meshIndices.Count]; for (int j = 0; j < meshIndices.Count; ++j) { indices[j] = meshIndices[j]; } IndexBuffer indexBuffer = Device.CreateIndexBuffer(usageHint, indices.Length * sizeof(ushort)); indexBuffer.CopyFromSystemMemory(indices); meshBuffers.IndexBuffer = indexBuffer; } else if (mesh.Indices.Datatype == IndicesType.UnsignedInt) { IList <uint> meshIndices = ((IndicesUnsignedInt)mesh.Indices).Values; uint[] indices = new uint[meshIndices.Count]; for (int j = 0; j < meshIndices.Count; ++j) { indices[j] = meshIndices[j]; } IndexBuffer indexBuffer = Device.CreateIndexBuffer(usageHint, indices.Length * sizeof(uint)); indexBuffer.CopyFromSystemMemory(indices); meshBuffers.IndexBuffer = indexBuffer; } else { throw new NotSupportedException("mesh.Indices.Datatype " + mesh.Indices.Datatype.ToString() + " is not supported."); } } // // Emulated double precision vectors are a special case: one mesh vertex attribute // yields two shader vertex attributes. As such, these are handled separately before // normal attributes. // HashSet <string> ignoreAttributes = new HashSet <string>(); foreach (VertexAttribute attribute in mesh.Attributes) { if (attribute is VertexAttributeDoubleVector3) { VertexAttributeDoubleVector3 emulated = (VertexAttributeDoubleVector3)attribute; int highLocation = -1; int lowLocation = -1; foreach (ShaderVertexAttribute shaderAttribute in shaderAttributes) { if (shaderAttribute.Name == emulated.Name + "High") { highLocation = shaderAttribute.Location; } else if (shaderAttribute.Name == emulated.Name + "Low") { lowLocation = shaderAttribute.Location; } if ((highLocation != -1) && (lowLocation != -1)) { break; } } if ((highLocation == -1) && (lowLocation == -1)) { // // The shader did not have either attribute. No problem. // continue; } else if ((highLocation == -1) || (lowLocation == -1)) { throw new ArgumentException("An emulated double vec3 mesh attribute requires both " + emulated.Name + "High and " + emulated.Name + "Low vertex attributes, but the shader only contains one matching attribute."); } // // Copy both high and low parts into a single vertex buffer. // IList <Vector3D> values = ((VertexAttribute <Vector3D>)attribute).Values; Vector3F[] vertices = new Vector3F[2 * values.Count]; int j = 0; for (int i = 0; i < values.Count; ++i) { EmulatedVector3D v = new EmulatedVector3D(values[i]); vertices[j++] = v.High; vertices[j++] = v.Low; } VertexBuffer vertexBuffer = Device.CreateVertexBuffer(usageHint, ArraySizeInBytes.Size(vertices)); vertexBuffer.CopyFromSystemMemory(vertices); int stride = 2 * SizeInBytes <Vector3F> .Value; meshBuffers.Attributes[highLocation] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.Float, 3, false, 0, stride); meshBuffers.Attributes[lowLocation] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.Float, 3, false, SizeInBytes <Vector3F> .Value, stride); ignoreAttributes.Add(emulated.Name + "High"); ignoreAttributes.Add(emulated.Name + "Low"); } } // TODO: Not tested exhaustively foreach (ShaderVertexAttribute shaderAttribute in shaderAttributes) { if (ignoreAttributes.Contains(shaderAttribute.Name)) { continue; } if (!mesh.Attributes.Contains(shaderAttribute.Name)) { throw new ArgumentException("Shader requires vertex attribute \"" + shaderAttribute.Name + "\", which is not present in mesh."); } VertexAttribute attribute = mesh.Attributes[shaderAttribute.Name]; if (attribute.Datatype == VertexAttributeType.EmulatedDoubleVector3) { IList <Vector3D> values = ((VertexAttribute <Vector3D>)attribute).Values; Vector3F[] valuesArray = new Vector3F[values.Count]; for (int i = 0; i < values.Count; ++i) { valuesArray[i] = values[i].ToVector3F(); } VertexBuffer vertexBuffer = Device.CreateVertexBuffer(usageHint, ArraySizeInBytes.Size(valuesArray)); vertexBuffer.CopyFromSystemMemory(valuesArray); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.Float, 3); } else if (attribute.Datatype == VertexAttributeType.HalfFloat) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <Half>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.HalfFloat, 1); } else if (attribute.Datatype == VertexAttributeType.HalfFloatVector2) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <Vector2H>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.HalfFloat, 2); } else if (attribute.Datatype == VertexAttributeType.HalfFloatVector3) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <Vector3H>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.HalfFloat, 3); } else if (attribute.Datatype == VertexAttributeType.HalfFloatVector4) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <Vector4H>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.HalfFloat, 4); } else if (attribute.Datatype == VertexAttributeType.Float) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <float>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.Float, 1); } else if (attribute.Datatype == VertexAttributeType.FloatVector2) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <Vector2F>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.Float, 2); } else if (attribute.Datatype == VertexAttributeType.FloatVector3) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <Vector3F>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.Float, 3); } else if (attribute.Datatype == VertexAttributeType.FloatVector4) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <Vector4F>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.Float, 4); } else if (attribute.Datatype == VertexAttributeType.UnsignedByte) { if (attribute is VertexAttributeRGBA) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <byte>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.UnsignedByte, 4, true, 0, 0); } else if (attribute is VertexAttributeRGB) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <byte>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.UnsignedByte, 3, true, 0, 0); } else { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <byte>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.UnsignedByte, 1); } } else { Debug.Fail("attribute.Datatype"); } } return(meshBuffers); }