private void CheckALError() { int err = AL10.alGetError(); if (err == AL10.AL_NO_ERROR) { return; } FNALoggerEXT.LogError("OpenAL Error: " + err.ToString("X4")); #if VERBOSE_AL_DEBUGGING throw new InvalidOperationException("OpenAL Error!"); #endif }
public void EndApplyRasterizer() { // Bool -> Int32 conversion int multiSampleAntiAlias = (MultiSampleAntiAlias ? 1 : 0); int scissorTestEnable = (ScissorTestEnable ? 1 : 0); int packedProperties = ((int)multiSampleAntiAlias << 4) | ((int)scissorTestEnable << 3) | ((int)CullMode << 1) | ((int)FillMode); StateHash hash = new StateHash( 0, packedProperties, FloatToInt32(DepthBias), FloatToInt32(SlopeScaleDepthBias) ); RasterizerState newRasterizer; if (!rasterizerCache.TryGetValue(hash, out newRasterizer)) { newRasterizer = new RasterizerState(); newRasterizer.CullMode = CullMode; newRasterizer.FillMode = FillMode; newRasterizer.DepthBias = DepthBias; newRasterizer.MultiSampleAntiAlias = MultiSampleAntiAlias; newRasterizer.ScissorTestEnable = ScissorTestEnable; newRasterizer.SlopeScaleDepthBias = SlopeScaleDepthBias; rasterizerCache.Add(hash, newRasterizer); #if VERBOSE_PIPELINECACHE FNALoggerEXT.LogInfo("New RasterizerState added to pipeline cache with hash:\n" + hash.ToString()); FNALoggerEXT.LogInfo("Updated size of RasterizerState cache: " + rasterizerCache.Count); } else { FNALoggerEXT.LogInfo("Retrieved RasterizerState from pipeline cache with hash:\n" + hash.ToString()); #endif } device.RasterizerState = newRasterizer; }
public void EndApplySampler(SamplerStateCollection samplers, int register) { StateHash hash = GetSamplerHash( AddressU, AddressV, AddressW, MaxAnisotropy, MaxMipLevel, MipMapLODBias, Filter ); SamplerState newSampler; if (!samplerCache.TryGetValue(hash, out newSampler)) { newSampler = new SamplerState(); newSampler.Filter = Filter; newSampler.AddressU = AddressU; newSampler.AddressV = AddressV; newSampler.AddressW = AddressW; newSampler.MaxAnisotropy = MaxAnisotropy; newSampler.MaxMipLevel = MaxMipLevel; newSampler.MipMapLevelOfDetailBias = MipMapLODBias; samplerCache.Add(hash, newSampler); #if VERBOSE_PIPELINECACHE FNALoggerEXT.LogInfo( "New SamplerState added to pipeline cache with hash:\n" + hash.ToString() ); FNALoggerEXT.LogInfo( "Updated size of SamplerState cache: " + samplerCache.Count ); } else { FNALoggerEXT.LogInfo( "Retrieved SamplerState from pipeline cache with hash:\n" + hash.ToString() ); #endif } samplers[register] = newSampler; }
public static void Clear() { if (File.Exists(filepath)) { try { File.Delete(filepath); using (File.Create(filepath)) { } } catch (Exception exception) { FNALoggerEXT.LogError(exception.ToString()); } } }
public void EndApplyRasterizer() { StateHash hash = GetRasterizerHash( CullMode, FillMode, DepthBias, MultiSampleAntiAlias, ScissorTestEnable, SlopeScaleDepthBias ); RasterizerState newRasterizer; if (!rasterizerCache.TryGetValue(hash, out newRasterizer)) { newRasterizer = new RasterizerState(); newRasterizer.CullMode = CullMode; newRasterizer.FillMode = FillMode; newRasterizer.DepthBias = DepthBias; newRasterizer.MultiSampleAntiAlias = MultiSampleAntiAlias; newRasterizer.ScissorTestEnable = ScissorTestEnable; newRasterizer.SlopeScaleDepthBias = SlopeScaleDepthBias; rasterizerCache.Add(hash, newRasterizer); #if VERBOSE_PIPELINECACHE FNALoggerEXT.LogInfo( "New RasterizerState added to pipeline cache with hash:\n" + hash.ToString() ); FNALoggerEXT.LogInfo( "Updated size of RasterizerState cache: " + rasterizerCache.Count ); } else { FNALoggerEXT.LogInfo( "Retrieved RasterizerState from pipeline cache with hash:\n" + hash.ToString() ); #endif } device.RasterizerState = newRasterizer; }
public bool Invoke(string namespaceClassnameMethodname, out object result, object[] param = null, Type[] types = null) { result = null; try { MethodInfo methodInfo = FindMethod(namespaceClassnameMethodname, types); if (methodInfo != null) { result = methodInfo.Invoke(null, param); return(true); } } catch (Exception ex) { Logger.Error($"Error trying to call '{namespaceClassnameMethodname}'."); FNALoggerEXT.LogError(ex.ToString()); } return(false); }
public static void Create() { IntPtr ctx; try { FAudio.FAudioCreate( out ctx, 0, FAudio.FAUDIO_DEFAULT_PROCESSOR ); } catch (Exception e) { /* FAudio is missing, bail! */ FNALoggerEXT.LogWarn("FAudio failed to load: " + e.ToString()); return; } uint devices; FAudio.FAudio_GetDeviceCount( ctx, out devices ); if (devices == 0) { /* No sound cards, bail! */ FAudio.FAudio_Release(ctx); return; } FAudioContext context = new FAudioContext(ctx, devices); if (context.Handle == IntPtr.Zero) { /* Soundcard failed to configure, bail! */ context.Dispose(); return; } Context = context; }
public static void Initialize() { // We should only have one of these! if (ALDevice != null) { FNALoggerEXT.LogWarn("ALDevice already exists, overwriting!"); } bool disableSound = Environment.GetEnvironmentVariable( "FNA_AUDIO_DISABLE_SOUND" ) == "1"; if (disableSound) { ALDevice = new NullALDevice(); } else { ALDevice = FNAPlatform.CreateALDevice(); } // Populate device info if (ALDevice != null) { ALDevice.SetMasterVolume(MasterVolume); ALDevice.SetDopplerScale(DopplerScale); ALDevice.SetSpeedOfSound(SpeedOfSound); Renderers = ALDevice.GetDevices(); Microphone.All = ALDevice.GetCaptureDevices(); InstancePool = new List <SoundEffectInstance>(); DynamicInstancePool = new List <DynamicSoundEffectInstance>(); ActiveMics = new List <Microphone>(); AppDomain.CurrentDomain.ProcessExit += Dispose; } else { Renderers = new ReadOnlyCollection <RendererDetail>(new List <RendererDetail>()); Microphone.All = new ReadOnlyCollection <Microphone>(new List <Microphone>()); } }
public ThreadedGLDevice(PresentationParameters presentationParameters) { csThread = new Thread(new ThreadStart(csThreadProc)); csThread.Start(); FNALoggerEXT.LogInfo("Running with ThreadedGLDevice!"); ForceToMainThread(() => { if (Environment.GetEnvironmentVariable( "FNA_THREADEDGLDEVICE_GLDEVICE" ) == "OpenGLDevice") { GLDevice = new OpenGLDevice( presentationParameters ); } else { GLDevice = new ModernGLDevice( presentationParameters ); } }); // End ForceToMainThread }
protected T ReadAsset <T>(string assetName, Action <IDisposable> recordDisposableObject) { if (string.IsNullOrEmpty(assetName)) { throw new ArgumentNullException("assetName"); } if (disposed) { throw new ObjectDisposedException("ContentManager"); } object result = null; Stream stream = null; string modifiedAssetName = String.Empty; // Will be used if we have to guess a filename try { stream = OpenStream(assetName); } catch (Exception e) { // Okay, so we couldn't open it. Maybe it needs a different extension? // FIXME: This only works for files on the disk, what about custom streams? -flibit modifiedAssetName = MonoGame.Utilities.FileHelpers.NormalizeFilePathSeparators( Path.Combine(RootDirectoryFullPath, assetName) ); if (typeof(T) == typeof(Texture2D) || typeof(T) == typeof(Texture)) { modifiedAssetName = Texture2DReader.Normalize(modifiedAssetName); } else if ((typeof(T) == typeof(SoundEffect))) { modifiedAssetName = SoundEffectReader.Normalize(modifiedAssetName); } else if ((typeof(T) == typeof(Effect))) { modifiedAssetName = EffectReader.Normalize(modifiedAssetName); } else if ((typeof(T) == typeof(Song))) { modifiedAssetName = SongReader.Normalize(modifiedAssetName); } else if ((typeof(T) == typeof(Video))) { modifiedAssetName = VideoReader.Normalize(modifiedAssetName); } else { // No raw format available, disregard! modifiedAssetName = null; } // Did we get anything...? if (String.IsNullOrEmpty(modifiedAssetName)) { // Nope, nothing we're aware of! throw new ContentLoadException( "Could not load asset " + assetName + "! Error: " + e.Message, e ); } stream = TitleContainer.OpenStream(modifiedAssetName); } // Check for XNB header stream.Read(xnbHeader, 0, xnbHeader.Length); if (xnbHeader[0] == 'X' && xnbHeader[1] == 'N' && xnbHeader[2] == 'B' && targetPlatformIdentifiers.Contains((char)xnbHeader[3])) { using (BinaryReader xnbReader = new BinaryReader(stream)) using (ContentReader reader = GetContentReaderFromXnb(assetName, ref stream, xnbReader, (char)xnbHeader[3], recordDisposableObject)) { result = reader.ReadAsset <T>(); GraphicsResource resource = result as GraphicsResource; if (resource != null) { resource.Name = assetName; } } } else { // It's not an XNB file. Try to load as a raw asset instead. // FIXME: Assuming seekable streams! -flibit stream.Seek(0, SeekOrigin.Begin); if (typeof(T) == typeof(Texture2D) || typeof(T) == typeof(Texture)) { Texture2D texture; if (xnbHeader[0] == 'D' && xnbHeader[1] == 'D' && xnbHeader[2] == 'S' && xnbHeader[3] == ' ') { texture = Texture2D.DDSFromStreamEXT( GetGraphicsDevice(), stream ); } else { texture = Texture2D.FromStream( GetGraphicsDevice(), stream ); } texture.Name = assetName; result = texture; } else if ((typeof(T) == typeof(SoundEffect))) { result = SoundEffect.FromStream(stream); } else if ((typeof(T) == typeof(Effect))) { byte[] data = new byte[stream.Length]; stream.Read(data, 0, (int)stream.Length); result = new Effect(GetGraphicsDevice(), data); } else if ((typeof(T) == typeof(Song))) { // FIXME: Not using the stream! -flibit result = new Song(modifiedAssetName); } else if ((typeof(T) == typeof(Video))) { // FIXME: Not using the stream! -flibit result = new Video(modifiedAssetName, GetGraphicsDevice()); FNALoggerEXT.LogWarn( "Video " + modifiedAssetName + " does not have an XNB file! Hacking Duration property!" ); } else { stream.Close(); throw new ContentLoadException("Could not load " + assetName + " asset!"); } /* Because Raw Assets skip the ContentReader step, they need to have their * disposables recorded here. Doing it outside of this catch will * result in disposables being logged twice. */ IDisposable disposableResult = result as IDisposable; if (disposableResult != null) { if (recordDisposableObject != null) { recordDisposableObject(disposableResult); } else { disposableAssets.Add(disposableResult); } } /* Because we're not using a BinaryReader for raw assets, we * need to close the stream ourselves. * -flibit */ stream.Close(); } return((T)result); }
/// <summary> /// Initializes a new instance of the <see cref="GraphicsDevice" /> class. /// </summary> /// <param name="adapter">The graphics adapter.</param> /// <param name="graphicsProfile">The graphics profile.</param> /// <param name="presentationParameters">The presentation options.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="presentationParameters"/> is <see langword="null"/>. /// </exception> public GraphicsDevice( GraphicsAdapter adapter, GraphicsProfile graphicsProfile, PresentationParameters presentationParameters ) { if (presentationParameters == null) { throw new ArgumentNullException("presentationParameters"); } // Set the properties from the constructor parameters. Adapter = adapter; PresentationParameters = presentationParameters; GraphicsProfile = graphicsProfile; PresentationParameters.MultiSampleCount = MathHelper.ClosestMSAAPower( PresentationParameters.MultiSampleCount ); // Set up the IGLDevice GLDevice = FNAPlatform.CreateGLDevice(PresentationParameters, adapter); // The mouse needs to know this for faux-backbuffer mouse scaling. Input.Mouse.INTERNAL_BackBufferWidth = PresentationParameters.BackBufferWidth; Input.Mouse.INTERNAL_BackBufferHeight = PresentationParameters.BackBufferHeight; // The Touch Panel needs this too, for the same reason. Input.Touch.TouchPanel.DisplayWidth = PresentationParameters.BackBufferWidth; Input.Touch.TouchPanel.DisplayHeight = PresentationParameters.BackBufferHeight; // Force set the default render states. BlendState = BlendState.Opaque; DepthStencilState = DepthStencilState.Default; RasterizerState = RasterizerState.CullCounterClockwise; // Initialize the Texture/Sampler state containers int maxTextures = Math.Min(GLDevice.MaxTextureSlots, MAX_TEXTURE_SAMPLERS); int maxVertexTextures = MathHelper.Clamp( GLDevice.MaxTextureSlots - MAX_TEXTURE_SAMPLERS, 0, MAX_VERTEXTEXTURE_SAMPLERS ); vertexSamplerStart = GLDevice.MaxTextureSlots - maxVertexTextures; Textures = new TextureCollection( maxTextures, modifiedSamplers ); SamplerStates = new SamplerStateCollection( maxTextures, modifiedSamplers ); VertexTextures = new TextureCollection( maxVertexTextures, modifiedVertexSamplers ); VertexSamplerStates = new SamplerStateCollection( maxVertexTextures, modifiedVertexSamplers ); // Set the default viewport and scissor rect. Viewport = new Viewport(PresentationParameters.Bounds); ScissorRectangle = Viewport.Bounds; // Allocate the pipeline cache to be used by Effects PipelineCache = new PipelineCache(this); #if WIIU_GAMEPAD wiiuStream = DRC.drc_new_streamer(); if (wiiuStream == IntPtr.Zero) { FNALoggerEXT.LogError("Failed to alloc GamePad stream!"); return; } if (DRC.drc_start_streamer(wiiuStream) < 1) // ??? { FNALoggerEXT.LogError("Failed to start GamePad stream!"); DRC.drc_delete_streamer(wiiuStream); wiiuStream = IntPtr.Zero; return; } DRC.drc_enable_system_input_feeder(wiiuStream); wiiuPixelData = new byte[ PresentationParameters.BackBufferWidth * PresentationParameters.BackBufferHeight * 4 ]; #endif }
internal void Play(bool isManaged) { // No-op if we're already playing. if (State != SoundState.Stopped) { if (State == SoundState.Paused) { // ... but be sure pause/resume still works Resume(); } return; } if (INTERNAL_alSource != null) { // The sound has stopped, but hasn't cleaned up yet... AudioDevice.ALDevice.StopAndDisposeSource(INTERNAL_alSource); INTERNAL_alSource = null; } while (queuedBuffers.Count > 0) { availableBuffers.Enqueue(queuedBuffers.Dequeue()); PendingBufferCount -= 1; } if (AudioDevice.ALDevice == null) { throw new NoAudioHardwareException(); } INTERNAL_alSource = AudioDevice.ALDevice.GenSource(); if (INTERNAL_alSource == null) { FNALoggerEXT.LogWarn("AL SOURCE WAS NOT AVAILABLE, SKIPPING."); return; } // Queue the buffers to this source while (buffersToQueue.Count > 0) { IALBuffer nextBuf = buffersToQueue.Dequeue(); queuedBuffers.Enqueue(nextBuf); AudioDevice.ALDevice.QueueSourceBuffer(INTERNAL_alSource, nextBuf); } // Apply Pan/Position if (INTERNAL_positionalAudio) { INTERNAL_positionalAudio = false; AudioDevice.ALDevice.SetSourcePosition( INTERNAL_alSource, position ); } else { Pan = Pan; } // Reassign Properties, in case the AL properties need to be applied. Volume = Volume; Pitch = Pitch; // ... but wait! What if we need moar buffers? for ( int i = MINIMUM_BUFFER_CHECK - PendingBufferCount; (i > 0) && BufferNeeded != null; i -= 1 ) { BufferNeeded(this, null); } // Finally. AudioDevice.ALDevice.PlaySource(INTERNAL_alSource); if (isManaged) { AudioDevice.DynamicInstancePool.Add(this); } }
public void EndApplyDepthStencil() { // Bool -> Int32 conversion int depthBufferEnable = DepthBufferEnable ? 1 : 0; int depthBufferWriteEnable = DepthBufferWriteEnable ? 1 : 0; int stencilEnable = StencilEnable ? 1 : 0; int twoSidedStencilMode = TwoSidedStencilMode ? 1 : 0; int packedProperties = ((int)depthBufferEnable << 32 - 2) | ((int)depthBufferWriteEnable << 32 - 3) | ((int)stencilEnable << 32 - 4) | ((int)twoSidedStencilMode << 32 - 5) | ((int)DepthBufferFunction << 32 - 8) | ((int)StencilFunction << 32 - 11) | ((int)CCWStencilFunction << 32 - 14) | ((int)StencilPass << 32 - 17) | ((int)StencilFail << 32 - 20) | ((int)StencilDepthBufferFail << 32 - 23) | ((int)CCWStencilFail << 32 - 26) | ((int)CCWStencilPass << 32 - 29) | ((int)CCWStencilDepthBufferFail); StateHash hash = new StateHash( packedProperties, StencilMask, StencilWriteMask, ReferenceStencil ); DepthStencilState newDepthStencil; if (!depthStencilCache.TryGetValue(hash, out newDepthStencil)) { newDepthStencil = new DepthStencilState(); newDepthStencil.DepthBufferEnable = DepthBufferEnable; newDepthStencil.DepthBufferWriteEnable = DepthBufferWriteEnable; newDepthStencil.DepthBufferFunction = DepthBufferFunction; newDepthStencil.StencilEnable = StencilEnable; newDepthStencil.StencilFunction = StencilFunction; newDepthStencil.StencilPass = StencilPass; newDepthStencil.StencilFail = StencilFail; newDepthStencil.StencilDepthBufferFail = StencilDepthBufferFail; newDepthStencil.TwoSidedStencilMode = TwoSidedStencilMode; newDepthStencil.CounterClockwiseStencilFunction = CCWStencilFunction; newDepthStencil.CounterClockwiseStencilFail = CCWStencilFail; newDepthStencil.CounterClockwiseStencilPass = CCWStencilPass; newDepthStencil.CounterClockwiseStencilDepthBufferFail = CCWStencilDepthBufferFail; newDepthStencil.StencilMask = StencilMask; newDepthStencil.StencilWriteMask = StencilWriteMask; newDepthStencil.ReferenceStencil = ReferenceStencil; depthStencilCache.Add(hash, newDepthStencil); #if VERBOSE_PIPELINECACHE FNALoggerEXT.LogInfo("New DepthStencilState added to pipeline cache with hash:\n" + hash.ToString()); FNALoggerEXT.LogInfo("Updated size of DepthStencilState cache: " + depthStencilCache.Count); } else { FNALoggerEXT.LogInfo("Retrieved DepthStencilState from pipeline cache with hash:\n" + hash.ToString()); #endif } device.DepthStencilState = newDepthStencil; }
public void Play(Video video) { checkDisposed(); // We need to assign this regardless of what happens next. Video = video; Video.AttachedToPlayer = true; // FIXME: This is a part of the Duration hack! if (Video.needsDurationHack) { Video.Duration = TimeSpan.MaxValue; } // Check the player state before attempting anything. if (State != MediaState.Stopped) { return; } // Update the player state now, before initializing State = MediaState.Playing; // Hook up the decoder to this player InitializeTheoraStream(); // Set up the texture data if (TheoraPlay.THEORAPLAY_hasVideoStream(Video.theoraDecoder) != 0) { // The VideoPlayer will use the GraphicsDevice that is set now. if (currentDevice != Video.GraphicsDevice) { GL_dispose(); currentDevice = Video.GraphicsDevice; GL_initialize(); } RenderTargetBinding overlap = videoTexture[0]; videoTexture[0] = new RenderTargetBinding( new RenderTarget2D( currentDevice, (int)currentVideo.width, (int)currentVideo.height, false, SurfaceFormat.Color, DepthFormat.None, 0, RenderTargetUsage.PreserveContents ) ); if (overlap.RenderTarget != null) { overlap.RenderTarget.Dispose(); } GL_setupTextures( (int)currentVideo.width, (int)currentVideo.height ); } // The player can finally start now! FNALoggerEXT.LogInfo("Starting Theora player..."); timer.Start(); if (audioStream != null) { audioStream.Play(); } FNALoggerEXT.LogInfo("Started!"); }
public virtual void Play() { if (State != SoundState.Stopped) { return; } if (INTERNAL_alSource != null) { // The sound has stopped, but hasn't cleaned up yet... AudioDevice.ALDevice.StopAndDisposeSource(INTERNAL_alSource); INTERNAL_alSource = null; } IALBuffer srcBuf; if (INTERNAL_positionalAudio && INTERNAL_parentEffect.INTERNAL_monoBuffer != null) { srcBuf = INTERNAL_parentEffect.INTERNAL_monoBuffer; } else { srcBuf = INTERNAL_parentEffect.INTERNAL_buffer; } INTERNAL_alSource = AudioDevice.ALDevice.GenSource( srcBuf, INTERNAL_isXACTSource ); if (INTERNAL_alSource == null) { FNALoggerEXT.LogWarn("AL SOURCE WAS NOT AVAILABLE, SKIPPING."); return; } // Apply Pan/Position if (INTERNAL_positionalAudio) { AudioDevice.ALDevice.SetSourcePosition( INTERNAL_alSource, position ); } else { Pan = Pan; } // Reassign Properties, in case the AL properties need to be applied. Volume = Volume; IsLooped = IsLooped; Pitch = Pitch; // Apply EFX if (INTERNAL_alReverb != null) { AudioDevice.ALDevice.SetSourceReverb( INTERNAL_alSource, INTERNAL_alReverb ); } AudioDevice.ALDevice.PlaySource(INTERNAL_alSource); }
public void EndApplyDepthStencil() { StateHash hash = GetDepthStencilHash( DepthBufferEnable, DepthBufferWriteEnable, DepthBufferFunction, StencilEnable, StencilFunction, StencilPass, StencilFail, StencilDepthBufferFail, TwoSidedStencilMode, CCWStencilFunction, CCWStencilPass, CCWStencilFail, CCWStencilDepthBufferFail, StencilMask, StencilWriteMask, ReferenceStencil ); DepthStencilState newDepthStencil; if (!depthStencilCache.TryGetValue(hash, out newDepthStencil)) { newDepthStencil = new DepthStencilState(); newDepthStencil.DepthBufferEnable = DepthBufferEnable; newDepthStencil.DepthBufferWriteEnable = DepthBufferWriteEnable; newDepthStencil.DepthBufferFunction = DepthBufferFunction; newDepthStencil.StencilEnable = StencilEnable; newDepthStencil.StencilFunction = StencilFunction; newDepthStencil.StencilPass = StencilPass; newDepthStencil.StencilFail = StencilFail; newDepthStencil.StencilDepthBufferFail = StencilDepthBufferFail; newDepthStencil.TwoSidedStencilMode = TwoSidedStencilMode; newDepthStencil.CounterClockwiseStencilFunction = CCWStencilFunction; newDepthStencil.CounterClockwiseStencilFail = CCWStencilFail; newDepthStencil.CounterClockwiseStencilPass = CCWStencilPass; newDepthStencil.CounterClockwiseStencilDepthBufferFail = CCWStencilDepthBufferFail; newDepthStencil.StencilMask = StencilMask; newDepthStencil.StencilWriteMask = StencilWriteMask; newDepthStencil.ReferenceStencil = ReferenceStencil; depthStencilCache.Add(hash, newDepthStencil); #if VERBOSE_PIPELINECACHE FNALoggerEXT.LogInfo( "New DepthStencilState added to pipeline cache with hash:\n" + hash.ToString() ); FNALoggerEXT.LogInfo( "Updated size of DepthStencilState cache: " + depthStencilCache.Count ); } else { FNALoggerEXT.LogInfo( "Retrieved DepthStencilState from pipeline cache with hash:\n" + hash.ToString() ); #endif } device.DepthStencilState = newDepthStencil; }