ISrvBindable CreateNewTexture(Vector2I resolution) { string debugName = string.Format("Debug-mipmap-{0}x{1}", resolution.X, resolution.Y); int mipmapLevels = MyResourceUtils.GetMipmapsCount(Math.Max(resolution.X, resolution.Y)); resolution.X = MyResourceUtils.GetMipmapStride(resolution.X, 0); // this is required by texture compression resolution.Y = MyResourceUtils.GetMipmapStride(resolution.Y, 0); // this is required by texture compression ISrvTexture dstTex = MyManagers.RwTextures.CreateSrv(debugName, resolution.X, resolution.Y, Format.BC7_UNorm_SRgb, mipmapLevels: mipmapLevels); for (int i = 0; i < mipmapLevels; i++) { ISrvBindable srcTex = m_fileTextures[i % m_fileTextures.Length]; Vector2I mipmapResolution = new Vector2I(MyResourceUtils.GetMipmapSize(resolution.X, i), MyResourceUtils.GetMipmapSize(resolution.Y, i)); for (int x = 0; x < mipmapResolution.X; x += srcTex.Size.X) { for (int y = 0; y < mipmapResolution.Y; y += srcTex.Size.Y) { MyRender11.RC.CopySubresourceRegion(srcTex, 0, null, dstTex, i, x, y); } } } return(dstTex); }
public void OnDeviceInit() { ISrvBindable firstTex = MyManagers.FileTextures.GetTexture(m_listSubresourceFilenames[0], m_type, true); var srcDesc = firstTex.Srv.Description; Vector2I Size = firstTex.Size; Texture2DDescription desc = new Texture2DDescription(); desc.ArraySize = m_listSubresourceFilenames.Count; desc.BindFlags = BindFlags.ShaderResource; desc.CpuAccessFlags = CpuAccessFlags.None; desc.Format = srcDesc.Format; desc.Height = (int)Size.Y; desc.Width = (int)Size.X; desc.MipLevels = srcDesc.Texture2D.MipLevels; 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 = srcDesc.Format; // foreach mip var mipmaps = srcDesc.Texture2D.MipLevels; int i = 0; foreach (var path in m_listSubresourceFilenames) { ISrvBindable tex = MyManagers.FileTextures.GetTexture(path, m_type, true); var tex2D = tex.Resource as Texture2D; MyRenderProxy.Assert(tex2D != null, "MyTextureArray supports only 2D textures. Inconsistent texture: " + tex.Name); bool consistent = MyResourceUtils.CheckTexturesConsistency(desc, tex2D.Description); if (!consistent) { string errorMsg = "All MyTextureArray has to have the same pixel format, width / height and # of mipmaps. Inconsistent textures: " + tex.Name + " / " + firstTex.Name; MyRenderProxy.Error(errorMsg); MyRender11.Log.WriteLine(errorMsg); } for (int m = 0; m < mipmaps; m++) { MyRender11.RC.CopySubresourceRegion(tex2D, 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); } i++; } m_srv = new ShaderResourceView(MyRender11.Device, Resource); }
IDynamicFileArrayTexture GetArrayTextureFromFilepath(string filepath, MyChannel channel, Vector2I defaultResolution) { MyFileTextureParams textureParams; MyArrayTextureKey key; key.Channel = channel; bool isLoaded = MyFileTextureParamsManager.LoadFromFile(filepath, out textureParams); if (isLoaded) { Format format; format = textureParams.Format; if (MyCompilationSymbols.ReinterpretFormatsStoredInFiles) { if (channel != MyChannel.NormalGloss) { format = MyResourceUtils.MakeSrgb(format); } } key.Format = format; key.ResolutionInFile = textureParams.Resolution; key.MipmapsCount = textureParams.Mipmaps; } else { Format format; switch (channel) { case MyChannel.ColorMetal: format = Format.BC7_UNorm_SRgb; break; case MyChannel.NormalGloss: format = Format.BC7_UNorm; break; case MyChannel.Extension: format = Format.BC7_UNorm_SRgb; break; case MyChannel.Alphamask: format = Format.BC4_UNorm; break; default: MyRenderProxy.Assert(false); format = Format.Unknown; break; } key.Format = format; key.ResolutionInFile = defaultResolution; key.MipmapsCount = MyResourceUtils.GetMipmapsCount(Math.Max(key.ResolutionInFile.X, key.ResolutionInFile.Y)); } return(GetArrayTextureFromKey(key)); }
public static string GetAlphamaskTexture(MyMeshPartInfo mwmPart, string contentPath) { if (mwmPart.m_MaterialDesc == null) { return(""); } var relativePath = mwmPart.m_MaterialDesc.Textures.Get("AlphamaskTexture", ""); return(MyResourceUtils.GetTextureFullPath(relativePath, contentPath)); }
public int GetOrAddSlice(string filepath) { filepath = MyResourceUtils.GetTextureFullPath(filepath); if (m_lookupTable.ContainsKey(filepath)) { return(m_lookupTable[filepath]); } int sliceNum = m_filepaths.Count; m_lookupTable.Add(filepath, sliceNum); m_filepaths.Add(filepath); m_dirtyFlag = true; return(sliceNum); }
public Vector4I[] CreateTextureIndices(List <MyMeshPartInfo> partInfos, int verticesNum, string contentPath) { Vector4I[] indices = new Vector4I[verticesNum]; for (int i = 0; i < verticesNum; i++) { indices[i] = new Vector4I(DEFAULT_ARRAY_TEXTURE_INDEX, DEFAULT_ARRAY_TEXTURE_INDEX, DEFAULT_ARRAY_TEXTURE_INDEX, DEFAULT_ARRAY_TEXTURE_INDEX); } if (!MyRender11.Settings.UseGeometryArrayTextures) // system is disabled { return(indices); } foreach (MyMeshPartInfo partInfo in partInfos) { MyMaterialDescriptor materialDesc = partInfo.m_MaterialDesc; if (materialDesc == null) { continue; } string cmTexture, ngTexture, extTexture, alphamaskTexture; if (!materialDesc.Textures.TryGetValue("ColorMetalTexture", out cmTexture)) { continue; } if (!materialDesc.Textures.TryGetValue("NormalGlossTexture", out ngTexture)) { continue; } materialDesc.Textures.TryGetValue("AddMapsTexture", out extTexture); materialDesc.Textures.TryGetValue("AlphamaskTexture", out alphamaskTexture); cmTexture = MyResourceUtils.GetTextureFullPath(cmTexture, contentPath); ngTexture = MyResourceUtils.GetTextureFullPath(ngTexture, contentPath); extTexture = MyResourceUtils.GetTextureFullPath(extTexture, contentPath); alphamaskTexture = MyResourceUtils.GetTextureFullPath(alphamaskTexture, contentPath); Vector4I textureIndices = GetTextureIndices(cmTexture, ngTexture, extTexture, alphamaskTexture); foreach (var offset in partInfo.m_indices) { indices[offset] = textureIndices; } } return(indices); }
internal static MyMeshMaterialId GetMaterialId(string name, string contentPath, string colorMetalTexture, string normalGlossTexture, string extensionTexture, string technique) { MyMeshMaterialInfo desc; desc = new MyMeshMaterialInfo { Name = X.TEXT_(name), ColorMetal_Texture = MyResourceUtils.GetTextureFullPath(colorMetalTexture, contentPath), NormalGloss_Texture = MyResourceUtils.GetTextureFullPath(normalGlossTexture, contentPath), Extensions_Texture = MyResourceUtils.GetTextureFullPath(extensionTexture, contentPath), Alphamask_Texture = String.Empty, Technique = ConvertToDrawTechnique(technique), TextureTypes = GetMaterialTextureTypes(colorMetalTexture, normalGlossTexture, extensionTexture, null), Facing = MyFacingEnum.None, }; return(GetMaterialId(ref desc)); }
unsafe void InitDxObjects(string name, Vector2I size, Format format, byte[] bytePattern) { Texture2DDescription desc = new Texture2DDescription(); desc.Format = format; desc.ArraySize = 1; desc.Height = size.Y; desc.Width = size.X; desc.MipLevels = MyResourceUtils.GetMipmapsCount(Math.Max(size.X, size.Y)); desc.BindFlags = BindFlags.ShaderResource; desc.CpuAccessFlags = CpuAccessFlags.None; desc.OptionFlags = ResourceOptionFlags.None; desc.Usage = ResourceUsage.Immutable; desc.SampleDescription = new SampleDescription(1, 0); Vector2I strides0; strides0.X = MyResourceUtils.GetMipmapStride(desc.Width, 0); strides0.Y = MyResourceUtils.GetMipmapStride(desc.Height, 0); byte[] dataBoxData = CreateTextureDataByPattern(strides0, bytePattern); DataBox[] dataBoxes = new DataBox[desc.MipLevels]; int blocksOffset = 0; fixed(void *ptr = dataBoxData) { for (int i = 0; i < dataBoxes.Length; i++) { dataBoxes[i].SlicePitch = 0; dataBoxes[i].RowPitch = MyResourceUtils.GetMipmapStride(size.X, i) * bytePattern.Length / 16; dataBoxes[i].DataPointer = new IntPtr(((byte *)ptr) + blocksOffset * bytePattern.Length); Vector2I blocksInMipmap; blocksInMipmap.X = MyResourceUtils.GetMipmapStride(size.X, i) / 4; blocksInMipmap.Y = MyResourceUtils.GetMipmapStride(size.Y, i) / 4; blocksOffset += blocksInMipmap.X * blocksInMipmap.Y; } m_resource = new Texture2D(MyRender11.Device, desc, dataBoxes); m_resource.DebugName = name; } m_srv = new ShaderResourceView(MyRender11.Device, m_resource); m_srv.DebugName = name; }
byte[] CreateTextureDataByPattern(Vector2I strides, byte[] pattern4x4) { MyRenderProxy.Assert(strides.X % 4 == 0); MyRenderProxy.Assert(strides.Y % 4 == 0); int blocksCount = 0; for (int i = 0; i < MyResourceUtils.GetMipmapsCount(Math.Max(strides.X, strides.Y)); i++) { Vector2I blocksInMipmap; blocksInMipmap.X = MyResourceUtils.GetMipmapStride(strides.X, i); blocksInMipmap.Y = MyResourceUtils.GetMipmapStride(strides.Y, i); blocksCount += blocksInMipmap.X * blocksInMipmap.Y / 16; } byte[] data = new byte[blocksCount * pattern4x4.Length]; for (int i = 0; i < blocksCount; i++) { Array.Copy(pattern4x4, 0, data, pattern4x4.Length * i, pattern4x4.Length); } return(data); }
public static MyMeshMaterialInfo ConvertImportDescToMeshMaterialInfo(MyMaterialDescriptor importDesc, string contentPath, string assetFile = null) { string colorMetalTexture = importDesc.Textures.Get("ColorMetalTexture", ""); string normalGlossTexture = importDesc.Textures.Get("NormalGlossTexture", ""); string extensionTexture = importDesc.Textures.Get("AddMapsTexture", ""); string alphamaskTexture = importDesc.Textures.Get("AlphamaskTexture", null); MyMeshMaterialInfo info = new MyMeshMaterialInfo { Name = X.TEXT_(importDesc.MaterialName), ColorMetal_Texture = MyResourceUtils.GetTextureFullPath(colorMetalTexture, contentPath), NormalGloss_Texture = MyResourceUtils.GetTextureFullPath(normalGlossTexture, contentPath), Extensions_Texture = MyResourceUtils.GetTextureFullPath(extensionTexture, contentPath), Alphamask_Texture = MyResourceUtils.GetTextureFullPath(alphamaskTexture, contentPath), TextureTypes = GetMaterialTextureTypes(colorMetalTexture, normalGlossTexture, extensionTexture, alphamaskTexture), Technique = ConvertToDrawTechnique(importDesc.Technique), Facing = importDesc.Facing, WindScaleAndFreq = importDesc.WindScaleAndFreq }; return(info); }
// if no file texture can be loaded, the function will return false and default value in parameters bool GetCorrectedFileTextureParams(out MyFileTextureParams parameters) { //parameters = new MyFileTextureParams(); foreach (string filepath in m_listSubresourceFilenames) { if (MyFileTextureParamsManager.LoadFromFile(filepath, out parameters)) { if (MyCompilationSymbols.ReinterpretFormatsStoredInFiles) { if (m_type != MyFileTextureEnum.NORMALMAP_GLOSS) { parameters.Format = MyResourceUtils.MakeSrgb(parameters.Format); } } int skipMipmaps = 0; if (m_type != MyFileTextureEnum.GUI && m_type != MyFileTextureEnum.GPUPARTICLES) { skipMipmaps = MyRender11.RenderSettings.TextureQuality.MipmapsToSkip(parameters.Resolution.X, parameters.Resolution.Y); } if (parameters.Mipmaps > 1) { parameters.Mipmaps -= skipMipmaps; parameters.Resolution.X = MyResourceUtils.GetMipmapSize(parameters.Resolution.X, skipMipmaps); parameters.Resolution.Y = MyResourceUtils.GetMipmapSize(parameters.Resolution.Y, skipMipmaps); } return(true); } } parameters.Format = m_recoverySystem.FormatBytePattern; parameters.Mipmaps = 3; parameters.Resolution = new Vector2I(4, 4); parameters.ArraySize = 1; return(false); }
public void Load() { if (TextureState == FileTextureState.Loaded) { return; } string path = Path.Combine(MyFileSystem.ContentPath, Name); Debug.Assert(m_resource == null); Debug.Assert(m_srv == null, "Texture " + Name + " in invalid state"); Image img = null; if (MyFileSystem.FileExists(path)) { try { using (var s = MyFileSystem.OpenRead(path)) { img = Image.Load(s); m_imageFormatInFile = img.Description.Format; } } catch (Exception e) { MyRender11.Log.WriteLine("Error while loading texture: " + path + ", exception: " + e); } } bool loaded = false; if (img != null) { int skipMipmaps = (m_type != MyFileTextureEnum.GUI && m_type != MyFileTextureEnum.GPUPARTICLES && img.Description.MipLevels > 1) ? MyRender11.RenderSettings.TextureQuality.MipmapsToSkip(img.Description.Width, img.Description.Height) : 0; if (m_skipQualityReduction) { skipMipmaps = 0; } int totalSize = 0; int targetMipmaps = img.Description.MipLevels - skipMipmaps; var mipmapsData = new DataBox[(img.Description.MipLevels - skipMipmaps) * img.Description.ArraySize]; long delta = 0; int lastSize = 0; for (int z = 0; z < img.Description.ArraySize; z++) { for (int i = 0; i < targetMipmaps; i++) { var pixels = img.GetPixelBuffer(z, i + skipMipmaps); mipmapsData[Resource.CalculateSubResourceIndex(i, z, targetMipmaps)] = new DataBox { DataPointer = pixels.DataPointer, RowPitch = pixels.RowStride }; delta = pixels.DataPointer.ToInt64() - img.DataPointer.ToInt64(); lastSize = pixels.BufferStride; totalSize += lastSize; } } var targetWidth = img.Description.Width >> skipMipmaps; var targetHeight = img.Description.Height >> skipMipmaps; bool overwriteFormatToSrgb = (m_type != MyFileTextureEnum.NORMALMAP_GLOSS) && !FormatHelper.IsSRgb(img.Description.Format); var desc = new Texture2DDescription { MipLevels = targetMipmaps, Format = overwriteFormatToSrgb ? MyResourceUtils.MakeSrgb(img.Description.Format) : img.Description.Format, Height = targetHeight, Width = targetWidth, ArraySize = img.Description.ArraySize, BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, Usage = ResourceUsage.Immutable, SampleDescription = new SampleDescription { Count = 1, Quality = 0 }, OptionFlags = img.Description.Dimension == TextureDimension.TextureCube ? ResourceOptionFlags.TextureCube : ResourceOptionFlags.None }; try { m_resource = new Texture2D(MyRender11.Device, desc, mipmapsData); m_size = new Vector2I(targetWidth, targetHeight); //m_skippedMipmaps = skipMipmaps; m_fileExists = true; m_byteSize = totalSize; m_ownsData = true; m_srv = new ShaderResourceView(MyRender11.Device, m_resource); m_resource.DebugName = m_name; m_srv.DebugName = m_name; img.Dispose(); loaded = true; } catch (SharpDXException) { img.Dispose(); } } if (!loaded) { ISrvBindable replacingTexture = MyGeneratedTextureManager.ZeroTex; switch (m_type) { case MyFileTextureEnum.NORMALMAP_GLOSS: replacingTexture = MyGeneratedTextureManager.MissingNormalGlossTex; break; case MyFileTextureEnum.EXTENSIONS: replacingTexture = MyGeneratedTextureManager.MissingExtensionTex; break; case MyFileTextureEnum.ALPHAMASK: replacingTexture = MyGeneratedTextureManager.MissingAlphamaskTex; break; case MyFileTextureEnum.CUBEMAP: replacingTexture = MyGeneratedTextureManager.MissingCubeTex; break; } MyRender11.Log.WriteLine("Could not load texture: " + path); m_srv = replacingTexture.Srv; m_resource = replacingTexture.Resource; m_size = replacingTexture.Size; m_ownsData = false; m_fileExists = false; m_byteSize = 0; MyRender11.Log.WriteLine("Missing or invalid texture: " + Name); } TextureState = FileTextureState.Loaded; }
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); }