Ejemplo n.º 1
0
        /// <summary>
        /// Sets a callback to be used whenever texture data is requested by a shader.
        /// The callback will be passed the u, v and w coordinates.
        /// </summary>
        /// <typeparam name="TColor">Color type, i.e. Vector4.</typeparam>
        /// <param name="name">Name of the resource.</param>
        /// <param name="callback">The callback will be executed once for each texture fetch,
        /// and will be passed the u, v and w coordinates.</param>
        public void SetResource <TColor>(string name, ResourceCallback <TColor> callback)
            where TColor : struct
        {
            // Validate.
            var resourceIndex = _resourceBindings.FindIndex(x => x.Name == name);

            if (resourceIndex == -1)
            {
                throw new ArgumentException("Could not find resource named '" + name + "'", "name");
            }
            if (StructUtility.SizeOf <TColor>() != Number4.SizeInBytes)
            {
                throw new ArgumentException(string.Format("Expected color struct to be {0} bytes, but was {1}'",
                                                          Number4.SizeInBytes, StructUtility.SizeOf <TColor>()));
            }

            // Set resource into virtual machine. We also set a default sampler state.
            var registerIndex = new RegisterIndex((ushort)resourceIndex);

            _virtualMachine.SetSampler(registerIndex, new SamplerState());
            _virtualMachine.SetTexture(registerIndex,
                                       new FakeTexture((u, v, w, i) =>
            {
                var bytes = StructUtility.ToBytes(callback(u, v, w, i));
                return(Number4.FromByteArray(bytes, 0));
            }));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Executes the shader. First, the input value is set into the input registers.
        /// Then the shader is executed. Finally, the output value is extracted from
        /// the output registers.
        /// </summary>
        /// <typeparam name="TInput">Input type. This must be a struct whose byte count
        /// exactly matches the shader input.</typeparam>
        /// <typeparam name="TOutput">Output type. This must be a struct whose byte count
        /// exactly matches the shader output.</typeparam>
        /// <param name="input">Input to the shader.</param>
        /// <returns>Shader output.</returns>
        public TOutput Execute <TInput, TOutput>(TInput input)
            where TInput : struct
            where TOutput : struct
        {
            // Validate.
            if (StructUtility.SizeOf <TInput>() != _inputSignatureSize)
            {
                throw new ArgumentException(string.Format("Expected input struct to be {0} bytes, but was {1}'",
                                                          _inputSignatureSize, StructUtility.SizeOf <TInput>()));
            }

            // Set input parameters into virtual machine registers. Use knowledge of byte size of each
            // parameter to extract the right values from the input.
            var inputBytes     = StructUtility.ToBytes(input);
            var inputByteIndex = 0;

            for (int i = 0; i < _inputSignature.Parameters.Count; i++)
            {
                var inputParameter = _inputSignature.Parameters[i];
                var registerBytes  = new byte[Number4.SizeInBytes];
                Array.Copy(inputBytes, inputByteIndex, registerBytes, 0, inputParameter.ByteCount);
                _virtualMachine.SetInputRegisterValue(ContextIndex, 0, i, Number4.FromByteArray(registerBytes, 0));
                inputByteIndex += inputParameter.ByteCount;
            }

            // Execute shader.
            _virtualMachine.Execute();

            // Get output parameters from virtual machine registers.
            var outputBytes     = new byte[_outputSignatureSize];
            var outputByteIndex = 0;

            for (var i = 0; i < _outputSignature.Parameters.Count; i++)
            {
                var outputParameter = _outputSignature.Parameters[i];
                var registerBytes   = _virtualMachine.GetOutputRegisterValue(ContextIndex, i).RawBytes;
                Array.Copy(registerBytes, 0, outputBytes, outputByteIndex, outputParameter.ByteCount);
                outputByteIndex += outputParameter.ByteCount;
            }
            return(StructUtility.FromBytes <TOutput>(outputBytes));
        }