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)); } } }
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."); } } } } } }
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; } }