private void GL_popState() { // End the effect, restoring the previous shader state FNA3D.FNA3D_EndPassRestore( currentDevice.GLDevice, shaderProgram.glEffect ); // Restore GL state currentDevice.BlendState = prevBlend; currentDevice.DepthStencilState = prevDepthStencil; currentDevice.RasterizerState = prevRasterizer; prevBlend = null; prevDepthStencil = null; prevRasterizer = null; /* Restore targets using GLDevice directly. * This prevents accidental clearing of previously bound targets. */ if (oldTargets == null || oldTargets.Length == 0) { FNA3D.FNA3D_SetRenderTargets( currentDevice.GLDevice, IntPtr.Zero, 0, IntPtr.Zero, DepthFormat.None, 0 ); } else { IRenderTarget oldTarget = oldTargets[0].RenderTarget as IRenderTarget; unsafe { fixed(FNA3D.FNA3D_RenderTargetBinding *rt = &nativeOldTargets[0]) { GraphicsDevice.PrepareRenderTargetBindings( rt, oldTargets ); FNA3D.FNA3D_SetRenderTargets( currentDevice.GLDevice, rt, oldTargets.Length, oldTarget.DepthStencilBuffer, oldTarget.DepthStencilFormat, (byte)(oldTarget.RenderTargetUsage != RenderTargetUsage.DiscardContents ? 1 : 0) /* lol c# */ ); } } } oldTargets = null; // Set viewport AFTER setting targets! FNA3D.FNA3D_SetViewport( currentDevice.GLDevice, ref prevViewport.viewport ); // Restore buffers currentDevice.SetVertexBuffers(oldBuffers); oldBuffers = null; // Restore samplers currentDevice.Textures.ignoreTargets = true; for (int i = 0; i < 3; i += 1) { /* The application may have set a texture ages * ago, only to not unset after disposing. We * have to avoid an ObjectDisposedException! */ if (oldTextures[i] == null || !oldTextures[i].IsDisposed) { currentDevice.Textures[i] = oldTextures[i]; } currentDevice.SamplerStates[i] = oldSamplers[i]; oldTextures[i] = null; oldSamplers[i] = null; } currentDevice.Textures.ignoreTargets = false; }
protected internal override Texture2D Read( ContentReader reader, Texture2D existingInstance ) { Texture2D texture = null; SurfaceFormat surfaceFormat; if (reader.version < 5) { /* These integer values are based on the enum values * from previous XNA versions. * -flibit */ int legacyFormat = reader.ReadInt32(); if (legacyFormat == 1) { surfaceFormat = SurfaceFormat.ColorBgraEXT; } else if (legacyFormat == 28) { surfaceFormat = SurfaceFormat.Dxt1; } else if (legacyFormat == 30) { surfaceFormat = SurfaceFormat.Dxt3; } else if (legacyFormat == 32) { surfaceFormat = SurfaceFormat.Dxt5; } else { throw new NotSupportedException( "Unsupported legacy surface format." ); } } else { surfaceFormat = (SurfaceFormat)reader.ReadInt32(); } int width = reader.ReadInt32(); int height = reader.ReadInt32(); int levelCount = reader.ReadInt32(); int levelCountOutput = levelCount; GraphicsDevice device = GraphicsDeviceManager.Instance.GraphicsDevice; // Check to see if we need to convert the surface data SurfaceFormat convertedFormat = surfaceFormat; if (surfaceFormat == SurfaceFormat.Dxt1 && FNA3D.FNA3D_SupportsDXT1(device.GLDevice) == 0) { convertedFormat = SurfaceFormat.Color; } else if ((surfaceFormat == SurfaceFormat.Dxt3 || surfaceFormat == SurfaceFormat.Dxt5) && FNA3D.FNA3D_SupportsS3TC(device.GLDevice) == 0) { convertedFormat = SurfaceFormat.Color; } // Check for duplicate instances if (existingInstance == null) { texture = new Texture2D( width, height, levelCountOutput > 1, convertedFormat ); } else { texture = existingInstance; } for (int level = 0; level < levelCount; level += 1) { int levelDataSizeInBytes = reader.ReadInt32(); byte[] levelData = null; // Don't assign this quite yet... int levelWidth = width >> level; int levelHeight = height >> level; if (level >= levelCountOutput) { continue; } // Swap the image data if required. if (reader.platform == 'x') { if (surfaceFormat == SurfaceFormat.Color || surfaceFormat == SurfaceFormat.ColorBgraEXT) { levelData = X360TexUtil.SwapColor( reader.ReadBytes(levelDataSizeInBytes) ); levelDataSizeInBytes = levelData.Length; } else if (surfaceFormat == SurfaceFormat.Dxt1) { levelData = X360TexUtil.SwapDxt1( reader.ReadBytes(levelDataSizeInBytes), levelWidth, levelHeight ); levelDataSizeInBytes = levelData.Length; } else if (surfaceFormat == SurfaceFormat.Dxt3) { levelData = X360TexUtil.SwapDxt3( reader.ReadBytes(levelDataSizeInBytes), levelWidth, levelHeight ); levelDataSizeInBytes = levelData.Length; } else if (surfaceFormat == SurfaceFormat.Dxt5) { levelData = X360TexUtil.SwapDxt5( reader.ReadBytes(levelDataSizeInBytes), levelWidth, levelHeight ); levelDataSizeInBytes = levelData.Length; } } // Convert the image data if required if (convertedFormat != surfaceFormat) { // May already be read in by 'x' conversion if (levelData == null) { levelData = reader.ReadBytes(levelDataSizeInBytes); } if (surfaceFormat == SurfaceFormat.Dxt1) { levelData = DxtUtil.DecompressDxt1( levelData, levelWidth, levelHeight ); } else if (surfaceFormat == SurfaceFormat.Dxt3) { levelData = DxtUtil.DecompressDxt3( levelData, levelWidth, levelHeight ); } else if (surfaceFormat == SurfaceFormat.Dxt5) { levelData = DxtUtil.DecompressDxt5( levelData, levelWidth, levelHeight ); } levelDataSizeInBytes = levelData.Length; } int levelDataByteOffset = 0; if (levelData == null) { if (reader.BaseStream is MemoryStream && ((MemoryStream)reader.BaseStream).TryGetBuffer(out levelData)) { /* Ideally, we didn't have to perform any conversion or * unnecessary reading. Just throw the buffer directly * into SetData, skipping a redundant byte[] copy. */ levelDataByteOffset = (int)reader.BaseStream.Seek(0, SeekOrigin.Current); reader.BaseStream.Seek( levelDataSizeInBytes, SeekOrigin.Current ); } else { /* If we don't have to perform any conversion and * the ContentReader is not backed by a MemoryStream * with a public buffer, we have to read the data in. */ levelData = reader.ReadBytes(levelDataSizeInBytes); } } texture.SetData( level, null, levelData, levelDataByteOffset, levelDataSizeInBytes ); } return(texture); }
private void INTERNAL_CreateGraphicsDeviceInformation( GraphicsDeviceInformation gdi ) { /* Apply the GraphicsDevice changes to the new Parameters. * Note that PreparingDeviceSettings can override any of these! * -flibit */ if (useResizedBackBuffer) { gdi.PresentationParameters.BackBufferWidth = resizedBackBufferWidth; gdi.PresentationParameters.BackBufferHeight = resizedBackBufferHeight; useResizedBackBuffer = false; } else { if (!supportsOrientations) { gdi.PresentationParameters.BackBufferWidth = PreferredBackBufferWidth; gdi.PresentationParameters.BackBufferHeight = PreferredBackBufferHeight; } else { /* Flip the backbuffer dimensions to scale * appropriately to the current orientation. */ int min = Math.Min(PreferredBackBufferWidth, PreferredBackBufferHeight); int max = Math.Max(PreferredBackBufferWidth, PreferredBackBufferHeight); if (gdi.PresentationParameters.DisplayOrientation == DisplayOrientation.Portrait) { gdi.PresentationParameters.BackBufferWidth = min; gdi.PresentationParameters.BackBufferHeight = max; } else { gdi.PresentationParameters.BackBufferWidth = max; gdi.PresentationParameters.BackBufferHeight = min; } } } gdi.PresentationParameters.BackBufferFormat = PreferredBackBufferFormat; gdi.PresentationParameters.DepthStencilFormat = PreferredDepthStencilFormat; gdi.PresentationParameters.IsFullScreen = IsFullScreen; gdi.PresentationParameters.PresentationInterval = SynchronizeWithVerticalRetrace ? PresentInterval.One : PresentInterval.Immediate; if (!PreferMultiSampling) { gdi.PresentationParameters.MultiSampleCount = 0; } else if (gdi.PresentationParameters.MultiSampleCount == 0) { /* XNA4 seems to have an upper limit of 8, but I'm willing to * limit this only in GraphicsDeviceManager's default setting. * If you want even higher values, Reset() with a custom value. * -flibit */ int maxMultiSampleCount = 0; if (graphicsDevice != null) { maxMultiSampleCount = FNA3D.FNA3D_GetMaxMultiSampleCount( graphicsDevice.GLDevice, gdi.PresentationParameters.BackBufferFormat, 8 ); } gdi.PresentationParameters.MultiSampleCount = Math.Min( maxMultiSampleCount, 8 ); } gdi.GraphicsProfile = GraphicsProfile; // Give the user a chance to override the above settings. OnPreparingDeviceSettings( this, new PreparingDeviceSettingsEventArgs(gdi) ); }