public IUserGeneratedTexture CreateGeneratedTexture(string name, int width, int height, MyGeneratedTextureType type, int numMipLevels) { IGeneratedTexture texture; if (m_generatedTextures.TryGetValue(name, out texture)) { IUserGeneratedTexture userTexture = texture as IUserGeneratedTexture; if (userTexture == null) { MyRenderProxy.Fail("Trying to replace system texture"); return(null); } if (userTexture.Size.X != width || userTexture.Size.Y != height || userTexture.Type != type || userTexture.MipmapCount != numMipLevels) { MyRenderProxy.Fail("Trying to replace existing texture"); } return(userTexture); } var manager = MyManagers.GeneratedTextures; IUserGeneratedTexture ret = manager.NewUserTexture(name, width, height, type, numMipLevels); m_generatedTextures[name] = ret; return(ret); }
protected unsafe sealed override void RecordCommandsInternal(MyRenderableProxy proxy) { if (proxy.Material.Info.GeometryTextureRef.IsUsed) { MyRenderProxy.Fail(String.Format("Ensure all glass materials for model '{0}' are dynamic materials inside Environment.sbc", proxy.Mesh.Info.Name)); return; } MyTransparentMaterial material; if (!MyTransparentMaterials.TryGetMaterial(proxy.Material.Info.Name.String, out material)) { MyRenderProxy.Fail(String.Format("Missing transparent material '{0}'", proxy.Material.Info.Name)); return; } Stats.Draws++; MyRenderUtils.BindShaderBundle(RC, proxy.Shaders); SetProxyConstants(proxy); BindProxyGeometry(proxy, RC); ISrvBindable texture = MyManagers.FileTextures.GetTexture(material.Texture, MyFileTextureEnum.GUI, true); RC.PixelShader.SetSrv(0, texture); StaticGlassConstants glassConstants = new StaticGlassConstants(); var glassCB = MyCommon.GetObjectCB(sizeof(StaticGlassConstants)); RC.PixelShader.SetConstantBuffer(2, glassCB); var mapping = MyMapping.MapDiscard(glassCB); glassConstants.Color = material.Color; glassConstants.Reflective = material.Reflectivity; mapping.WriteAndPosition(ref glassConstants); mapping.Unmap(); var submesh = proxy.DrawSubmesh; if (proxy.InstanceCount == 0) { RC.DrawIndexed(submesh.IndexCount, submesh.StartIndex, submesh.BaseVertex); ++Stats.Instances; Stats.Triangles += submesh.IndexCount / 3; } else { RC.DrawIndexedInstanced(submesh.IndexCount, proxy.InstanceCount, submesh.StartIndex, submesh.BaseVertex, proxy.StartInstance); Stats.Instances += proxy.InstanceCount; Stats.Triangles += proxy.InstanceCount * submesh.IndexCount / 3; } }
public void OnDeviceInit() { MyFileTextureParams fileTexParams; bool ret = GetCorrectedFileTextureParams(out fileTexParams); //MyRenderProxy.Assert(ret, "It is not implemented mechanism, what to do, when none of the textures exist"); m_size = fileTexParams.Resolution; Texture2DDescription desc = new Texture2DDescription(); desc.ArraySize = m_listSubresourceFilenames.Count; desc.BindFlags = BindFlags.ShaderResource; desc.CpuAccessFlags = CpuAccessFlags.None; desc.Format = fileTexParams.Format; desc.Height = (int)Size.Y; desc.Width = (int)Size.X; var mipmaps = desc.MipLevels = fileTexParams.Mipmaps; desc.SampleDescription.Count = 1; desc.SampleDescription.Quality = 0; desc.Usage = ResourceUsage.Default; m_resource = new Texture2D(MyRender11.Device, desc); m_resource.DebugName = m_resourceName; TextureFormat = fileTexParams.Format; // foreach mip int i = 0; foreach (var path in m_listSubresourceFilenames) { bool isUsedCreatedGeneratedTexture = false; ISrvBindable tex = MyManagers.FileTextures.GetTexture(path, m_type, true); var tex2D = tex.Resource as Texture2D; MyRenderProxy.Assert(tex2D != null, "MyFileArrayTexture supports only 2D textures. Inconsistent texture: " + tex.Name); bool consistent = MyResourceUtils.CheckTexturesConsistency(desc, tex2D.Description); if (!consistent) { if (!string.IsNullOrEmpty(path) && MyFileSystem.FileExists(path)) { string msg = string.Format( "Texture {0} cannot be loaded. If this message is displayed on reloading textures, please restart the game. If it is not, please notify developers.", path); MyRenderProxy.Fail(msg); } } if (!consistent && m_recoverySystem.UseErrorTexture) // if the texture cannot be used, error texture will be used { tex = MyManagers.FileTextures.GetTexture(m_recoverySystem.TextureFilepath, m_type, true); tex2D = tex.Resource as Texture2D; MyRenderProxy.Assert(tex2D != null, "MyFileArrayTexture supports only 2D textures. Inconsistent texture: " + m_recoverySystem.TextureFilepath); consistent = MyResourceUtils.CheckTexturesConsistency(desc, tex2D.Description); } if (!consistent && m_recoverySystem.UseBytePattern) // if the texture cannot be used, byte pattern will be used to generate texture { tex = MyManagers.GeneratedTextures.CreateFromBytePattern("MyFileArrayTexture.Tmp", desc.Width, desc.Height, m_recoverySystem.FormatBytePattern, m_recoverySystem.BytePattern); tex2D = tex.Resource as Texture2D; MyRenderProxy.Assert(tex2D != null); consistent = MyResourceUtils.CheckTexturesConsistency(desc, tex2D.Description); isUsedCreatedGeneratedTexture = true; } if (!consistent) { Texture2DDescription desc1 = desc; Texture2DDescription desc2 = tex2D.Description; string errorMsg = string.Format("Textures ({0}) is not compatible within array texture! Width: ({1},{2}) Height: ({3},{4}) Mipmaps: ({5},{6}) Format: ({7},{8})", path, desc1.Width, desc2.Width, desc1.Height, desc2.Height, desc1.MipLevels, desc2.MipLevels, desc1.Format, desc2.Format); MyRenderProxy.Error(errorMsg); MyRender11.Log.WriteLine(errorMsg); } for (int m = 0; m < mipmaps; m++) { MyRender11.RC.CopySubresourceRegion(tex, Resource.CalculateSubResourceIndex(m, 0, mipmaps), null, Resource, Resource.CalculateSubResourceIndex(m, i, mipmaps)); int sizeX = Resource.CalculateMipSize(m, Size.X); int sizeY = Resource.CalculateMipSize(m, Size.Y); ByteSize += FormatHelper.ComputeScanlineCount(TextureFormat, sizeX) * 4 * FormatHelper.ComputeScanlineCount(TextureFormat, sizeY) * 4 * FormatHelper.SizeOfInBytes(TextureFormat); } if (isUsedCreatedGeneratedTexture) { IGeneratedTexture generatedTex = (IGeneratedTexture)tex; MyManagers.GeneratedTextures.DisposeTex(generatedTex); } i++; } m_srv = new ShaderResourceView(MyRender11.Device, Resource); }
static bool GatherInternal() { m_batches.Clear(); // counting sorted billboards ClearBucketCounts(); PreGatherList(MyRenderProxy.BillboardsRead); PreGatherList(m_billboardsOnce); int billboardCount = 0; for (int j = 0; j < BUCKETS_COUNT; j++) { billboardCount += m_bucketCounts[j]; } if (billboardCount == 0) { return(false); } m_billboardCountSafe = billboardCount > MAX_BILLBOARDS_SIZE ? MAX_BILLBOARDS_SIZE : billboardCount; InitGatherList(billboardCount, m_billboardCountSafe); InitBucketIndices(); GatherList(MyRenderProxy.BillboardsRead); GatherList(m_billboardsOnce); InitBucketIndices(); int i; for (i = 0; i < BUCKETS_COUNT; i++) { Array.Sort(m_tempBuffer, m_bucketIndices[i], m_bucketCounts[i]); } bool resetBindings = false; int currentOffset = 0; ISrvBindable prevTex = null; MyTransparentMaterial prevMaterial = null; for (i = 0; i < m_billboardCountSafe; i++) { MyBillboard billboard = m_tempBuffer[i]; MyTransparentMaterial material = MyTransparentMaterials.GetMaterial(billboard.Material); ISrvBindable batchTex = null; if (material.UseAtlas) { var atlasItem = m_atlas.FindElement(material.Texture); batchTex = atlasItem.Texture; } else { MyFileTextureManager texManager = MyManagers.FileTextures; switch (material.TextureType) { case MyTransparentMaterialTextureType.FileTexture: if (material.Texture == null || !m_fileTextures.TryGetValue(material.Texture, out batchTex)) { batchTex = texManager.GetTexture(material.Texture, MyFileTextureEnum.GUI, true); if (material.Texture != null) { m_fileTextures.Add(material.Texture, batchTex); } else { MyRenderProxy.Fail("Material: " + material.Name + " is missing a texture."); } } break; case MyTransparentMaterialTextureType.RenderTarget: batchTex = MyRender11.DrawSpritesOffscreen(material.Name, material.TargetSize.X, material.TargetSize.Y); resetBindings = true; break; default: throw new Exception(); } } bool boundary = IsBucketBoundary(i); bool closeBatch = i > 0 && (batchTex != prevTex || boundary); if (closeBatch) { AddBatch(i, currentOffset, prevTex, prevMaterial); currentOffset = i; } var billboardData = new MyBillboardData(); var billboardVertices = new MyBillboardVertexData(); billboardData.CustomProjectionID = billboard.CustomViewProjection; billboardData.Color = billboard.Color; billboardData.Color.X *= billboard.ColorIntensity; billboardData.Color.Y *= billboard.ColorIntensity; billboardData.Color.Z *= billboard.ColorIntensity; billboardData.AlphaCutout = billboard.AlphaCutout; billboardData.AlphaSaturation = material.AlphaSaturation; billboardData.SoftParticleDistanceScale = billboard.SoftParticleDistanceScale * material.SoftParticleDistanceScale; billboardData.Reflective = billboard.Reflectivity; Vector3D pos0 = billboard.Position0; Vector3D pos1 = billboard.Position1; Vector3D pos2 = billboard.Position2; Vector3D pos3 = billboard.Position3; if (billboard.ParentID != -1) { var parent = MyIDTracker <MyActor> .FindByID((uint)billboard.ParentID); if (parent != null) { var matrix = parent.WorldMatrix; Vector3D.Transform(ref pos0, ref matrix, out pos0); Vector3D.Transform(ref pos1, ref matrix, out pos1); Vector3D.Transform(ref pos2, ref matrix, out pos2); Vector3D.Transform(ref pos3, ref matrix, out pos3); } } MyEnvironmentMatrices envMatrices = MyRender11.Environment.Matrices; if (MyStereoRender.Enable) { if (MyStereoRender.RenderRegion == MyStereoRegion.LEFT) { envMatrices = MyStereoRender.EnvMatricesLeftEye; } else if (MyStereoRender.RenderRegion == MyStereoRegion.RIGHT) { envMatrices = MyStereoRender.EnvMatricesRightEye; } } if (billboard.CustomViewProjection == -1) { pos0 -= envMatrices.CameraPosition; pos1 -= envMatrices.CameraPosition; pos2 -= envMatrices.CameraPosition; pos3 -= envMatrices.CameraPosition; } var normal = Vector3D.Cross(pos1 - pos0, pos2 - pos0); normal.Normalize(); billboardData.Normal = normal; billboardVertices.V0.Position = pos0; billboardVertices.V1.Position = pos1; billboardVertices.V2.Position = pos2; billboardVertices.V3.Position = pos3; var uv0 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y); var uv1 = new Vector2(material.UVOffset.X + material.UVSize.X * billboard.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y); var uv2 = new Vector2(material.UVOffset.X + material.UVSize.X * billboard.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y + material.UVSize.Y * billboard.UVSize.Y); var uv3 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y + material.UVSize.Y * billboard.UVSize.Y); if (material.UseAtlas) { var atlasItem = m_atlas.FindElement(material.Texture); uv0 = uv0 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv1 = uv1 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv2 = uv2 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv3 = uv3 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); } billboardVertices.V0.Texcoord = new HalfVector2(uv0); billboardVertices.V1.Texcoord = new HalfVector2(uv1); billboardVertices.V2.Texcoord = new HalfVector2(uv2); billboardVertices.V3.Texcoord = new HalfVector2(uv3); pos0.AssertIsValid(); pos1.AssertIsValid(); pos2.AssertIsValid(); pos3.AssertIsValid(); MyTriangleBillboard triBillboard = billboard as MyTriangleBillboard; if (triBillboard != null) { billboardVertices.V3.Position = pos2; // second triangle will die in rasterizer billboardVertices.V0.Texcoord = new HalfVector2(triBillboard.UV0); billboardVertices.V1.Texcoord = new HalfVector2(triBillboard.UV1); billboardVertices.V2.Texcoord = new HalfVector2(triBillboard.UV2); billboardData.Normal = triBillboard.Normal0; } m_arrayDataBillboards.Data[i] = billboardData; m_arrayDataBillboards.Vertex[i] = billboardVertices; prevTex = batchTex; prevMaterial = material; } AddBatch(m_billboardCountSafe, currentOffset, prevTex, prevMaterial); TransferDataCustomProjections(); TransferDataBillboards(0, m_billboardCountSafe, ref m_arrayDataBillboards); return(resetBindings); }
public static void Run(IRtvBindable target, ICustomTexture fxaaTarget, IDepthStencil depthStencilCopy) { if (!HasHighlights) { return; } ProfilerShort.Begin("MyHighlight.Run"); MyGpuProfiler.IC_BeginBlock("MyHighlight.Run"); // set resolved depth/ stencil // render all with proper depth-stencil state // blur // blend to main target testing with stencil again MyHighlightPass.Instance.ViewProjection = MyRender11.Environment.Matrices.ViewProjectionAt0; MyHighlightPass.Instance.Viewport = new MyViewport(MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y); MyHighlightPass.Instance.PerFrame(); MyHighlightPass.Instance.Begin(); int samples = MyRender11.Settings.User.AntialiasingMode.SamplesCount(); IBorrowedRtvTexture rgba8_1 = MyManagers.RwTexturesPool.BorrowRtv("MyHighlight.Rgba8_1", Format.R8G8B8A8_UNorm_SRgb, samples); RC.ClearRtv(rgba8_1, new SharpDX.Color4(0, 0, 0, 0)); RC.SetRtv(depthStencilCopy, MyDepthStencilAccess.DepthReadOnly, rgba8_1); foreach (var pair in m_highlights) { MyActor actor = MyIDTracker <MyActor> .FindByID(pair.Key); if (actor == null) { MyRenderProxy.Fail("The actor cannot be found for highlight. This bug is outside of the renderer."); continue; } MyRenderableComponent renderableComponent = actor.GetRenderable(); MyInstanceComponent instanceComponent = actor.GetInstance(); if (renderableComponent != null) { DrawRenderableComponent(actor, renderableComponent, pair.Value); } else if (instanceComponent != null) { DrawInstanceComponent(instanceComponent, pair.Value); } else { // If an actor has been removed without removing outlines, just remove the outlines too m_keysToRemove.Add(pair.Key); MyRenderProxy.Fail("The actor has been removed, but the highligh is still active. This bug is caused by the issue out of the renderer."); } } MyHighlightPass.Instance.End(); RC.SetBlendState(null); foreach (var outlineKey in m_keysToRemove) { m_highlights.Remove(outlineKey); } m_keysToRemove.Clear(); ISrvBindable initialSourceView = rgba8_1; IRtvBindable renderTargetview = rgba8_1; float maxThickness = 0f; foreach (var pair in m_highlights) { foreach (MyHighlightDesc descriptor in pair.Value) { maxThickness = Math.Max(maxThickness, descriptor.Thickness); } } if (maxThickness > 0) { IBorrowedRtvTexture rgba8_2 = MyManagers.RwTexturesPool.BorrowRtv("MyHighlight.Rgba8_2", Format.R8G8B8A8_UNorm_SRgb); MyBlur.Run(renderTargetview, rgba8_2, initialSourceView, (int)Math.Round(maxThickness), MyBlur.MyBlurDensityFunctionType.Exponential, 0.25f, MyDepthStencilStateManager.IgnoreDepthStencil); rgba8_2.Release(); } MyGpuProfiler.IC_EndBlock(); ProfilerShort.End(); BlendHighlight(target, rgba8_1, fxaaTarget, depthStencilCopy); }
bool IsModelSuitable(MyMwmData mwmData) { if (mwmData.HasBones) { return(false); } if (!mwmData.IsValid2ndStream) { return(false); } foreach (var partInfo in mwmData.PartInfos) { if (partInfo.m_MaterialDesc == null) { continue; } string materialName = partInfo.m_MaterialDesc.MaterialName; if (m_blackListMaterials.Contains(materialName)) { return(false); } switch (partInfo.m_MaterialDesc.Facing) { case MyFacingEnum.None: break; default: return(false); } switch (partInfo.Technique) { case MyMeshDrawTechnique.MESH: case MyMeshDrawTechnique.ALPHA_MASKED: case MyMeshDrawTechnique.DECAL: case MyMeshDrawTechnique.DECAL_CUTOUT: case MyMeshDrawTechnique.DECAL_NOPREMULT: break; default: return(false); } } // The current model is fine, let's check the lods foreach (var lod in mwmData.Lods) { string filepath = lod.GetModelAbsoluteFilePath(mwmData.MwmFilepath); if (filepath == null) { string errMsg = string.Format("The table for lods is specified, but it is invalid (filepath for lod is missing). File: '{0}'", mwmData.MwmFilepath); MyRenderProxy.Fail(errMsg); MyRenderProxy.Log.WriteLine(errMsg); return(false); } MyMwmData lodMwmData = new MyMwmData(); if (lodMwmData.LoadFromFile(filepath)) { bool isSuitable = IsModelSuitable(lodMwmData); if (!isSuitable) { return(false); } } } return(true); }