예제 #1
0
            public ProtogameParameterSet(ProtogameEffect protogameEffect)
            {
                _writableParameters = new OrderedDictionary();
                _semantics          = new List <IEffectSemantic>();

#if DEBUG
                GraphicsMetricsProfilerVisualiser.ParameterSetsCreated++;
#endif

                for (var i = 0; i < protogameEffect.NativeEffect.Parameters.Count; i++)
                {
                    var nativeParameter = protogameEffect.NativeEffect.Parameters[i];
                    _writableParameters.Add(nativeParameter.Name, new ProtogameEffectWriteableParameter(
                                                this,
                                                nativeParameter,
                                                nativeParameter.Name,
                                                nativeParameter.ParameterClass,
                                                nativeParameter.ParameterType));
                }

                foreach (var semantic in protogameEffect._availableSemantics)
                {
                    if (semantic.ShouldAttachToParameterSet(this))
                    {
                        _semantics.Add(semantic.Clone(this));
                    }
                }
            }
예제 #2
0
        public void ReloadEffects()
        {
            if (_assetContentManager == null)
            {
                throw new NoAssetContentManagerException();
            }

            if (_assetContentManager != null && PlatformData != null)
            {
                // FIXME: We shouldn't be casting IAssetContentManager like this!
                var assetContentManager = _assetContentManager as AssetContentManager;
                if (assetContentManager == null)
                {
                    throw new NoAssetContentManagerException();
                }

                var serviceProvider        = assetContentManager.ServiceProvider;
                var graphicsDeviceProvider =
                    (IGraphicsDeviceService)serviceProvider.GetService(typeof(IGraphicsDeviceService));
                if (graphicsDeviceProvider != null && graphicsDeviceProvider.GraphicsDevice != null)
                {
                    var graphicsDevice = graphicsDeviceProvider.GraphicsDevice;

                    // The platform data for uber effects is a bunch of XNA effects
                    // concatenated together.  We have to parse the binary platform data, and load
                    // each effect into our Effects dictionary.
                    Effects = new Dictionary <string, IEffect>();
                    using (var memory = new MemoryStream(PlatformData.Data))
                    {
                        using (var reader = new BinaryReader(memory))
                        {
                            switch (reader.ReadUInt32())
                            {
                            case 1:
                            {
                                var count = reader.ReadUInt32();
                                for (var i = 0; i < count; i++)
                                {
                                    var name       = reader.ReadString();
                                    var defines    = reader.ReadString();
                                    var dataLength = reader.ReadInt32();
                                    var data       = reader.ReadBytes(dataLength);

                                    // Use the new EffectWithSemantics class that allows for extensible semantics.
                                    var availableSemantics = _kernel.GetAll <IEffectSemantic>();
                                    Effects[name] = new ProtogameEffect(graphicsDevice, data, Name + ":" + name,
                                                                        availableSemantics);
                                }
                                break;
                            }

                            case 2:
                            {
                                var count = reader.ReadUInt32();
                                for (var i = 0; i < count; i++)
                                {
                                    var name              = reader.ReadString();
                                    var defines           = reader.ReadString();
                                    var debugDataLength   = reader.ReadInt32();
                                    var debugData         = reader.ReadBytes(debugDataLength);
                                    var releaseDataLength = reader.ReadInt32();
                                    var releaseData       = reader.ReadBytes(releaseDataLength);

                                    // Use the new EffectWithSemantics class that allows for extensible semantics.
                                    var availableSemantics = _kernel.GetAll <IEffectSemantic>();
                                    Effects[name] = new ProtogameEffect(
                                        graphicsDevice,
                                        _rawLaunchArguments.Arguments.Contains("--debug-shaders")
                                                ? debugData
                                                : releaseData,
                                        Name + ":" + name,
                                        availableSemantics);
                                }
                                break;
                            }

                            default:
                                throw new InvalidOperationException("Unexpected version number for uber effect.");
                            }
                        }
                    }
                }
            }
        }
예제 #3
0
        public void ReadyOnGameThread()
        {
            if (_assetContentManager == null)
            {
                throw new NoAssetContentManagerException();
            }

            if (_assetContentManager != null && _effect != null)
            {
                // We don't load XNB-based effects because MonoGame doesn't have a reader
                // that supports them, and the XNB format mangles the shader bytecode if we
                // try and parse it out manually.  We also can't just define our own effect reader
                // as that doesn't seem to get picked up by the MonoGame content manager.

                // FIXME: We shouldn't be casting IAssetContentManager like this!
                var assetContentManager = _assetContentManager as AssetContentManager;
                if (assetContentManager == null)
                {
                    throw new NoAssetContentManagerException();
                }

                var serviceProvider        = assetContentManager.ServiceProvider;
                var graphicsDeviceProvider =
                    (IGraphicsDeviceService)serviceProvider.GetService(typeof(IGraphicsDeviceService));
                if (graphicsDeviceProvider != null && graphicsDeviceProvider.GraphicsDevice != null)
                {
                    var graphicsDevice = graphicsDeviceProvider.GraphicsDevice;

                    var availableSemantics = _kernel.GetAll <IEffectSemantic>();

                    using (var stream = new MemoryStream(_effect))
                    {
                        using (var reader = new BinaryReader(stream))
                        {
                            if (reader.ReadUInt32() == (uint)0x12345678)
                            {
                                // This is the new effect format that supports storing both debug
                                // and release builds of the shader code.
                                switch (reader.ReadUInt32())
                                {
                                case 1:
                                    var debugLength   = reader.ReadInt32();
                                    var debugCode     = reader.ReadBytes(debugLength);
                                    var releaseLength = reader.ReadInt32();
                                    var releaseCode   = reader.ReadBytes(releaseLength);
                                    if (_rawLaunchArguments.Arguments.Contains("--debug-shaders"))
                                    {
                                        Effect = new ProtogameEffect(graphicsDevice, debugCode,
                                                                     Name, availableSemantics);
                                    }
                                    else
                                    {
                                        Effect = new ProtogameEffect(graphicsDevice, releaseCode,
                                                                     Name, availableSemantics);
                                    }
                                    break;

                                default:
                                    throw new NotSupportedException("Unknown version of effect binary data.");
                                }
                            }
                            else
                            {
                                // This is a legacy shader with no versioning.
                                Effect = new ProtogameEffect(graphicsDevice, _effect, Name, availableSemantics);
                            }
                        }
                    }
                }

                // Free the resource from main memory since it is now loaded into the GPU.  If the
                // resource is ever removed from the GPU (i.e. UnloadContent occurs followed by
                // LoadContent), then the asset will need to be reloaded through the asset management
                // system.
                _effect = null;
            }
        }