/// <summary> /// Render method is called directly by renderer. Depending on stage, post process can do various things /// </summary> /// <param name="postProcessStage">Stage indicating in which part renderer currently is.</param>public override void RenderAfterBlendLights() public override Texture Render(PostProcessStage postProcessStage, Texture source, Texture availableRenderTarget) { switch (postProcessStage) { case PostProcessStage.HDR: { MyMinerGame.SetRenderTarget(availableRenderTarget, null); MyEffectContrast effectContrast = MyRender.GetEffect(MyEffects.Contrast) as MyEffectContrast; effectContrast.SetDiffuseTexture(source); effectContrast.SetHalfPixel(MyUtils.GetHalfPixel(source.GetLevelDescription(0).Width, source.GetLevelDescription(0).Height)); effectContrast.SetContrast(Contrast); effectContrast.SetHue(Hue); effectContrast.SetSaturation(Saturation); MyGuiManager.GetFullscreenQuad().Draw(effectContrast); return availableRenderTarget; } break; } return source; }
/// <summary> /// Render method is called directly by renderer. Depending on stage, post process can do various things /// </summary> /// <param name="postProcessStage">Stage indicating in which part renderer currently is.</param>public override void RenderAfterBlendLights() public override Texture Render(PostProcessStage postProcessStage, Texture source, Texture availableRenderTarget) { switch (postProcessStage) { case PostProcessStage.AlphaBlended: { BlendState.Opaque.Apply(); DepthStencilState.None.Apply(); RasterizerState.CullCounterClockwise.Apply(); MyRender.SetRenderTarget(availableRenderTarget, null); MyEffectAntiAlias effectAntiAlias = MyRender.GetEffect(MyEffects.AntiAlias) as MyEffectAntiAlias; effectAntiAlias.SetDiffuseTexture(source); effectAntiAlias.SetHalfPixel(source.GetLevelDescription(0).Width, source.GetLevelDescription(0).Height); if (MyRenderConstants.RenderQualityProfile.EnableFXAA) effectAntiAlias.ApplyFxaa(); else return source; // Nothing to do, return source MyRender.GetFullscreenQuad().Draw(effectAntiAlias); return availableRenderTarget; } break; } return source; }
public override Texture Render(PostProcessStage postProcessStage, Texture source, Texture availableRenderTarget) { switch (postProcessStage) { case PostProcessStage.AlphaBlended: { BlendState.Opaque.Apply(); DepthStencilState.None.Apply(); RasterizerState.CullCounterClockwise.Apply(); MyRender.SetRenderTarget(availableRenderTarget, null); MyEffectChromaticAberration effectChromaAberr = MyRender.GetEffect(MyEffects.ChromaticAberration) as MyEffectChromaticAberration; effectChromaAberr.SetInputTexture(source); effectChromaAberr.SetHalfPixel(source.GetLevelDescription(0).Width, source.GetLevelDescription(0).Height); effectChromaAberr.SetAspectRatio((float)source.GetLevelDescription(0).Width / (float)source.GetLevelDescription(0).Height); effectChromaAberr.SetDistortionLens(DistortionLens); effectChromaAberr.SetDistortionCubic(DistortionCubic); effectChromaAberr.SetDistortionWeights(ref DistortionWeights); effectChromaAberr.Enable(); MyRender.GetFullscreenQuad().Draw(effectChromaAberr); return availableRenderTarget; } } return source; }
public static void DrawCentered(this Sprite sprite, Texture texture, Vector2 position, Rectangle? rectangle = null) { var desc = texture.GetLevelDescription(0); sprite.Draw( texture, new ColorBGRA(255, 255, 255, 255), rectangle, new Vector3(-(position.X - desc.Width / 2f), -(position.Y - desc.Height / 2f), 0)); }
//loads the data from a stream in to a texture object. private static void InternalDDSFromStream(Stream stream, Device device, int streamOffset, bool loadMipMap, int offsetMipMaps, out SharpDX.Direct3D9.Texture texture) { stream.Position = 0; if (offsetMipMaps == 0) { texture = SharpDX.Direct3D9.Texture.FromStream(device, stream, 0, 0, 0, Usage.None, Format.Unknown, Pool.Default, Filter.None, Filter.None, 0); } else { texture = SharpDX.Direct3D9.Texture.FromStream(device, stream, 0, 0, 0, Usage.Dynamic, Format.Unknown, Pool.Default, Filter.None, Filter.None, 0); int width = MipMapSize(offsetMipMaps, texture.GetLevelDescription(0).Width); int height = MipMapSize(offsetMipMaps, texture.GetLevelDescription(0).Height); int maxLevels = Math.Min(MaxMipMapLevels(width), MaxMipMapLevels(height)); int actualLevels = Math.Min(maxLevels, texture.LevelCount - offsetMipMaps); Format format = texture.GetLevelDescription(0).Format; Texture offsetedTexture = new Texture(device, width, height, actualLevels, Usage.Dynamic, format, Pool.Default); for (int i = offsetMipMaps, j = 0; j < actualLevels; i++, j++) { int levelWidth = MipMapSize(j, width); int levelHeight = MipMapSize(j, height); SharpDX.DataStream ds; texture.LockRectangle(i, LockFlags.ReadOnly, out ds); texture.UnlockRectangle(i); SharpDX.DataStream ds2; offsetedTexture.LockRectangle(j, LockFlags.None, out ds2); ds2.Position = 0; ds2.Write(ds.DataPointer, 0, (int)MipMapSizeInBytes(levelWidth, levelHeight, format)); offsetedTexture.UnlockRectangle(j); } texture.Dispose(); texture = offsetedTexture; } }
public override Texture Render(PostProcessStage postProcessStage, Texture source, Texture availableRenderTarget) { switch (postProcessStage) { case PostProcessStage.AlphaBlended: { BlendState.Opaque.Apply(); DepthStencilState.None.Apply(); RasterizerState.CullCounterClockwise.Apply(); MyRender.SetRenderTarget(availableRenderTarget, null); MyEffectColorMapping effect = MyRender.GetEffect(MyEffects.ColorMapping) as MyEffectColorMapping; effect.SetInputTexture(source); effect.SetHalfPixel(source.GetLevelDescription(0).Width, source.GetLevelDescription(0).Height); effect.Enable(); MyRender.GetFullscreenQuad().Draw(effect); return availableRenderTarget; } } return source; }
public TextureBase(DeviceContext context, Texture texture) : base(context) { _texture = texture; SurfaceDescription desc = _texture.GetLevelDescription(0); _width = desc.Width; _height = desc.Height; _size = new Vector2(_width, _height); _levelCount = _texture.LevelCount; _usage = desc.Usage; _format = desc.Format; _pool = desc.Pool; #if DEBUG Context.PerformanceMonitor.IncreaseLifetimeCounter(LifetimeCounters.TextureCount); #endif }
private void GenerateThreshold(Texture sourceMod, Texture sourceDiv, Texture[] destination, MyEffectThreshold effect, float threshold, float bloomIntensity, float bloomIntensityBackground, float exposure) { MyMinerGame.SetRenderTargets(destination, null); effect.SetSourceTextureMod(sourceMod); effect.SetSourceTextureDiv(sourceDiv); //effect.SetLumTexture(currentFrameAdaptedLuminance); effect.SetHalfPixel(sourceMod.GetLevelDescription(0).Width, sourceMod.GetLevelDescription(0).Height); effect.SetThreshold(threshold); effect.SetBloomIntensity(bloomIntensity); effect.SetBloomIntensityBackground(bloomIntensityBackground); effect.SetExposure(exposure); MyGuiManager.GetFullscreenQuad().Draw(effect); }
/// <summary> /// Downscales the source to 1/4th size, using mipmaps /// !! IMPORTANT !! you cannot just switch function call. Also changing RTs is necessary. /// </summary> protected void GenerateDownscale4(Texture sourceMod, Texture sourceDiv, Texture destination, MyEffectScale effect) { effect.SetTechnique(MyEffectScale.Technique.Downscale4); MyMinerGame.SetRenderTarget(destination, null); effect.SetSourceTextureMod(sourceMod); effect.SetSourceTextureDiv(sourceDiv); //effect.SetLumTexture(currentFrameAdaptedLuminance); effect.SetHalfPixel(sourceMod.GetLevelDescription(0).Width, sourceMod.GetLevelDescription(0).Height); MyGuiManager.GetFullscreenQuad().Draw(effect); }
protected void PostProcess(Texture source, Texture destination, MyEffectHDRBase effect) { MyMinerGame.SetRenderTarget(destination, null); effect.SetHalfPixel(source.GetLevelDescription(0).Width, source.GetLevelDescription(0).Height); effect.SetSourceTextureMod(source); MyGuiManager.GetFullscreenQuad().Draw(effect); }
/* private void CalculateAverageLuminance(RenderTarget2D source, RenderTarget2D destination, MyEffectLuminance luminanceEffect, MyEffectScale scalingEffect, float dt, float tau) { // Calculate the initial luminance luminanceEffect.SetTechniqueLuminance(); PostProcess(source, destination, luminanceEffect); //// Repeatedly downscale //scalingEffect.SetTechniqueDownscale(); //for (int i = 1; i < luminanceChain.Length; i++) //{ // scalingEffect.SetSourceDimensions(luminanceChain[i - 1].Width, luminanceChain[i - 1].Height); // PostProcess(luminanceChain[i - 1], luminanceChain[i], scalingEffect); //} //// Final downscale //scalingEffect.SetTechniqueDownscaleLuminance(); //scalingEffect.SetSourceDimensions(luminanceChain[luminanceChain.Length - 1].Width, luminanceChain[luminanceChain.Length - 1].Height); //PostProcess(luminanceChain[luminanceChain.Length - 1], currentFrameLuminance, scalingEffect); // Final downscale luminanceEffect.SetTechniqueLuminanceMipmap(); float size = MathHelper.Min(MyCamera.ForwardViewport.Width, MyCamera.ForwardViewport.Height); // TODO check if mipmap level is correct int mipLevel = (int)Math.Floor(Math.Log(size / 8.0f, 2)); //int mipLevel = (int)Math.Ceiling(Math.Log(size / 8.0f, 2)); luminanceEffect.SetMipLevel(mipLevel); PostProcess(destination, currentFrameLuminance, luminanceEffect); // Adapt the luminance, to simulate slowly adjust exposure MyMinerGame.Static.GraphicsDevice.SetRenderTarget(currentFrameAdaptedLuminance); luminanceEffect.SetTechniqueAdaptedLuminance(); luminanceEffect.SetDT(dt); luminanceEffect.SetTau(tau); luminanceEffect.SetSourceTexture(currentFrameLuminance); luminanceEffect.SetSourceTexture2(lastFrameAdaptedLuminance); luminanceEffect.SetHalfPixel(source.Width, source.Height); MyGuiManager.GetFullscreenQuad().Draw(luminanceEffect); } */ private void HDR(Texture sourceMod, Texture sourceDiv, Texture bloomSource, MyEffectHDR effect, float middleGrey, float exposure) { effect.SetSourceTextureMod(sourceMod); effect.SetSourceTextureDiv(sourceDiv); effect.SetBloomTexture(bloomSource); //effect.SetLumTexture(currentFrameAdaptedLuminance); //effect.SetLumTexture(currentFrameLuminance); effect.SetHalfPixel(sourceMod.GetLevelDescription(0).Width, sourceMod.GetLevelDescription(0).Height); //effect.SetMiddleGrey(middleGrey); effect.SetExposure(exposure); MyGuiManager.GetFullscreenQuad().Draw(effect); }
private void Blur(Texture sourceAndDestination, Texture aux, MyEffectGaussianBlur effect, float verticalBlurAmount, float horizontalBlurAmount) { effect.SetHalfPixel(sourceAndDestination.GetLevelDescription(0).Width, sourceAndDestination.GetLevelDescription(0).Height); int numberOfBlurPasses = Convert.ToInt32(Math.Floor(NumberOfBlurPasses)); for (int i = 0; i < numberOfBlurPasses; i++) { // Apply vertical gaussian blur MyMinerGame.SetRenderTarget(aux, null); effect.BlurAmount = verticalBlurAmount; effect.SetSourceTexture(sourceAndDestination); //effect.SetWidthForHorisontalPass(sourceAndDestination.Width); effect.SetHeightForVerticalPass(sourceAndDestination.GetLevelDescription(0).Height); MyGuiManager.GetFullscreenQuad().Draw(effect); // Apply horizontal gaussian blur MyMinerGame.SetRenderTarget(sourceAndDestination, null); effect.BlurAmount = horizontalBlurAmount; effect.SetSourceTexture(aux); //effect.SetHeightForVerticalPass(sourceAndDestination.Height); effect.SetWidthForHorisontalPass(aux.GetLevelDescription(0).Width); MyGuiManager.GetFullscreenQuad().Draw(effect); } }
public static void SaveScreenshot(Texture texture2D, string file) { MyMwcLog.WriteLine("MyScreenshot.SaveTexture2D() - START"); MyMwcLog.IncreaseIndent(); Texture systemTex = new Texture(MinerWars.AppCode.App.MyMinerGame.Static.GraphicsDevice, texture2D.GetLevelDescription(0).Width, texture2D.GetLevelDescription(0).Height, 0, Usage.None, Format.A8R8G8B8, Pool.SystemMemory); Surface sourceSurface = texture2D.GetSurfaceLevel(0); Surface destSurface = systemTex.GetSurfaceLevel(0); MinerWars.AppCode.App.MyMinerGame.Static.GraphicsDevice.GetRenderTargetData(sourceSurface, destSurface); sourceSurface.Dispose(); destSurface.Dispose(); texture2D = systemTex; try { MyMwcLog.WriteLine("File: " + file); MyFileSystemUtils.CreateFolderForFile(file); Stack<SharpDX.Rectangle> tiles = new Stack<SharpDX.Rectangle>(); int tileWidth = texture2D.GetLevelDescription(0).Width; int tileHeight = texture2D.GetLevelDescription(0).Height; while (tileWidth > 3200) { tileWidth /= 2; tileHeight /= 2; } int widthOffset = 0; int heightOffset = 0; while (widthOffset < texture2D.GetLevelDescription(0).Width) { while (heightOffset < texture2D.GetLevelDescription(0).Height) { tiles.Push(new SharpDX.Rectangle(widthOffset, heightOffset, tileWidth, tileHeight)); heightOffset += tileHeight; } heightOffset = 0; widthOffset += tileWidth; } int sc = 0; while (tiles.Count > 0) { SharpDX.Rectangle rect = tiles.Pop(); byte[] data = new byte[rect.Width * rect.Height * 4]; SharpDX.Rectangle rect2 = new SharpDX.Rectangle(rect.X, rect.Y, rect.Width, rect.Height); //texture2D.GetData<byte>(0, rect2, data, 0, data.Length); DataStream ds; texture2D.LockRectangle(0, rect2, LockFlags.None, out ds); ds.Read(data, 0, data.Length); /* for (int i = 0; i < data.Length; i += 4) { //Swap ARGB <-> RGBA byte b = data[i + 0]; byte g = data[i + 1]; byte r = data[i + 2]; byte a = data[i + 3]; data[i + 0] = r; //Blue data[i + 1] = g; //Green data[i + 2] = b; //Red data[i + 3] = a; //Alpha } */ ds.Seek(0, SeekOrigin.Begin); ds.WriteRange(data); texture2D.UnlockRectangle(0); string filename = file.Replace(".png", "_" + sc.ToString("##00") + ".png"); using (Stream stream = File.Create(filename)) { System.Drawing.Bitmap image = new System.Drawing.Bitmap(rect.Width, rect.Height); System.Drawing.Imaging.BitmapData imageData = image.LockBits(new System.Drawing.Rectangle(0,0,rect.Width, rect.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); System.Runtime.InteropServices.Marshal.Copy(data, 0, imageData.Scan0, data.Length); image.Save(stream, System.Drawing.Imaging.ImageFormat.Png); image.UnlockBits(imageData); image.Dispose(); //texture2D.SaveAsPng(stream, texture2D.Width, texture2D.Height); //BaseTexture.ToStream(texture2D, ImageFileFormat.Png); } sc++; GC.Collect(); } } catch (Exception exc) { // Write exception to log, but continue as if nothing wrong happened MyMwcLog.WriteLine(exc); } texture2D.Dispose(); //BaseTexture.ToFile(texture2D, "c:\\test.png", ImageFileFormat.Png); MyMwcLog.DecreaseIndent(); MyMwcLog.WriteLine("MyScreenshot.SaveTexture2D() - END"); }
public void SetSourceTexture(Texture renderTarget2D) { m_D3DEffect.SetTexture(m_source, renderTarget2D); m_D3DEffect.SetValue(m_halfPixel, MyUtils.GetHalfPixel(renderTarget2D.GetLevelDescription(0).Width, renderTarget2D.GetLevelDescription(0).Height)); }
static void DrawVertexBuffer(Texture depthForParticlesRT, List<MyBillboard> billboards) { // This is important for optimalization (although I don't know when it can happen to have zero billboards), but // also that loop below needs it - as it assumes we are rendering at least one billboard. if (billboards.Count == 0) return; Device device = MyRender.GraphicsDevice; Surface oldTargets = null; DepthStencilState previousState = null; if (MyRender.Settings.VisualizeOverdraw) { oldTargets = device.GetRenderTarget(0); //We borrow lod0normals to render stencil MyRender.SetRenderTarget(MyRender.GetRenderTarget(MyRenderTargets.Auxiliary0), null); device.Clear(ClearFlags.Target | ClearFlags.Stencil, new ColorBGRA(0), 1.0f, 0); previousState = MyStateObjects.StencilMask_AlwaysIncrement_DepthStencilState; MyStateObjects.StencilMask_AlwaysIncrement_DepthStencilState.Apply(); } else { previousState = DepthStencilState.None; DepthStencilState.None.Apply(); } // Draw particles without culling. It's because how we calculate left/up vector, we can have problems in back camera. (yes, that can be solved, but why bother...) // Also I guess that drawing without culling may be faster - as GPU doesn't have to check it // No it's not, correct culling is faster: http://msdn.microsoft.com/en-us/library/windows/desktop/bb204882(v=vs.85).aspx RasterizerState.CullNone.Apply(); MyEffectTransparentGeometry effect = MyRender.GetEffect(MyEffects.TransparentGeometry) as MyEffectTransparentGeometry; effect.SetWorldMatrix(Matrix.Identity); Matrix viewMatrix = MyRenderCamera.ViewMatrixAtZero; effect.SetViewMatrix(ref viewMatrix); effect.SetProjectionMatrix(ref MyRenderCamera.ProjectionMatrix); Viewport originalViewport = MyRender.GraphicsDevice.Viewport; effect.SetDepthsRT(depthForParticlesRT); effect.SetHalfPixel(depthForParticlesRT.GetLevelDescription(0).Width, depthForParticlesRT.GetLevelDescription(0).Height); effect.SetScale(MyRender.GetScaleForViewport(depthForParticlesRT)); // Later we can interpolate between Main and Aux effect.SetEnvironmentMap(MyRender.GetRenderTargetCube(MyRenderTargets.EnvironmentCube)); //For struct size checks //int stride = MyVertexFormatTransparentGeometry.VertexDeclaration.VertexStride; //int s = Marshal.SizeOf(new MyVertexFormatTransparentGeometry()); // We iterate over all sorted billboards, and seach for when texture/shader has changed. // We try to draw as many billboards as possible (using the same texture), but because we are rendering billboards // sorted by depth, we still need to switch sometimes. Btw: I have observed, that most time consuming when drawing particles // is device.DrawUserPrimitives(), even if I call it for the whole list of billboards (without this optimization). I think, it's // because particles are pixel-bound (I do a lot of light calculation + there is blending, which is always slow). MyTransparentMaterial lastMaterial = MyTransparentMaterials.GetMaterial(billboards[0].Material); MyBillboard lastBillboard = billboards[0]; MyTransparentMaterial lastBlendMaterial = lastBillboard.BlendMaterial != null ? MyTransparentMaterials.GetMaterial(lastBillboard.BlendMaterial) : null; bool ignoreDepth = false; Matrix projectionMatrix = MyRenderCamera.ProjectionMatrix; Matrix invProjectionMatrix = Matrix.Invert(projectionMatrix); effect.SetInverseDefaultProjectionMatrix(ref invProjectionMatrix); if (lastBillboard.CustomViewProjection != -1) { SetupCustomViewProjection(effect, ref originalViewport, lastBillboard, ref ignoreDepth, ref projectionMatrix); } // 0.05% of billboard is blended const float softColorizeSize = 0.05f; device.VertexDeclaration = MyVertexFormatTransparentGeometry.VertexDeclaration; device.SetStreamSource(0, m_vertexBuffer, 0, MyVertexFormatTransparentGeometry.Stride); device.Indices = m_indexBuffer; MyRender.GetShadowRenderer().SetupShadowBaseEffect(effect); MyEffectTransparentGeometry effect2 = MyRender.GetEffect(MyEffects.TransparentGeometry) as MyEffectTransparentGeometry; effect2.SetShadowBias(0.001f); MyLights.UpdateEffectReflector(effect2.Reflector, false); MyLights.UpdateEffect(effect2, false); int geomCount = billboards.Count; int it = 0; int cnt = 0; while (geomCount > 0) { if (geomCount > RENDER_BUFFER_SIZE) { geomCount -= RENDER_BUFFER_SIZE; cnt = RENDER_BUFFER_SIZE; } else { cnt = geomCount; geomCount = 0; } int indexFrom = it * RENDER_BUFFER_SIZE + 1; cnt = cnt + indexFrom - 1; for (int i = indexFrom; i <= cnt; i++) { // We need texture from billboard that's before the current billboard (because we always render "what was") MyBillboard billboard = billboards[i - 1]; MyTransparentMaterial blendMaterialProperties = billboard.BlendMaterial != null ? MyTransparentMaterials.GetMaterial(billboard.BlendMaterial) : MyTransparentMaterials.GetMaterial(billboard.Material); MyTransparentMaterial lastBlendMaterialProperties = lastBlendMaterial == null ? blendMaterialProperties : lastBlendMaterial; bool colorizeChanged = EnableColorize && lastBillboard.EnableColorize != billboard.EnableColorize; bool nearChanged = lastBillboard.Near != billboard.Near; bool sizeChanged = EnableColorize && billboard.EnableColorize && lastBillboard.Size != billboard.Size; bool blendTextureChanged = false; bool projectionChanged = lastBillboard.CustomViewProjection != billboard.CustomViewProjection; bool cullStencilChanges = lastBillboard.CullWithStencil != billboard.CullWithStencil; if (lastBlendMaterial != (billboard.BlendMaterial != null ? MyTransparentMaterials.GetMaterial(billboard.BlendMaterial) : null) && billboard.BlendTextureRatio > 0) { if ((lastBlendMaterialProperties.UseAtlas) && (blendMaterialProperties.UseAtlas)) blendTextureChanged = false; else blendTextureChanged = true; } //bool blendTextureChanged = lastBlendTexture != billboard.BlendTexture; bool billboardChanged = colorizeChanged || sizeChanged || blendTextureChanged || nearChanged || projectionChanged || cullStencilChanges; MyTransparentMaterial actMaterialProperties = MyTransparentMaterials.GetMaterial(billboard.Material); MyTransparentMaterial lastMaterialProperties = lastMaterial; billboardChanged |= (actMaterialProperties.CanBeAffectedByOtherLights != lastMaterialProperties.CanBeAffectedByOtherLights) || (actMaterialProperties.IgnoreDepth != lastMaterialProperties.IgnoreDepth); if (projectionChanged) { SetupCustomViewProjection(effect, ref originalViewport, lastBillboard, ref ignoreDepth, ref projectionMatrix); } if (!billboardChanged) { if (MyTransparentMaterials.GetMaterial(billboard.Material) != lastMaterial) { if (actMaterialProperties.UseAtlas && lastMaterialProperties.UseAtlas) billboardChanged = false; else billboardChanged = true; } } // If texture is different than the last one, or if we reached end of billboards if ((i == cnt) || billboardChanged) { // We don't need to do this when we reach end of billboards - it's needed only if we do next iteration of possible billboards if ((i != cnt) || billboardChanged) { if ((i - indexFrom) > 0) { int firstIndex = (indexFrom - 1) * MyTransparentGeometryConstants.INDICES_PER_TRANSPARENT_GEOMETRY; //MyTransparentGeometryConstants.VERTICES_PER_TRANSPARENT_GEOMETRY; SetupCustomViewProjection(effect, ref originalViewport, lastBillboard, ref ignoreDepth, ref projectionMatrix); SetupEffect(ref lastMaterial, lastBlendMaterialProperties, EnableColorize && lastBillboard.EnableColorize, lastBillboard.Size * softColorizeSize, lastBillboard.Near, ignoreDepth, ref projectionMatrix); effect.Begin(); DrawBuffer(firstIndex, (i - indexFrom) * MyTransparentGeometryConstants.TRIANGLES_PER_TRANSPARENT_GEOMETRY); effect.End(); MyPerformanceCounter.PerCameraDrawWrite.BillboardsDrawCalls++; } lastMaterial = MyTransparentMaterials.GetMaterial(billboard.Material); lastBillboard = billboard; lastBlendMaterial = billboard.BlendMaterial != null ? MyTransparentMaterials.GetMaterial(billboard.BlendMaterial) : null; indexFrom = i; } if ((i == cnt) && (i - indexFrom + 1 != 0)) { lastMaterial = MyTransparentMaterials.GetMaterial(lastBillboard.Material); blendMaterialProperties = lastBillboard.BlendMaterial == null ? MyTransparentMaterials.GetMaterial(lastBillboard.Material) : MyTransparentMaterials.GetMaterial(lastBillboard.BlendMaterial); int firstIndex = (indexFrom - 1) * MyTransparentGeometryConstants.INDICES_PER_TRANSPARENT_GEOMETRY; SetupCustomViewProjection(effect, ref originalViewport, lastBillboard, ref ignoreDepth, ref projectionMatrix); SetupEffect(ref lastMaterial, blendMaterialProperties, EnableColorize && billboard.EnableColorize, lastBillboard.Size * softColorizeSize, lastBillboard.Near, ignoreDepth, ref projectionMatrix); if (billboard.CullWithStencil) { DepthStencilState.BackgroundObjects.Apply(); } effect.Begin(); DrawBuffer(firstIndex, (i - indexFrom + 1) * MyTransparentGeometryConstants.TRIANGLES_PER_TRANSPARENT_GEOMETRY); effect.End(); if (billboard.CullWithStencil) { previousState.Apply(); } MyPerformanceCounter.PerCameraDrawWrite.BillboardsDrawCalls++; } } } it++; } device.SetStreamSource(0, null, 0, 0); MyPerformanceCounter.PerCameraDrawWrite.BillboardsInFrustum += billboards.Count; // Visualize overdraw of particles. More overdraws = bigger performance issue. if (MyRender.Settings.VisualizeOverdraw) { if (m_overDrawColorsAnim == null) { m_overDrawColorsAnim = new MyAnimatedPropertyVector4(); m_overDrawColorsAnim.AddKey(0.0f, new Vector4(0.0f, 1.0f, 0.0f, 1.0f)); m_overDrawColorsAnim.AddKey(0.25f, new Vector4(1.0f, 1.0f, 0.0f, 1.0f)); m_overDrawColorsAnim.AddKey(0.75f, new Vector4(0.0f, 0.0f, 1.0f, 1.0f)); m_overDrawColorsAnim.AddKey(1.0f, new Vector4(1.0f, 0.0f, 0.0f, 1.0f)); } //Space without particles is black device.Clear(ClearFlags.Target, new ColorBGRA(0), 1.0f, 0); for (int referenceStencil = 1; referenceStencil < PARTICLES_OVERDRAW_MAX; referenceStencil++) { DepthStencilState ds = new DepthStencilState() { StencilEnable = true, ReferenceStencil = referenceStencil, StencilFunction = Compare.LessEqual, }; ds.Apply(false); float diff = (float)(referenceStencil - 1) / (PARTICLES_OVERDRAW_MAX - 1); Vector4 referenceColorV4; m_overDrawColorsAnim.GetInterpolatedValue<Vector4>(diff, out referenceColorV4); Color referenceColor = new Color(referenceColorV4); MyRender.BeginSpriteBatch(BlendState.Opaque, null, null); MyRender.DrawSprite(MyRender.BlankTexture, new Rectangle(0, 0, MyRenderCamera.Viewport.Width, MyRenderCamera.Viewport.Height), referenceColor); MyRender.EndSpriteBatch(); } DepthStencilState.None.Apply(); int leftStart = MyRenderCamera.Viewport.Width / 4; int topStart = (int)(MyRenderCamera.Viewport.Height * 0.75f); int size = MyRenderCamera.Viewport.Width - 2 * leftStart; int sizeY = (int)(MyRenderCamera.Viewport.Width / 32.0f); int sizeStep = size / PARTICLES_OVERDRAW_MAX; MyRender.BeginSpriteBatch(null, null, null); for (int i = 0; i < PARTICLES_OVERDRAW_MAX; i++) { float diff = (float)(i - 1) / (PARTICLES_OVERDRAW_MAX - 1); Vector4 referenceColorV4; m_overDrawColorsAnim.GetInterpolatedValue<Vector4>(diff, out referenceColorV4); Color referenceColor = new Color(referenceColorV4); MyRender.DrawSprite(MyRender.BlankTexture, new Rectangle(leftStart + i * sizeStep, topStart, sizeStep, sizeY), referenceColor); } MyDebugDraw.DrawText(new Vector2((float)leftStart, (float)(topStart + sizeY)), new System.Text.StringBuilder("1"), Color.White, 1.0f, false); MyDebugDraw.DrawText(new Vector2((float)leftStart + size, (float)(topStart + sizeY)), new System.Text.StringBuilder(">" + PARTICLES_OVERDRAW_MAX.ToString()), Color.White, 1.0f, false); MyRender.EndSpriteBatch(); device.SetRenderTarget(0, oldTargets); oldTargets.Dispose(); MyRender.Blit(MyRender.GetRenderTarget(MyRenderTargets.Auxiliary0), false); } // Restore to 'opaque', because that's the usual blend state BlendState.Opaque.Apply(); }
// Draws sprite batch at specified position // normalizedPosition -> X and Y are within interval <0..1> // scale -> scale for original texture, it's not in pixel/texels, but multiply of original size. E.g. 1 means unchanged size, 2 means double size. Scale is uniform, preserves aspect ratio. // rotation -> angle in radians. Rotation is always around "origin" coordinate // originNormalized -> the origin of the sprite. Specify (0,0) for the upper-left corner. // RETURN: Method returns rectangle where was sprite/texture drawn in normalized coordinates public static void DrawSpriteBatch(Texture texture, Vector2 normalizedCoord, float scale, Color color, MyGuiDrawAlignEnum drawAlign, float rotation, Vector2 originNormalized) { System.Diagnostics.Debug.Assert(m_spriteBatchUsageCount > 0); if (texture == null) return; Vector2 screenCoord = GetScreenCoordinateFromNormalizedCoordinate(normalizedCoord); // Fix the scale for screen resolution float fixedScale = scale * m_safeScreenScale; Vector2 sizeInPixels = new Vector2(texture.GetLevelDescription(0).Width, texture.GetLevelDescription(0).Height); Vector2 sizeInPixelsScaled = sizeInPixels * fixedScale; screenCoord = GetAlignedCoordinate(screenCoord, sizeInPixelsScaled, drawAlign); m_spriteBatch.Draw(texture, SharpDXHelper.ToSharpDX(screenCoord), null, SharpDXHelper.ToSharpDX(color), rotation, SharpDXHelper.ToSharpDX(originNormalized * sizeInPixels), fixedScale, SpriteEffects.None, 0); }
public void SetDitheringTexture(Texture ditheringTexture) { m_D3DEffect.SetTexture(m_ditheringTexture, ditheringTexture); var desc = ditheringTexture.GetLevelDescription(0); m_D3DEffect.SetValue(m_ditheringTextureSize, new Vector2(desc.Width, desc.Height)); }
private static void InternalDDSFromStream(Stream stream, Device device, int streamOffset, bool loadMipMap, int offsetMipMaps, out SharpDX.Direct3D9.Texture texture) { var fileStream = stream as FileStream; byte[] data = fileStream != null ? null : SharpDX.Utilities.ReadStream(stream); int maxTextureDimension = MyRender.GraphicsDevice.Capabilities.MaxTextureWidth; if (IntPtr.Size == 4 || MyRender.GraphicsDevice.AvailableTextureMemory < 1024 * 1024 * 600) { maxTextureDimension = 2048; } ImageInformation imageInfo; if (fileStream != null) { imageInfo = GetImageInfoFromFileW(fileStream.Name); } else { imageInfo = ImageInformation.FromMemory(data); } var textureWidth = imageInfo.Width; var textureHeight = imageInfo.Height; textureWidth = Math.Max(1, textureWidth >> offsetMipMaps); textureHeight = Math.Max(1, textureHeight >> offsetMipMaps); int loadMipmapOffset = offsetMipMaps; while (textureWidth > maxTextureDimension || textureHeight > maxTextureDimension) { loadMipmapOffset++; textureWidth = Math.Max(1, textureWidth >> 1); textureHeight = Math.Max(1, textureHeight >> 1); } if (offsetMipMaps == 0 && loadMipmapOffset == 0) { if (fileStream != null) { texture = SharpDX.Direct3D9.Texture.FromFile(device, fileStream.Name, 0, 0, 0, Usage.None, Format.Unknown, Pool.Default, Filter.None, Filter.None, 0); } else { texture = SharpDX.Direct3D9.Texture.FromMemory(device, data, 0, 0, 0, Usage.None, Format.Unknown, Pool.Default, Filter.None, Filter.None, 0); } } else if (loadMipmapOffset > 0) { var skipFilter = (Filter)D3DXSkipDDSMipLevels((uint)loadMipmapOffset); if (fileStream != null) { texture = SharpDX.Direct3D9.Texture.FromFile(device, fileStream.Name, 0, 0, 0, Usage.None, Format.Unknown, Pool.Default, Filter.None, skipFilter, 0); } else { texture = SharpDX.Direct3D9.Texture.FromMemory(device, data, 0, 0, 0, Usage.None, Format.Unknown, Pool.Default, Filter.None, skipFilter, 0); } } else { if (fileStream != null) { texture = SharpDX.Direct3D9.Texture.FromFile(device, fileStream.Name, 0, 0, 0, Usage.None, Format.Unknown, Pool.Default, Filter.None, Filter.None, 0); } else { texture = SharpDX.Direct3D9.Texture.FromMemory(device, data, 0, 0, 0, Usage.None, Format.Unknown, Pool.Default, Filter.None, Filter.None, 0); } int width = MipMapSize(offsetMipMaps, texture.GetLevelDescription(0).Width); int height = MipMapSize(offsetMipMaps, texture.GetLevelDescription(0).Height); int maxLevels = Math.Min(MaxMipMapLevels(width), MaxMipMapLevels(height)); int actualLevels = Math.Min(maxLevels, texture.LevelCount - offsetMipMaps); Format format = texture.GetLevelDescription(0).Format; Texture offsetedTexture = new Texture(device, width, height, actualLevels, Usage.Dynamic, format, Pool.Default); for (int i = offsetMipMaps, j = 0; j < actualLevels; i++, j++) { int levelWidth = MipMapSize(j, width); int levelHeight = MipMapSize(j, height); SharpDX.DataStream ds; texture.LockRectangle(i, LockFlags.ReadOnly, out ds); texture.UnlockRectangle(i); SharpDX.DataStream ds2; offsetedTexture.LockRectangle(j, LockFlags.None, out ds2); ds2.Position = 0; ds2.Write(ds.DataPointer, 0, (int)MipMapSizeInBytes(levelWidth, levelHeight, format)); offsetedTexture.UnlockRectangle(j); } texture.Dispose(); texture = offsetedTexture; } }
public void DrawOverlay(Texture targetTexture) { Subtitle currentSubtitle; lock (_syncObj) { currentSubtitle = _subtitles.ToList().FirstOrDefault(s => s.ShouldDraw); if (currentSubtitle == null) return; if (targetTexture == null || targetTexture.IsDisposed || currentSubtitle.SubTexture == null || currentSubtitle.SubTexture.IsDisposed) { if (_drawCount > 0) ServiceRegistration.Get<ILogger>().Debug("Draw count for last sub: {0}", _drawCount); _drawCount = 0; return; } _drawCount++; } try { // TemporaryRenderTarget changes RenderTarget to texture and restores settings when done (Dispose) using (new TemporaryRenderTarget(targetTexture)) using (TemporaryRenderState temporaryRenderState = new TemporaryRenderState()) using (Sprite sprite = new Sprite(_device)) { sprite.Begin(SpriteFlags.AlphaBlend); // No alpha test here, allow all values temporaryRenderState.SetTemporaryRenderState(RenderState.AlphaTestEnable, 0); // Use the SourceAlpha channel and InverseSourceAlpha for destination temporaryRenderState.SetTemporaryRenderState(RenderState.BlendOperation, (int)BlendOperation.Add); temporaryRenderState.SetTemporaryRenderState(RenderState.SourceBlend, (int)Blend.SourceAlpha); temporaryRenderState.SetTemporaryRenderState(RenderState.DestinationBlend, (int)Blend.InverseSourceAlpha); // Check the target texture dimensions and adjust scaling and translation SurfaceDescription desc = targetTexture.GetLevelDescription(0); Matrix transform = Matrix.Identity; // Position subtitle and scale it to match video frame size, if required transform *= Matrix.Translation(currentSubtitle.HorizontalPosition, currentSubtitle.FirstScanLine, 0); if (currentSubtitle.ScreenWidth != desc.Width || currentSubtitle.ScreenHeight != desc.Height) { var factorW = (float)desc.Width / currentSubtitle.ScreenWidth; var factorH = (float)desc.Height / currentSubtitle.ScreenHeight; transform *= Matrix.Scaling(factorW, factorH, 1); } sprite.Transform = transform; sprite.Draw(currentSubtitle.SubTexture, SharpDX.Color.White); sprite.End(); } if (_onTextureInvalidated != null) _onTextureInvalidated(); } catch (Exception ex) { ServiceRegistration.Get<ILogger>().Debug("Error in DrawOverlay", ex); } }
public void Allocate(int width, int height, Usage usage, Format format) { bool free; lock (_syncObj) free = width != _size.Width || height != _size.Height || usage != _usage || format != _format; if (free) Free(); lock (_syncObj) { if (_texture != null) return; _size.Width = width; _size.Height = height; _usage = usage; _format = format; // Note that it doesn't seem to be possible to create a texture with multisample surfaces inside. So rendering to that texture // won't provide multisample antialiasing. _texture = new Texture(GraphicsDevice.Device, width, height, 1, usage, format, Pool.Default); _surface0 = _texture.GetSurfaceLevel(0); SurfaceDescription desc = _texture.GetLevelDescription(0); _maxU = _size.Width/((float) desc.Width); _maxV = _size.Height/((float) desc.Height); } AllocationChanged(AllocationSize); KeepAlive(); }
public void SetRandomTexture(Texture randomTexture) { m_D3DEffect.SetTexture(m_randomTexture, randomTexture); m_D3DEffect.SetValue(m_randomTextureSize, randomTexture.GetLevelDescription(0).Width); }
protected static Texture CreateTextureCopy(Texture sourceTexture, out SizeF textureSize) { if (sourceTexture == null) { textureSize = new SizeF(); return null; } SurfaceDescription desc = sourceTexture.GetLevelDescription(0); textureSize = new SizeF(desc.Width, desc.Height); DeviceEx device = SkinContext.Device; Texture result = new Texture(device, desc.Width, desc.Height, 1, Usage.None, Format.A8R8G8B8, Pool.Default); using(Surface target = result.GetSurfaceLevel(0)) using(Surface source = sourceTexture.GetSurfaceLevel(0)) device.StretchRectangle(source, target, TextureFilter.None); return result; }
// Draws sprite batch at specified position // normalizedPosition -> X and Y are within interval <0..1> // scale -> scale for original texture, it's not in pixel/texels, but multiply of original size. E.g. 1 means unchanged size, 2 means double size. Scale is uniform, preserves aspect ratio. // rotation -> angle in radians. Rotation is always around "origin" coordinate // originNormalized -> the origin of the sprite. Specify (0,0) for the upper-left corner. // RETURN: Method returns rectangle where was sprite/texture drawn in normalized coordinates internal static void DrawSpriteBatch(Texture texture, Vector2 normalizedCoord, float scale, Color color, MyGuiDrawAlignEnum drawAlign, Vector2 rightVector, Vector2 originNormalized) { System.Diagnostics.Debug.Assert(m_spriteBatchUsageCount > 0); if (texture == null) return; if (m_screenshot != null && m_screenshot.IgnoreSprites) return; Vector2 screenCoord = GetScreenCoordinateFromNormalizedCoordinate(normalizedCoord); // Fix the scale for screen resolution float fixedScale = scale * m_safeScreenScale; Vector2 sizeInPixels = new Vector2(texture.GetLevelDescription(0).Width, texture.GetLevelDescription(0).Height); Vector2 sizeInPixelsScaled = sizeInPixels * fixedScale; screenCoord = GetAlignedCoordinate(screenCoord, sizeInPixelsScaled, drawAlign); //m_spriteBatch.Draw(texture, SharpDXHelper.ToSharpDX(screenCoord), null, SharpDXHelper.ToSharpDX(color), rotation, SharpDXHelper.ToSharpDX(originNormalized * sizeInPixels), fixedScale, SpriteEffects.None, 0); RectangleF rect = new RectangleF(screenCoord.X, screenCoord.Y, fixedScale, fixedScale); Vector2 origin = originNormalized * sizeInPixels; m_spriteBatch.DrawSprite(texture, null, ref rect, true, null, color, rightVector, ref origin, VRageRender.Graphics.SpriteEffects.None, 0); }
private void BlitToThumbnail(Device device, Texture renderTarget) { MyMinerGame.SetRenderTarget(renderTarget, null); var screenEffect = MyRender.GetEffect(MyEffects.Scale) as MyEffectScale; Debug.Assert(screenEffect != null); screenEffect.SetTechnique(MyEffectScale.Technique.HWScalePrefabPreviews); screenEffect.SetSourceTextureMod(m_fullSizeRT); //screenEffect.SetScale(2f * new Vector2(renderTarget.Width / (float)m_fullSizeRT.Width, renderTarget.Height / (float)m_fullSizeRT.Height)); screenEffect.SetScale(2f * new Vector2((renderTarget.GetLevelDescription(0).Width - 1) / (float)m_fullSizeRT.GetLevelDescription(0).Width, (renderTarget.GetLevelDescription(0).Height - 1) / (float)m_fullSizeRT.GetLevelDescription(0).Height)); MyGuiManager.GetFullscreenQuad().Draw(screenEffect); MyMinerGame.SetRenderTarget(null, null); }
public static string SaveScreenshot(Texture tex, string file) { MyRender.Log.WriteLine("MyScreenshot.SaveTexture2D() - START"); MyRender.Log.IncreaseIndent(); string filename = null; using (Texture systemTex = new Texture(MyRender.GraphicsDevice, tex.GetLevelDescription(0).Width, tex.GetLevelDescription(0).Height, 1, Usage.None, Format.A8R8G8B8, Pool.SystemMemory)) { string extension = Path.GetExtension(file); using (Surface sourceSurface = tex.GetSurfaceLevel(0)) using (Surface destSurface = systemTex.GetSurfaceLevel(0)) { MyRender.GraphicsDevice.GetRenderTargetData(sourceSurface, destSurface); } try { MyRender.Log.WriteLine("File: " + file); Stack<SharpDX.Rectangle> tiles = new Stack<SharpDX.Rectangle>(); int tileWidth = systemTex.GetLevelDescription(0).Width; int tileHeight = systemTex.GetLevelDescription(0).Height; while (tileWidth > 3200) { tileWidth /= 2; tileHeight /= 2; } int widthOffset = 0; int heightOffset = 0; while (widthOffset < systemTex.GetLevelDescription(0).Width) { while (heightOffset < systemTex.GetLevelDescription(0).Height) { tiles.Push(new SharpDX.Rectangle(widthOffset, heightOffset, widthOffset + tileWidth, heightOffset + tileHeight)); heightOffset += tileHeight; } heightOffset = 0; widthOffset += tileWidth; } bool multipleTiles = tiles.Count > 1; int sc = 0; byte[] data = new byte[tileWidth * tileHeight * 4]; int sysTexWidth = systemTex.GetLevelDescription(0).Width; int sysTexHeight = systemTex.GetLevelDescription(0).Height; while (tiles.Count > 0) { SharpDX.Rectangle rect = tiles.Pop(); //texture2D.GetData<byte>(0, rect2, data, 0, data.Length); DataStream ds; //DataRectangle dr = texture2D.LockRectangle(0, rect2, LockFlags.ReadOnly, out ds); DataRectangle dr = systemTex.LockRectangle(0, LockFlags.ReadOnly, out ds); //we have to go line by line.. ds.Seek(rect.Y * sysTexWidth * 4, SeekOrigin.Begin); int targetOffset = 0; int linesCount = tileHeight; int pixelsBefore = rect.X; int pixelsAfter = sysTexWidth - tileWidth - rect.X; while (linesCount-- > 0) { if (pixelsBefore > 0) ds.Seek(pixelsBefore * 4, SeekOrigin.Current); ds.Read(data, targetOffset, tileWidth * 4); targetOffset += tileWidth * 4; if (pixelsAfter > 0 && linesCount > 0) ds.Seek(pixelsAfter * 4, SeekOrigin.Current); } systemTex.UnlockRectangle(0); filename = file; if (multipleTiles) { filename = file.Replace(extension, "_" + sc.ToString("##00") + extension); } using (var stream = MyFileSystem.OpenWrite(MyFileSystem.UserDataPath, filename)) { using (System.Drawing.Bitmap image = new System.Drawing.Bitmap(tileWidth, tileHeight)) { System.Drawing.Imaging.BitmapData imageData = image.LockBits(new System.Drawing.Rectangle(0, 0, tileWidth, tileHeight), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); System.Runtime.InteropServices.Marshal.Copy(data, 0, imageData.Scan0, data.Length); if (extension == ".png") image.Save(stream, System.Drawing.Imaging.ImageFormat.Png); else if (extension == ".jpg" || extension == ".jpeg") image.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg); else if (extension == ".bmp") image.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp); else throw new InvalidOperationException("Invalid file extension: " + extension + ", please use png, jpg or bmp"); image.UnlockBits(imageData); } //texture2D.SaveAsPng(stream, texture2D.Width, texture2D.Height); //BaseTexture.ToStream(texture2D, ImageFileFormat.Png); } sc++; GC.Collect(); } } catch (Exception exc) { // Write exception to log, but continue as if nothing wrong happened MyRender.Log.WriteLine(exc); filename = null; } } //BaseTexture.ToFile(texture2D, "c:\\test.png", ImageFileFormat.Png); MyRender.Log.DecreaseIndent(); MyRender.Log.WriteLine("MyScreenshot.SaveTexture2D() - END"); return filename; }
public void SetDiffuseTexture(Texture dt) { m_D3DEffect.SetTexture(m_diffuseTexture, dt); SetHalfPixel(MyUtils.GetHalfPixel(dt.GetLevelDescription(0).Width, dt.GetLevelDescription(0).Height)); }
internal static void RenderLights() { PrepareLights(); RenderSpotShadows(); GetRenderProfiler().StartProfilingBlock("Render lights"); MyRender.SetRenderTarget(GetRenderTarget(MyRenderTargets.Auxiliary1), null, SetDepthTargetEnum.RestoreDefault); MyRender.GraphicsDevice.Clear(ClearFlags.Target, new SharpDX.ColorBGRA(0.0f), 1, 0); SetCorrectViewportSize(); if (MyRender.CurrentRenderSetup.EnableSmallLights.Value) { MyEffectPointLight effectPointLight = (MyEffectPointLight)MyRender.GetEffect(MyEffects.PointLight); SharpDX.Direct3D9.Texture diffuseRT = MyRender.GetRenderTarget(MyRenderTargets.Diffuse); effectPointLight.SetNormalsRT(MyRender.GetRenderTarget(MyRenderTargets.Normals)); effectPointLight.SetDiffuseRT(diffuseRT); effectPointLight.SetDepthsRT(MyRender.GetRenderTarget(MyRenderTargets.Depth)); effectPointLight.SetHalfPixel(diffuseRT.GetLevelDescription(0).Width, diffuseRT.GetLevelDescription(0).Height); effectPointLight.SetScale(GetScaleForViewport(diffuseRT)); var invViewProjMatrix = Matrix.Invert(MyRenderCamera.ViewProjectionMatrixAtZero); var invViewMatrix = Matrix.Invert(MyRenderCamera.ViewMatrixAtZero); effectPointLight.SetCameraPosition(Vector3.Zero); effectPointLight.SetViewMatrix(MyRenderCamera.ViewMatrixAtZero); effectPointLight.SetInvViewMatrix(invViewMatrix); DepthStencilState.None.Apply(); MyStateObjects.Light_Combination_BlendState.Apply(); //Render each light with a model specific to the light GetRenderProfiler().StartProfilingBlock("PointLight"); var cullRationSq = MyRenderConstants.DISTANCE_LIGHT_CULL_RATIO * MyRenderConstants.DISTANCE_LIGHT_CULL_RATIO; if (MyRender.Settings.EnablePointLights) { foreach (MyRenderLight light in m_pointLights) { var distanceSq = (MyRenderCamera.Position - light.PositionWithOffset).LengthSquared(); var hasVolumetricGlare = light.GlareOn && light.Glare.Type == MyGlareTypeEnum.Distant; var isTooFarAway = (light.Range * light.Range) < (distanceSq / cullRationSq); if (!isTooFarAway) { // Always cull clockwise (render inner parts of object), depth test is done is PS using light radius RasterizerState.CullClockwise.Apply(); effectPointLight.SetLightPosition((Vector3)(light.PositionWithOffset - MyRenderCamera.Position)); effectPointLight.SetLightIntensity(light.Intensity); effectPointLight.SetSpecularLightColor(light.SpecularColor); effectPointLight.SetFalloff(light.Falloff); effectPointLight.SetLightRadius(light.Range); effectPointLight.SetReflectorTexture(light.ReflectorTexture); effectPointLight.SetLightColor(light.Color.ToVector3()); effectPointLight.SetTechnique(effectPointLight.PointTechnique); MyDebugDraw.DrawSphereForLight(effectPointLight, light.PositionWithOffset, light.Range, ref Vector3.One, 1); MyPerformanceCounter.PerCameraDrawWrite.LightsCount++; } // if(!isTooFarAway || hasVolumetricGlare) // light.Draw(); } } GetRenderProfiler().EndProfilingBlock(); GetRenderProfiler().StartProfilingBlock("Hemisphere"); if (MyRender.Settings.EnablePointLights) { foreach (MyRenderLight light in m_hemiLights) { // compute bounding box //Vector3 center = light.Position;// - light.Range * new Vector3(0,1,0); //Vector3 extend = new Vector3(light.Range, light.Range, light.Range); //m_lightBoundingBox.Min = center - extend; //m_lightBoundingBox.Max = center + extend; // Always cull clockwise (render inner parts of object), depth test is done is PS using light radius if (Vector3D.Dot((Vector3D)light.ReflectorDirection, MyRenderCamera.Position - light.Position) > 0 && light.PointBoundingSphere.Contains(MyRenderCamera.Position) == VRageMath.ContainmentType.Contains) { RasterizerState.CullNone.Apply(); //zevnitr } else { RasterizerState.CullCounterClockwise.Apply(); //zvenku } effectPointLight.SetLightPosition((Vector3)(light.Position - MyRenderCamera.Position)); effectPointLight.SetLightIntensity(light.Intensity); effectPointLight.SetSpecularLightColor(light.SpecularColor); effectPointLight.SetFalloff(light.Falloff); effectPointLight.SetLightRadius(light.Range); effectPointLight.SetReflectorTexture(light.ReflectorTexture); effectPointLight.SetLightColor(light.Color.ToVector3()); effectPointLight.SetTechnique(effectPointLight.HemisphereTechnique); MatrixD world = MatrixD.CreateScale(light.Range) * MatrixD.CreateWorld(light.Position - MyRenderCamera.Position, light.ReflectorDirection, light.ReflectorUp); MyDebugDraw.DrawHemisphereForLight(effectPointLight, ref world, ref Vector3.One, 1); //light.Draw(); MyPerformanceCounter.PerCameraDrawWrite.LightsCount++; } } GetRenderProfiler().EndProfilingBlock(); GetRenderProfiler().StartProfilingBlock("Spotlight"); RenderSpotLights(m_spotLightRenderElements, effectPointLight); GetRenderProfiler().EndProfilingBlock(); foreach (var light in m_renderLightsForDraw) { light.Draw(); } } DepthStencilState.None.Apply(); RasterizerState.CullCounterClockwise.Apply(); MyStateObjects.Sun_Combination_BlendState.Apply(); GetRenderProfiler().StartProfilingBlock("Sun light"); if (Settings.EnableSun && CurrentRenderSetup.EnableSun.Value && MyRender.Sun.Direction != Vector3.Zero) { //Sun light MyEffectDirectionalLight effectDirectionalLight = MyRender.GetEffect(MyEffects.DirectionalLight) as MyEffectDirectionalLight; Texture diffuseRTSun = MyRender.GetRenderTarget(MyRenderTargets.Diffuse); effectDirectionalLight.SetNormalsRT(MyRender.GetRenderTarget(MyRenderTargets.Normals)); effectDirectionalLight.SetDiffuseRT(diffuseRTSun); effectDirectionalLight.SetDepthsRT(MyRender.GetRenderTarget(MyRenderTargets.Depth)); effectDirectionalLight.SetHalfPixelAndScale(diffuseRTSun.GetLevelDescription(0).Width, diffuseRTSun.GetLevelDescription(0).Height, GetScaleForViewport(diffuseRTSun)); effectDirectionalLight.SetCameraMatrix(Matrix.Invert(MyRenderCamera.ViewMatrixAtZero)); effectDirectionalLight.SetAmbientMinimumAndIntensity(new Vector4(AmbientColor * AmbientMultiplier, EnvAmbientIntensity)); effectDirectionalLight.SetTextureEnvironmentMain(MyEnvironmentMap.EnvironmentMainMap); effectDirectionalLight.SetTextureEnvironmentAux(MyEnvironmentMap.EnvironmentAuxMap); effectDirectionalLight.SetTextureAmbientMain(MyEnvironmentMap.AmbientMainMap); effectDirectionalLight.SetTextureAmbientAux(MyEnvironmentMap.AmbientAuxMap); effectDirectionalLight.SetTextureEnvironmentBlendFactor(MyEnvironmentMap.BlendFactor); effectDirectionalLight.SetCameraPosition(Vector3.Zero); //Set distance where no slope bias will be applied (because of cockpit artifacts) effectDirectionalLight.SetNearSlopeBiasDistance(3); effectDirectionalLight.ShowSplitColors(Settings.ShowCascadeSplits); effectDirectionalLight.SetShadowBias(MyRenderCamera.FieldOfView * 0.0001f * MyRenderConstants.RenderQualityProfile.ShadowBiasMultiplier); effectDirectionalLight.SetSlopeBias(0.00002f * MyRenderConstants.RenderQualityProfile.ShadowSlopeBiasMultiplier); effectDirectionalLight.SetSlopeCascadeMultiplier(20.0f); //100 makes artifacts in prefabs MyRender.GetShadowRenderer().SetupShadowBaseEffect(effectDirectionalLight); effectDirectionalLight.SetLightDirection(m_sun.Direction); effectDirectionalLight.SetLightColorAndIntensity(new Vector3(m_sun.Color.X, m_sun.Color.Y, m_sun.Color.Z), m_sun.Intensity); effectDirectionalLight.SetBacklightColorAndIntensity(new Vector3(m_sun.BackColor.X, m_sun.BackColor.Y, m_sun.BackColor.Z), m_sun.BackIntensity); //m_sun.SpecularColor = {X:0,9137255 Y:0,6078432 Z:0,2078431} //nice yellow effectDirectionalLight.SetSpecularLightColor(m_sun.SpecularColor); effectDirectionalLight.EnableCascadeBlending(MyRenderConstants.RenderQualityProfile.EnableCascadeBlending); effectDirectionalLight.SetFrustumCorners(MyRender.GetShadowRenderer().GetFrustumCorners()); effectDirectionalLight.SetEnableAmbientEnvironment(Settings.EnableEnvironmentMapAmbient && MyRenderConstants.RenderQualityProfile.EnableEnvironmentals && CurrentRenderSetup.EnableEnvironmentMapping.Value); effectDirectionalLight.SetEnableReflectionEnvironment(Settings.EnableEnvironmentMapReflection && MyRenderConstants.RenderQualityProfile.EnableEnvironmentals && CurrentRenderSetup.EnableEnvironmentMapping.Value); if (Settings.EnableShadows && MyRender.CurrentRenderSetup.ShadowRenderer != null) { effectDirectionalLight.SetTechnique(effectDirectionalLight.DefaultTechnique); } else { effectDirectionalLight.SetTechnique(effectDirectionalLight.DefaultWithoutShadowsTechnique); } GetFullscreenQuad().Draw(effectDirectionalLight); } GetRenderProfiler().EndProfilingBlock(); // var st = MyRender.GetRenderTarget(MyRenderTargets.ShadowMap); // Texture.ToFile(st, "c:\\sm.dds", ImageFileFormat.Dds); // Blend in background if (true) // blend background { GetRenderProfiler().StartProfilingBlock("Blend background"); //todo /*if (MyFakes.RENDER_PREVIEWS_WITH_CORRECT_ALPHA) * { * // for some reason the other option does not give 0 alpha for the background when rendering gui preview images * MyStateObjects.Additive_NoAlphaWrite_BlendState.Apply(); * } * else */ { MyStateObjects.NonPremultiplied_NoAlphaWrite_BlendState.Apply(); //BlendState.NonPremultiplied.Apply(); } DepthStencilState.None.Apply(); RasterizerState.CullCounterClockwise.Apply(); MyEffectBlendLights effectBlendLights = MyRender.GetEffect(MyEffects.BlendLights) as MyEffectBlendLights; Texture diffuseRT = GetRenderTarget(MyRenderTargets.Diffuse); MyRenderCamera.SetupBaseEffect(effectBlendLights, m_currentLodDrawPass, m_currentSetup.FogMultiplierMult); effectBlendLights.SetDiffuseTexture(diffuseRT); effectBlendLights.SetNormalTexture(GetRenderTarget(MyRenderTargets.Normals)); effectBlendLights.SetDepthTexture(GetRenderTarget(MyRenderTargets.Depth)); effectBlendLights.SetHalfPixel(diffuseRT.GetLevelDescription(0).Width, diffuseRT.GetLevelDescription(0).Height); effectBlendLights.SetScale(GetScaleForViewport(diffuseRT)); effectBlendLights.SetBackgroundTexture(GetRenderTarget(MyRenderTargets.Auxiliary0)); effectBlendLights.SetTechnique(effectBlendLights.DefaultTechnique); GetFullscreenQuad().Draw(effectBlendLights); GetRenderProfiler().EndProfilingBlock(); // Blend in emissive light, overwrite emissivity (alpha) GetRenderProfiler().StartProfilingBlock("Copy emisivity"); //todo // if (MyPostProcessHDR.RenderHDRThisFrame()) // MyStateObjects.AddEmissiveLight_BlendState.Apply(); // else MyStateObjects.AddEmissiveLight_NoAlphaWrite_BlendState.Apply(); effectBlendLights.SetTechnique(effectBlendLights.CopyEmissivityTechnique); GetFullscreenQuad().Draw(effectBlendLights); bool showDebugLighting = false; if (Settings.ShowSpecularIntensity) { effectBlendLights.SetTechnique(MyEffectBlendLights.Technique.OnlySpecularIntensity); showDebugLighting = true; } else if (Settings.ShowSpecularPower) { effectBlendLights.SetTechnique(MyEffectBlendLights.Technique.OnlySpecularPower); showDebugLighting = true; } else if (Settings.ShowEmissivity) { effectBlendLights.SetTechnique(MyEffectBlendLights.Technique.OnlyEmissivity); showDebugLighting = true; } else if (Settings.ShowReflectivity) { effectBlendLights.SetTechnique(MyEffectBlendLights.Technique.OnlyReflectivity); showDebugLighting = true; } if (showDebugLighting) { BlendState.Opaque.Apply(); GetFullscreenQuad().Draw(effectBlendLights); } GetRenderProfiler().EndProfilingBlock(); } //TakeScreenshot("Accumulated_lights", GetRenderTarget(MyRenderTargets.Lod0Depth), MyEffectScreenshot.ScreenshotTechniqueEnum.Default); /*TakeScreenshot("EnvironmentMap_1", GetRenderTargetCube(MyRenderTargets.EnvironmentCube), MyEffectScreenshot.ScreenshotTechniqueEnum.Default); * TakeScreenshot("EnvironmentMap_2", GetRenderTargetCube(MyRenderTargets.EnvironmentCubeAux), MyEffectScreenshot.ScreenshotTechniqueEnum.Default); * TakeScreenshot("AmbientMap_1", GetRenderTargetCube(MyRenderTargets.AmbientCube), MyEffectScreenshot.ScreenshotTechniqueEnum.Default); * TakeScreenshot("AmbientMap_2", GetRenderTargetCube(MyRenderTargets.AmbientCubeAux), MyEffectScreenshot.ScreenshotTechniqueEnum.Default); */ GetRenderProfiler().EndProfilingBlock(); }
public void SetDepthRT(Texture depthRT) { m_D3DEffect.SetTexture(m_depthRT, depthRT); m_D3DEffect.SetValue(m_halfPixel, MyUtilsRender9.GetHalfPixel(depthRT.GetLevelDescription(0).Width, depthRT.GetLevelDescription(0).Height)); }
internal static void DrawSpriteBatch(Texture texture, Vector2 normalizedCoord, Vector2 normalizedSize, Color color, MyGuiDrawAlignEnum drawAlign, Vector2 rightVector) { System.Diagnostics.Debug.Assert(m_spriteBatchUsageCount > 0); if (texture == null) return; if (m_screenshot != null && m_screenshot.IgnoreSprites) return; Vector2 screenCoord = GetScreenCoordinateFromNormalizedCoordinate(normalizedCoord); Vector2 screenSize = GetScreenSizeFromNormalizedSize(normalizedSize); screenCoord = GetAlignedCoordinate(screenCoord, screenSize, drawAlign); Vector2 origin; origin.X = texture.GetLevelDescription(0).Width / 2f; origin.Y = texture.GetLevelDescription(0).Height / 2f; //m_spriteBatch.Draw(texture, new DrawingRectangle((int)screenCoord.X, (int)screenCoord.Y, (int)screenSize.X, (int)screenSize.Y), null, SharpDXHelper.ToSharpDX(color), rotation, SharpDXHelper.ToSharpDX(origin), SpriteEffects.None, 0); RectangleF rect = new RectangleF(screenCoord.X, screenCoord.Y, screenSize.X, screenSize.Y); m_spriteBatch.DrawSprite(texture, null, ref rect, false, null, color, rightVector, ref origin, VRageRender.Graphics.SpriteEffects.None, 0); }
protected virtual void FinalizeAllocation(Texture texture, int fileWidth, int fileHeight) { lock (_syncObj) { if (texture != null) { if (_texture != null) { _texture.Dispose(); AllocationChanged(_allocationSize); } _texture = texture; SurfaceDescription desc = _texture.GetLevelDescription(0); _width = fileWidth; _height = fileHeight; _maxU = fileWidth / ((float)desc.Width); _maxV = fileHeight / ((float)desc.Height); _allocationSize = desc.Width * desc.Height * 4; AllocationChanged(_allocationSize); } } }
/// <summary> /// Draws sprite batch at specified position /// normalizedPosition -> X and Y are within interval <0..1> /// size -> size of destination rectangle (normalized). Don't forget that it may be distorted by aspect ration, so rectangle size [1,1] can make larger wide than height on your screen. /// rotation -> angle in radians. Rotation is always around "origin" coordinate /// originNormalized -> the origin of the sprite. Specify (0,0) for the upper-left corner. /// RETURN: Method returns rectangle where was sprite/texture drawn in normalized coordinates /// </summary> /// <returns></returns> public static void DrawSpriteBatch(Texture texture, Vector2 normalizedCoord, Vector2 normalizedSize, Color color, MyGuiDrawAlignEnum drawAlign, float rotation) { System.Diagnostics.Debug.Assert(m_spriteBatchUsageCount > 0); if (texture == null) return; Vector2 screenCoord = GetScreenCoordinateFromNormalizedCoordinate(normalizedCoord); Vector2 screenSize = GetScreenSizeFromNormalizedSize(normalizedSize); screenCoord = GetAlignedCoordinate(screenCoord, screenSize, drawAlign); Vector2 origin; origin.X = texture.GetLevelDescription(0).Width / 2f; origin.Y = texture.GetLevelDescription(0).Height / 2f; m_spriteBatch.Draw(texture, new DrawingRectangle((int)screenCoord.X, (int)screenCoord.Y, (int)screenSize.X, (int)screenSize.Y), null, SharpDXHelper.ToSharpDX(color), rotation, SharpDXHelper.ToSharpDX(origin), SpriteEffects.None, 0); //return new MyRectangle2D(GetNormalizedCoordinateFromScreenCoordinate(screenCoord), normalizedSize); }