public async Task<object> ReadAsync(ContentReadParameters parameters) { EffectPassDescription desc; using (StreamReader sr = new StreamReader(parameters.AssetStream, Encoding.UTF8, true, 512, true)) using (JsonTextReader jtr = new JsonTextReader(sr)) { desc = serializer.Deserialize<EffectPassDescription>(jtr); } if (string.IsNullOrWhiteSpace(desc.VertexShader)) { throw new InvalidOperationException("The vertex shader resource string was null or whitespace!"); } if (string.IsNullOrWhiteSpace(desc.FragmentShader)) { throw new InvalidOperationException("The fragment shader resource string was null or whitespace!"); } IContentManager mgr = parameters.ContentManager; CancellationToken token = parameters.CancellationToken; IEnumerable<Shader> shaders = (await Task.WhenAll( TryLoadAsync(desc.VertexShader, ShaderType.VertexShader, mgr, token), TryLoadAsync(desc.TessControlShader, ShaderType.TessControlShader, mgr, token), TryLoadAsync(desc.TessEvalShader, ShaderType.TessEvaluationShader, mgr, token), TryLoadAsync(desc.GeometryShader, ShaderType.GeometryShader, mgr, token), TryLoadAsync(desc.FragmentShader, ShaderType.FragmentShader, mgr, token) ).ConfigureAwait(false)).FilterNull(); ShaderProgram program = await this.Dispatcher.Invoke(ct => new ShaderProgram(shaders.ToArray()), DispatcherPriority.Normal, token) .ConfigureAwait(false); return new EffectPass(program, true); }
Task<object> IContentReader.ReadAsync(ContentReadParameters parameters) { Contract.Requires<ArgumentNullException>(parameters.ContentManager != null); Contract.Requires<ArgumentNullException>(!string.IsNullOrWhiteSpace(parameters.ResourceString)); Contract.Requires<ArgumentNullException>(parameters.AssetStream != null); Contract.Requires<ArgumentNullException>(parameters.AssetType != null); Contract.Requires<ArgumentException>(parameters.AssetStream.CanRead); Contract.Ensures(Contract.Result<Task<object>>() != null); return null; }
public async Task<object> ReadAsync(ContentReadParameters parameters) { if (!(parameters.Parameter is ShaderType)) { throw new ArgumentException("The parameter must not be null and must be a {0}.".FormatWith(typeof(ShaderType).FullName)); } string source; using (StreamReader sr = new StreamReader(parameters.AssetStream, Encoding.UTF8, true, 2048, true)) { source = await sr.ReadToEndAsync().ConfigureAwait(false); } return await this.Dispatcher.Invoke(() => new Shader(source, (ShaderType)parameters.Parameter)).ConfigureAwait(false); }
public async Task<object> ReadAsync(ContentReadParameters parameters) { using (Bitmap bmp = new Bitmap(parameters.AssetStream)) { BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, GDIPixelFormat.Format32bppArgb); try { return await this.Dispatcher.Invoke((Func<CancellationToken, object>)(ct => { ct.ThrowIfCancellationRequested(); TextureDescription desc = new TextureDescription( data.Width, data.Height, TextureDescription.GetMaxTextureLevels(data.Width, data.Height), 2, (TextureTarget2d)(parameters.Parameter ?? TextureTarget2d.Texture2D), PixelInternalFormat.Rgba ); if (parameters.AssetType == typeof(Texture2D)) { return Texture2D.Create(desc, data.Scan0, GLPixelFormat.Bgra, PixelType.UnsignedByte, data.Width, data.Height, 0, 0, 0); } else if (parameters.AssetType == typeof(Texture1DArray)) { return Texture1DArray.Create(desc, data.Scan0, GLPixelFormat.Bgra, PixelType.UnsignedByte, data.Width, data.Height, 0, 0, 0); } else { throw new InvalidOperationException( string.Format( "{0} can only load {1} and {2}, not {3}!", typeof(TextureReader).Name, typeof(Texture1DArray).Name, typeof(Texture2D).Name, parameters.AssetType.Name ) ); } }), DispatcherPriority.Normal, parameters.CancellationToken).ConfigureAwait(false); } finally { bmp.UnlockBits(data); } } }
public async Task<object> ReadAsync(ContentReadParameters parameters) { List<string> effects; using (StreamReader sr = new StreamReader(parameters.AssetStream, Encoding.UTF8, true, 1024, true)) using (JsonTextReader jtr = new JsonTextReader(sr)) { effects = serializer.Deserialize<List<string>>(jtr); } if (!effects.Any()) { throw new InvalidOperationException("The given effect file did not contain any passes."); } return new Effect( await Task.WhenAll(effects.Select(e => parameters.ContentManager.LoadAsync<EffectPass>(e, parameters.CancellationToken))).ConfigureAwait(false), false ); }
/// <summary> /// Asynchronously reads the icon. /// </summary> /// <param name="parameters"> /// <see cref="ContentReadParameters"/> containing information about the asset to be loaded. /// </param> /// <returns> /// The deserialized asset. /// </returns> public Task<object> ReadAsync(ContentReadParameters parameters) { return Task.FromResult<object>(new Icon(parameters.AssetStream)); }
public async Task<object> ReadAsync(ContentReadParameters parameters) { Func<AssimpScene> f = () => { parameters.CancellationToken.ThrowIfCancellationRequested(); return this.context.ImportFileFromStream( parameters.AssetStream, postProcessingSteps, Path.GetExtension(parameters.ResourceString) ); }; Task<Effect> shaderLoadTask = parameters.ContentManager.LoadAsync<Effect>("Shaders/Basic.fx", parameters.CancellationToken); AssimpScene s = this.Dispatcher.IsOnThread ? await Task.Run(f).ConfigureAwait(false) : f(); // Make sure we don't pollute the main thread with IO ConcurrentDictionary<AssimpMesh, MeshInfo> meshData = new ConcurrentDictionary<AssimpMesh, MeshInfo>(); // Two separate tasks since one of them can be loaded asynchronously, and the other one // must be loaded on the main thread. Task textureLoadTask = Task.WhenAll(s.Meshes.Select(async mesh => { Material mat = s.Materials[mesh.MaterialIndex]; Texture2D tex2D = await parameters.ContentManager.LoadAsync<Texture2D>( mat.HasTextureDiffuse ? Path.Combine(Path.GetDirectoryName(parameters.ResourceString), mat.TextureDiffuse.FilePath) : "Internals/Default.png", parameters.CancellationToken ).ConfigureAwait(false); meshData.AddOrUpdate(mesh, new MeshInfo() { Texture = tex2D }, (m, mi) => { mi.Texture = tex2D; return mi; }); })); Task vaoCreateTask = this.Dispatcher.ImmediateOr(() => { foreach (AssimpMesh mesh in s.Meshes) { if (!mesh.HasVertices) { this.Log.Warn(() => string.Format("Mesh {0} does not have vertex data! It will not be loaded.", mesh.Name)); continue; } VertexArrayObject vao = new VertexArrayObject( BufferObject.Create(mesh.GetIndicesUInt16(), BufferTarget.ElementArrayBuffer), new BufferDescription( BufferObject.Create(mesh.Normals.ToArray(), BufferTarget.ArrayBuffer), new VertexAttributePointer(VertexAttributeLocation.Normals, 3, VertexAttribPointerType.Float, false, 0, 0) ), new BufferDescription( mesh.HasTextureCoords(0) ? BufferObject.Create(mesh.TextureCoordinateChannels[0].Select(v => new Vector2(v.X, v.Y)).ToArray(), BufferTarget.ArrayBuffer) : null, new VertexAttributePointer(VertexAttributeLocation.TexCoords, 2, VertexAttribPointerType.Float, false, 0, 0) ), new BufferDescription( BufferObject.Create(mesh.Vertices.ToArray(), BufferTarget.ArrayBuffer), new VertexAttributePointer(VertexAttributeLocation.Position, 3, VertexAttribPointerType.Float, false, 0, 0) ) ); meshData.AddOrUpdate(mesh, new MeshInfo() { Vao = vao }, (m, mi) => { mi.Vao = vao; return mi; }); } }, DispatcherPriority.Normal); // Calculate vertex data size, and if it surpasses 85kb, turn on LoH compaction if (s.Meshes.Any(mesh => (mesh.VertexCount * 3 * 4) >= 85000)) { GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; } await Task.WhenAll(shaderLoadTask, textureLoadTask, vaoCreateTask).ConfigureAwait(false); IEnumerable<ModelPart> modelParts = meshData.Values.Select(mi => new LightClawModelPart(shaderLoadTask.Result, mi.Vao, mi.Texture, false, true, false)); return new Model(s.HasMeshes ? s.Meshes[0].Name : null, modelParts, true); }
/// <summary> /// Asynchronously converts from the specified <see name="ContentReadParameters.AssetStream"/> into a /// usable asset of type <see name="ContentReadParameters.AssetType"/>. /// </summary> /// <remarks> /// This method accepts an <see cref="Encoding"/> via <see cref="ContentReadParameters.Parameter"/>. If /// <see cref="ContentReadParameters.Parameter"/> is <c>null</c>, <see cref="PrimitiveReader"/> will fall back /// to <see cref="Encoding.UTF8"/>. /// </remarks> /// <param name="parameters"> /// <see cref="ContentReadParameters"/> containing information about the asset to be loaded. /// </param> /// <returns> /// The deserialized asset or <c>null</c> if an error occured or the specified type of asset cannot be read. /// </returns> public async Task<object> ReadAsync(ContentReadParameters parameters) { Encoding encoding = parameters.Parameter as Encoding; Type assetType = parameters.AssetType; if (assetType.IsPrimitive || assetType == typeof(decimal)) { using (BinaryReader br = new BinaryReader(parameters.AssetStream, encoding ?? Encoding.UTF8, true)) { parameters.CancellationToken.ThrowIfCancellationRequested(); // Integers if (assetType == typeof(byte)) { return br.ReadByte(); } else if (assetType == typeof(sbyte)) { return br.ReadSByte(); } else if (assetType == typeof(short)) { return br.ReadInt16(); } else if (assetType == typeof(ushort)) { return br.ReadUInt16(); } else if (assetType == typeof(int)) { return br.ReadInt32(); } else if (assetType == typeof(uint)) { return br.ReadUInt32(); } else if (assetType == typeof(long)) { return br.ReadInt64(); } else if (assetType == typeof(ulong)) { return br.ReadUInt64(); } // Floating point numbers else if (assetType == typeof(float)) { return br.ReadSingle(); } else if (assetType == typeof(double)) { return br.ReadDouble(); } else if (assetType == typeof(decimal)) { return br.ReadDecimal(); } // Rest else if (assetType == typeof(bool)) { return br.ReadBoolean(); } else if (assetType == typeof(char)) { return br.ReadChar(); } else if (assetType == typeof(IntPtr)) { return new IntPtr(br.ReadInt32()); } else if (assetType == typeof(UIntPtr)) { return new UIntPtr(br.ReadUInt32()); } } } else if (assetType == typeof(string)) { using (StreamReader sr = new StreamReader(parameters.AssetStream, encoding ?? Encoding.UTF8)) { parameters.CancellationToken.ThrowIfCancellationRequested(); return await sr.ReadToEndAsync(); } } else if (assetType == typeof(byte[])) { using (MemoryStream ms = new MemoryStream(parameters.AssetStream.CanSeek ? MathF.ClampToInt32(parameters.AssetStream.Length) : 8192)) { await parameters.AssetStream.CopyToAsync(ms); return ms.ToArray(); } } return null; }
/// <summary> /// Asynchronously reads the <see cref="Scene"/>. /// </summary> /// <param name="parameters"> /// <see cref="ContentReadParameters"/> containing information about the asset to be loaded. /// </param> /// <returns>The deserialized <see cref="Scene"/>.</returns> public async Task<object> ReadAsync(ContentReadParameters parameters) { return await Scene.Load(parameters.AssetStream); // await for covariance }