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);
        }
Exemple #2
0
        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;
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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);
                }
            }
        }
Exemple #5
0
        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
            );
        }
Exemple #6
0
 /// <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));
 }
Exemple #7
0
        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);
        }
Exemple #8
0
        /// <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;
        }
Exemple #9
0
 /// <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
 }