//---------------------------------------------------------------------------- public static PKFxManagerImpl.EImageFormat ResolveImageFormat(Texture2D t, ref byte[] data) { if (t.format == TextureFormat.DXT1) { return(PKFxManagerImpl.EImageFormat.DXT1); } else if (t.format == TextureFormat.DXT5) { return(PKFxManagerImpl.EImageFormat.DXT5); } else if (t.format == TextureFormat.ARGB32) { PKImageConverter.ARGB2BGRA(ref data); return(PKFxManagerImpl.EImageFormat.BGRA8); } else if (t.format == TextureFormat.RGBA32) { PKImageConverter.RGBA2BGRA(ref data); return(PKFxManagerImpl.EImageFormat.BGRA8); } else if (t.format == TextureFormat.BGRA32) { return(PKFxManagerImpl.EImageFormat.BGRA8); } else if (t.format == TextureFormat.RGB24) { PKImageConverter.RGB2BGR(ref data); return(PKFxManagerImpl.EImageFormat.BGR8); } else if (t.format == TextureFormat.PVRTC_RGB4) { return(PKFxManagerImpl.EImageFormat.RGB4_PVRTC1); } else if (t.format == TextureFormat.PVRTC_RGBA4) { return(PKFxManagerImpl.EImageFormat.RGBA4_PVRTC1); } else if (t.format == TextureFormat.PVRTC_RGB2) { return(PKFxManagerImpl.EImageFormat.RGB2_PVRTC1); } else if (t.format == TextureFormat.PVRTC_RGBA2) { return(PKFxManagerImpl.EImageFormat.RGBA2_PVRTC1); } else if (t.format == TextureFormat.ETC_RGB4) { return(PKFxManagerImpl.EImageFormat.RGB8_ETC1); } else if (t.format == TextureFormat.ETC2_RGB) { return(PKFxManagerImpl.EImageFormat.RGB8_ETC2); } else if (t.format == TextureFormat.ETC2_RGBA8) { return(PKFxManagerImpl.EImageFormat.RGBA8_ETC2); } else if (t.format == TextureFormat.ETC2_RGBA1) { return(PKFxManagerImpl.EImageFormat.RGB8A1_ETC2); } else if (t.format == TextureFormat.RGBAFloat) { return(PKFxManagerImpl.EImageFormat.Fp32_RGBA); } else { Debug.LogError("[PKFX] " + t.name + " texture format not supported : " + t.format); return(PKFxManagerImpl.EImageFormat.Invalid); } }
public void UpdateAttributes(bool forceUpdate) { int attrCount = -1; int smpCount = -1; if (m_FxAttributesList.Count <= 0 && m_FxSamplersList.Count <= 0) { return; } AllocAttributesCacheIFN(); AllocCurvesDataCacheIFN(); // Attributes for (int i = 0; i < m_FxAttributesList.Count; i++) { PKFxManager.Attribute srcAttr = m_FxAttributesList[i]; bool wasChanged = m_AttributesCache[i].m_Value0 != srcAttr.m_Value0 || m_AttributesCache[i].m_Value1 != srcAttr.m_Value1 || m_AttributesCache[i].m_Value2 != srcAttr.m_Value2 || m_AttributesCache[i].m_Value3 != srcAttr.m_Value3; if (wasChanged || forceUpdate || m_ForceUpdateAttributes) { m_AttributesCache[i].m_Type = (int)(m_FxAttributesList[i].m_Descriptor.Type); m_AttributesCache[i].m_Value0 = srcAttr.m_Value0; m_AttributesCache[i].m_Value1 = srcAttr.m_Value1; m_AttributesCache[i].m_Value2 = srcAttr.m_Value2; m_AttributesCache[i].m_Value3 = srcAttr.m_Value3; attrCount = i; } } if (attrCount >= 0) { if (!PKFxManager.EffectSetAttributes(this.m_FXGUID, attrCount + 1, this.m_AttributesHandler)) { Debug.LogError("[PKFX] Attribute through pinned memory failed."); Debug.LogError("[PKFX] Did you try to change an FX without stopping it beforehand?"); } } // Samplers int samplerCurveOffset = 0; for (int i = 0; i < m_FxSamplersList.Count; i++) { PKFxManager.Sampler srcAttr = m_FxSamplersList[i]; int smpType = (int)(m_FxSamplersList[i].m_Descriptor.Type); Vector3 smpPos = new Vector3(m_SamplersCache[i].m_PosX, m_SamplersCache[i].m_PosY, m_SamplersCache[i].m_PosZ); Vector3 smpEul = new Vector3(m_SamplersCache[i].m_EulX, m_SamplersCache[i].m_EulY, m_SamplersCache[i].m_EulZ); Vector3 smpSize = new Vector3(m_SamplersCache[i].m_SizeX, m_SamplersCache[i].m_SizeY, m_SamplersCache[i].m_SizeZ); bool wasChanged; m_SamplersCache[i].m_Type1 = smpType; if (m_SamplersCache[i].m_Type1 == (int)PKFxManager.ESamplerType.SamplerShape) { bool isMesh = (srcAttr.m_ShapeType == (int)PKFxManager.EShapeType.MeshShape || srcAttr.m_ShapeType == (int)PKFxManager.EShapeType.SkinnedMeshShape); bool withSkinning = srcAttr.m_ShapeType == (int)PKFxManager.EShapeType.SkinnedMeshShape && srcAttr.m_SkinnedMeshRenderer != null; if (srcAttr.m_EditorShapeType == (int)PKFxManager.EShapeType.MeshShape + 1) //MeshFilter { if (srcAttr.m_MeshFilter == null) { srcAttr.m_Mesh = null; } else if (srcAttr.m_Mesh != srcAttr.m_MeshFilter.sharedMesh) { srcAttr.m_Mesh = srcAttr.m_MeshFilter.sharedMesh; if (srcAttr.m_Mesh != null) { srcAttr.m_MeshHashCode = srcAttr.m_Mesh.name.GetHashCode(); } else { srcAttr.m_MeshHashCode = 0; } } } wasChanged = srcAttr.m_MeshHashCode != m_SamplersCache[i].m_HashCode || smpSize != srcAttr.m_Dimensions || m_SamplersCache[i].m_Type2 != srcAttr.m_ShapeType || smpPos != srcAttr.m_ShapeCenter || smpEul != srcAttr.m_EulerOrientation; if (m_SamplersCache[i].m_MeshChanged != 0 && m_SamplersCache[i].m_Data != IntPtr.Zero && !srcAttr.m_InSkinning) { Marshal.FreeHGlobal(m_SamplersCache[i].m_Data); m_SamplersCache[i].m_Data = IntPtr.Zero; } m_SamplersCache[i].m_MeshChanged = 0; if (wasChanged || forceUpdate || m_ForceUpdateAttributes) { if (isMesh && srcAttr.m_Mesh != null) { int boneCount = withSkinning ? srcAttr.m_SkinnedMeshRenderer.bones.Length : 0; int triangleSize = srcAttr.m_Mesh.triangles.Length * sizeof(int); int verticesSize = (srcAttr.m_SamplingChannels & (int)PKFxManager.EMeshChannels.Channel_Position) != 0 ? srcAttr.m_Mesh.vertexCount * sizeof(float) * 3 : 0; int normalsSize = (srcAttr.m_SamplingChannels & (int)PKFxManager.EMeshChannels.Channel_Normal) != 0 ? srcAttr.m_Mesh.vertexCount * sizeof(float) * 3 : 0; int tangentsSize = (srcAttr.m_SamplingChannels & (int)PKFxManager.EMeshChannels.Channel_Tangent) != 0 ? srcAttr.m_Mesh.vertexCount * sizeof(float) * 4 : 0; int uvsSize = (srcAttr.m_SamplingChannels & (int)PKFxManager.EMeshChannels.Channel_UV) != 0 ? srcAttr.m_Mesh.vertexCount * sizeof(float) * 2 : 0; int vertexColorsSize = (srcAttr.m_SamplingChannels & (int)PKFxManager.EMeshChannels.Channel_VertexColor) != 0 ? srcAttr.m_Mesh.vertexCount * sizeof(float) * 4 : 0; int boneWeightsSize = boneCount != 0 ? srcAttr.m_Mesh.boneWeights.Length * sizeof(float) * 8 : 0; int totalSize = triangleSize + verticesSize + normalsSize + tangentsSize + uvsSize + vertexColorsSize + boneWeightsSize; m_SamplersCache[i].m_IndexCount = srcAttr.m_Mesh.triangles.Length; m_SamplersCache[i].m_VertexCount = srcAttr.m_Mesh.vertices.Length; m_SamplersCache[i].m_BoneCount = boneCount; m_SamplersCache[i].m_SamplingChannels = srcAttr.m_SamplingChannels; if (totalSize > 0 && (forceUpdate || m_SamplersCache[i].m_HashCode != srcAttr.m_MeshHashCode || m_SamplersCache[i].m_Type2 != (int)m_FxSamplersList[i].m_ShapeType)) { if (m_SamplersCache[i].m_Data != IntPtr.Zero) { Marshal.FreeHGlobal(m_SamplersCache[i].m_Data); } m_SamplersCache[i].m_Data = Marshal.AllocHGlobal(totalSize); UpdateMesh(m_SamplersCache[i].m_Data, srcAttr.m_Mesh, srcAttr.m_SamplingChannels, withSkinning); m_SamplersCache[i].m_MeshChanged = 0x2A; // nonzero, why not 42? m_SamplersCache[i].m_HashCode = srcAttr.m_MeshHashCode; srcAttr.m_InSkinning = false; } } else { if (m_SamplersCache[i].m_Data != IntPtr.Zero) { Marshal.FreeHGlobal(m_SamplersCache[i].m_Data); m_SamplersCache[i].m_Data = IntPtr.Zero; } m_SamplersCache[i].m_IndexCount = 0; m_SamplersCache[i].m_VertexCount = 0; m_SamplersCache[i].m_MeshChanged = 0x2A; // nonzero, why not 42? m_SamplersCache[i].m_HashCode = 0; m_SamplersCache[i].m_BoneCount = 0; } srcAttr.m_TextureChanged = false; smpCount = i; } m_SamplersCache[i].m_Type2 = (int)(m_FxSamplersList[i].m_ShapeType); m_SamplersCache[i].m_SizeX = srcAttr.m_Dimensions.x; m_SamplersCache[i].m_SizeY = srcAttr.m_Dimensions.y; m_SamplersCache[i].m_SizeZ = srcAttr.m_Dimensions.z; m_SamplersCache[i].m_PosX = srcAttr.m_ShapeCenter.x; m_SamplersCache[i].m_PosY = srcAttr.m_ShapeCenter.y; m_SamplersCache[i].m_PosZ = srcAttr.m_ShapeCenter.z; m_SamplersCache[i].m_EulX = srcAttr.m_EulerOrientation.x; m_SamplersCache[i].m_EulY = srcAttr.m_EulerOrientation.y; m_SamplersCache[i].m_EulZ = srcAttr.m_EulerOrientation.z; } else if (m_SamplersCache[i].m_Type1 == (int)PKFxManager.ESamplerType.SamplerImage) { wasChanged = srcAttr.m_TextureChanged || (int)srcAttr.m_TextureTexcoordMode != (int)m_SamplersCache[i].m_PosX; if (wasChanged || forceUpdate || m_ForceUpdateAttributes) { if (srcAttr.m_Texture == null) { m_SamplersCache[i].m_SizeX = 0; m_SamplersCache[i].m_SizeY = 0; if (m_SamplersCache[i].m_Data != IntPtr.Zero) { Marshal.FreeHGlobal(m_SamplersCache[i].m_Data); } m_SamplersCache[i].m_Data = IntPtr.Zero; int size = 0; m_SamplersCache[i].m_SizeZ = size; m_SamplersCache[i].m_PosX = 0; } else { byte[] data = srcAttr.m_Texture.GetRawTextureData(); if (data.Length == 0) { Debug.LogError("[PKFX] Sampler " + srcAttr.m_Descriptor.Name + " : Could not get raw texture data. Enable read/write in import settings."); } if (srcAttr.m_Texture.format == TextureFormat.DXT1) { m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.DXT1; } else if (srcAttr.m_Texture.format == TextureFormat.DXT5) { m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.DXT5; } else if (srcAttr.m_Texture.format == TextureFormat.ARGB32) { PKImageConverter.ARGB2BGRA(ref data); m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.BGRA8; } else if (srcAttr.m_Texture.format == TextureFormat.RGBA32) { PKImageConverter.RGBA2BGRA(ref data); m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.BGRA8; } else if (srcAttr.m_Texture.format == TextureFormat.BGRA32) { m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.BGRA8; } else if (srcAttr.m_Texture.format == TextureFormat.RGB24) { PKImageConverter.RGB2BGR(ref data); m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.BGR8; } else if (srcAttr.m_Texture.format == TextureFormat.PVRTC_RGB4) { m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.RGB4_PVRTC1; } else if (srcAttr.m_Texture.format == TextureFormat.PVRTC_RGBA4) { m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.RGBA4_PVRTC1; } else if (srcAttr.m_Texture.format == TextureFormat.PVRTC_RGB2) { m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.RGB2_PVRTC1; } else if (srcAttr.m_Texture.format == TextureFormat.PVRTC_RGBA2) { m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.RGBA2_PVRTC1; } else if (srcAttr.m_Texture.format == TextureFormat.ETC_RGB4) { m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.RGB8_ETC1; } else if (srcAttr.m_Texture.format == TextureFormat.ETC2_RGB) { m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.RGB8_ETC2; } else if (srcAttr.m_Texture.format == TextureFormat.ETC2_RGBA8) { m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.RGBA8_ETC2; } else if (srcAttr.m_Texture.format == TextureFormat.ETC2_RGBA1) { m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.RGB8A1_ETC2; } else { m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.Invalid; Debug.LogError("[PKFX] Sampler " + srcAttr.m_Descriptor.Name + " texture format not supported : " + srcAttr.m_Texture.format); } m_SamplersCache[i].m_SizeX = srcAttr.m_Texture.width; m_SamplersCache[i].m_SizeY = srcAttr.m_Texture.height; if (m_SamplersCache[i].m_Data != IntPtr.Zero) { Marshal.FreeHGlobal(m_SamplersCache[i].m_Data); } int size = data.Length; m_SamplersCache[i].m_Data = Marshal.AllocHGlobal(size); Marshal.Copy(data, 0, m_SamplersCache[i].m_Data, size); m_SamplersCache[i].m_SizeZ = size; m_SamplersCache[i].m_PosX = (int)srcAttr.m_TextureTexcoordMode; } srcAttr.m_TextureChanged = false; smpCount = i; } } else if (m_SamplersCache[i].m_Type1 == (int)PKFxManager.ESamplerType.SamplerCurve) { int timeKeysCount = srcAttr.m_CurvesTimeKeys == null ? 0 : srcAttr.m_CurvesTimeKeys.Length; if (timeKeysCount == 0 && timeKeysCount != m_SamplersCache[i].m_SizeX) { if (this.m_SamplersCurvesDataGCH.IsAllocated) { this.m_SamplersCurvesDataGCH.Free(); } m_SamplersCurvesDataCache = null; m_SamplersCache[i].m_Data = IntPtr.Zero; m_SamplersCache[i].m_SizeX = 0; smpCount = i; } else if (srcAttr.m_CurvesArray != null) { int curvesCount = srcAttr.m_CurvesArray.Length; int keyDataOffset = (1 + curvesCount * 3); wasChanged = timeKeysCount != m_SamplersCache[i].m_SizeX; //check key times changed if (!wasChanged && !forceUpdate && !m_ForceUpdateAttributes) { for (int keyId = 0; keyId < timeKeysCount; ++keyId) { if (m_SamplersCache[i].m_Data != IntPtr.Zero) { int realId = samplerCurveOffset + (keyId * keyDataOffset); float key = srcAttr.m_CurvesTimeKeys[keyId]; if (key != m_SamplersCurvesDataCache[realId]) { wasChanged = true; break; } } } } ////check values changed if (!wasChanged && !forceUpdate && !m_ForceUpdateAttributes) { for (int curveId = 0; curveId < srcAttr.m_CurvesArray.Length; ++curveId) { if (m_SamplersCache[i].m_Data != IntPtr.Zero) { var curve = srcAttr.m_CurvesArray[curveId]; for (int keyId = 0; keyId < curve.keys.Length; ++keyId) { int realId = samplerCurveOffset + (keyId * keyDataOffset) + 1 + curveId * 3; var key = curve.keys[keyId]; if (key.value != m_SamplersCurvesDataCache[realId + 0] || key.inTangent != m_SamplersCurvesDataCache[realId + 1] || key.outTangent != m_SamplersCurvesDataCache[realId + 2]) { wasChanged = true; break; } } } } } if (wasChanged || forceUpdate || m_ForceUpdateAttributes) { m_SamplersCache[i].m_Data = new IntPtr(m_SamplersCurvesDataHandler.ToInt64() + samplerCurveOffset); // copy values for (int keyId = 0; keyId < srcAttr.m_CurvesTimeKeys.Length; ++keyId) { int realId = samplerCurveOffset + (keyId * keyDataOffset); m_SamplersCurvesDataCache[realId] = srcAttr.m_CurvesTimeKeys[keyId]; for (int curveId = 0; curveId < srcAttr.m_CurvesArray.Length; ++curveId) { var curve = srcAttr.m_CurvesArray[curveId]; int curveRealId = realId + 1 + curveId * 3; var key = curve.keys[keyId]; //Check if key exist m_SamplersCurvesDataCache[curveRealId + 0] = key.value; m_SamplersCurvesDataCache[curveRealId + 1] = key.inTangent; m_SamplersCurvesDataCache[curveRealId + 2] = key.outTangent; } } samplerCurveOffset += timeKeysCount * keyDataOffset; m_SamplersCache[i].m_SizeX = timeKeysCount; //key count m_SamplersCache[i].m_SizeY = srcAttr.m_CurvesArray.Length; //dimension smpCount = i; } } } else if (m_SamplersCache[i].m_Type1 == (int)PKFxManager.ESamplerType.SamplerText) { wasChanged = srcAttr.m_Text.Length != m_SamplersCache[i].m_SizeX; if (!wasChanged && srcAttr.m_Text.Length > 0 && m_SamplersCache[i].m_Data == IntPtr.Zero) { wasChanged = true; } if (!wasChanged && m_SamplersCache[i].m_Data != IntPtr.Zero && Marshal.PtrToStringAnsi(m_SamplersCache[i].m_Data) != srcAttr.m_Text) { wasChanged = true; } if (wasChanged || forceUpdate || m_ForceUpdateAttributes) { if (m_SamplersCache[i].m_Data != IntPtr.Zero) { Marshal.FreeHGlobal(m_SamplersCache[i].m_Data); m_SamplersCache[i].m_Data = IntPtr.Zero; } int size = srcAttr.m_Text.Length; if (size > 0) { m_SamplersCache[i].m_Data = Marshal.StringToHGlobalAnsi(srcAttr.m_Text); } m_SamplersCache[i].m_SizeX = size; smpCount = i; } } } if (smpCount >= 0) { if (!PKFxManager.EffectSetSamplers(this.m_FXGUID, smpCount + 1, this.m_SamplersHandler)) { Debug.LogError("[PKFX] Sampler through pinned memory failed."); Debug.LogError("[PKFX] Did you try to change an FX without stopping it beforehand?"); } } for (int i = 0; i < m_FxSamplersList.Count; i++) { PKFxManager.Sampler srcAttr = m_FxSamplersList[i]; bool withSkinning = m_FxSamplersList[i].m_ShapeType == (int)PKFxManager.EShapeType.SkinnedMeshShape && m_FxSamplersList[i].m_SkinnedMeshRenderer != null; if (withSkinning) { int boneCount = srcAttr.m_SkinnedMeshRenderer != null ? srcAttr.m_SkinnedMeshRenderer.bones.Length : 0; if (!srcAttr.m_InSkinning) { int skeletonSize = boneCount != 0 ? srcAttr.m_SkinnedMeshRenderer.bones.Length * sizeof(float) * 16 : 0; if (m_SamplersCache[i].m_Data != IntPtr.Zero) { Marshal.FreeHGlobal(m_SamplersCache[i].m_Data); } m_SamplersCache[i].m_Data = Marshal.AllocHGlobal(skeletonSize); srcAttr.m_InSkinning = true; } UpdateBones(m_SamplersCache[i].m_Data, srcAttr.m_SkinnedMeshRenderer); if (!PKFxManager.EffectUpdateSamplerSkinning(this.m_FXGUID, i, this.m_SamplersHandler, Time.deltaTime)) { Debug.LogError("[PKFX] Skinning through pinned memory failed."); } } } m_ForceUpdateAttributes = false; }