Browse Source

Added C# PixelUtility

Marko Pintera 11 years ago
parent
commit
2ee57f4357

+ 1 - 0
MBansheeEngine/MBansheeEngine.csproj

@@ -94,6 +94,7 @@
     <Compile Include="Math\Rect2I.cs" />
     <Compile Include="Math\Rect2I.cs" />
     <Compile Include="Math\Vector2I.cs" />
     <Compile Include="Math\Vector2I.cs" />
     <Compile Include="PixelData.cs" />
     <Compile Include="PixelData.cs" />
+    <Compile Include="PixelUtility.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Math\Quaternion.cs" />
     <Compile Include="Math\Quaternion.cs" />

+ 173 - 0
MBansheeEngine/PixelUtility.cs

@@ -0,0 +1,173 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace BansheeEngine
+{
+    public static class PixelUtility
+    {
+        public static int GetMemorySize(int width, int height, int depth, PixelFormat format)
+        {
+            int value;
+            Internal_GetMemorySize(width, height, depth, format, out value);
+            return value;
+        }
+
+        public static bool HasAlpha(PixelFormat format)
+        {
+            bool value;
+            Internal_HasAlpha(format, out value);
+            return value;
+        }
+
+        public static bool IsFloatingPoint(PixelFormat format)
+        {
+            bool value;
+            Internal_IsFloatingPoint(format, out value);
+            return value;
+        }
+
+        public static bool IsCompressed(PixelFormat format)
+        {
+            bool value;
+            Internal_IsCompressed(format, out value);
+            return value;
+        }
+
+        public static bool IsDepth(PixelFormat format)
+        {
+            bool value;
+            Internal_IsDepth(format, out value);
+            return value;
+        }
+
+        public static int GetMaxMipmaps(int width, int height, int depth, PixelFormat format)
+        {
+            int value;
+            Internal_GetMaxMipmaps(width, height, depth, format, out value);
+            return value;
+        }
+
+        public static PixelData ConvertFormat(PixelData source, PixelFormat newFormat)
+        {
+            return Internal_ConvertFormat(source, newFormat);
+        }
+
+        public static PixelData Compress(PixelData source, CompressionOptions options)
+        {
+            return Internal_Compress(source, options);
+        }
+
+		public static PixelData[] GenerateMipmaps(PixelData source, MipMapGenOptions options)
+        {
+            return Internal_GenerateMipmaps(source, options);
+        }
+
+        public static PixelData Scale(PixelData source, PixelVolume newSize, ScaleFilter filter = ScaleFilter.Linear)
+        {
+            return Internal_Scale(source, newSize, filter);
+        }
+
+        public static void ApplyGamma(PixelData source, float gamma)
+        {
+            Internal_ApplyGamma(source, gamma);
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetMemorySize(int width, int height, int depth, PixelFormat format, out int value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_HasAlpha(PixelFormat format, out bool value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_IsFloatingPoint(PixelFormat format, out bool value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_IsCompressed(PixelFormat format, out bool value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_IsDepth(PixelFormat format, out bool value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetMaxMipmaps(int width, int height, int depth, PixelFormat format, out int value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern PixelData Internal_ConvertFormat(PixelData source, PixelFormat newFormat);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern PixelData Internal_Compress(PixelData source, CompressionOptions options);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern PixelData[] Internal_GenerateMipmaps(PixelData source, MipMapGenOptions options);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern PixelData Internal_Scale(PixelData source, PixelVolume newSize, ScaleFilter filter);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_ApplyGamma(PixelData source, float gamma);
+    }
+
+    // Note: IDs must match C++ enum PixelUtil::Filter
+    public enum ScaleFilter
+    {
+        Nearest,
+        Linear
+    };
+
+    // Note: IDs must match C++ enum CompressionQuality
+	public enum CompressionQuality
+	{
+		Fastest,
+		Normal,
+		Production,
+		Highest
+	};
+
+    // Note: IDs must match C++ enum AlphaMode
+	public enum AlphaMode
+	{
+		None,
+		Transparency,
+		Premultiplied
+	};
+
+    // Note: IDs must match C++ enum MipMapWrapMode
+	public enum MipMapWrapMode
+	{
+		Mirror,
+		Repeat,
+		Clamp
+	};
+
+	// Note: IDs must match C++ enum MipMapFilter
+	public enum MipMapFilter
+	{
+		Box,
+		Triangle,
+		Kaiser
+	};
+
+    // Note: Layout must match C++ struct CompressionOptions
+    [StructLayout(LayoutKind.Sequential)]
+	public struct CompressionOptions
+	{
+		public PixelFormat format;
+	    public AlphaMode alphaMode;
+		public bool isNormalMap;
+		public bool isSRGB;
+		public CompressionQuality quality;
+	};
+
+    // Note: Layout must match C++ struct MipMapGenOptions
+    [StructLayout(LayoutKind.Sequential)]
+	public struct MipMapGenOptions
+	{
+		public MipMapFilter filter;
+		public MipMapWrapMode wrapMode;
+		public bool isNormalMap;
+		public bool normalizeMipmaps;
+	};
+}

+ 30 - 0
SBansheeEngine/Include/BsScriptPixelUtility.h

@@ -0,0 +1,30 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsScriptObject.h"
+#include "BsPixelData.h"
+#include "BsPixelUtil.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BE_EXPORT ScriptPixelUtility : public ScriptObject <ScriptPixelUtility>
+	{
+	public:
+		SCRIPT_OBJ(BansheeEngineAssemblyName, "BansheeEngine", "PixelUtility")
+
+	private:
+		static void internal_getMemorySize(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format, UINT32* value);
+		static void internal_hasAlpha(PixelFormat format, bool* value);
+		static void internal_isFloatingPoint(PixelFormat format, bool* value);
+		static void internal_isCompressed(PixelFormat format, bool* value);
+		static void internal_isDepth(PixelFormat format, bool* value);
+		static void internal_getMaxMipmaps(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format, UINT32* value);
+		static MonoObject* internal_convertFormat(MonoObject* source, PixelFormat newFormat);
+		static MonoObject* internal_compress(MonoObject* source, CompressionOptions options);
+		static MonoArray* internal_generateMipmaps(MonoObject* source, MipMapGenOptions options);
+		static MonoObject* internal_scale(MonoObject* source, PixelVolume newSize, PixelUtil::Filter filter);
+		static void internal_applyGamma(MonoObject* source, float gamma);
+
+		ScriptPixelUtility(MonoObject* instance);
+	};
+}

+ 2 - 0
SBansheeEngine/SBansheeEngine.vcxproj

@@ -278,6 +278,7 @@
     <ClInclude Include="Include\BsScriptObject.h" />
     <ClInclude Include="Include\BsScriptObject.h" />
     <ClInclude Include="Include\BsScriptObjectImpl.h" />
     <ClInclude Include="Include\BsScriptObjectImpl.h" />
     <ClInclude Include="Include\BsScriptPixelData.h" />
     <ClInclude Include="Include\BsScriptPixelData.h" />
+    <ClInclude Include="Include\BsScriptPixelUtility.h" />
     <ClInclude Include="Include\BsScriptResource.h" />
     <ClInclude Include="Include\BsScriptResource.h" />
     <ClInclude Include="Include\BsScriptResourceManager.h" />
     <ClInclude Include="Include\BsScriptResourceManager.h" />
     <ClInclude Include="Include\BsScriptSceneObject.h" />
     <ClInclude Include="Include\BsScriptSceneObject.h" />
@@ -340,6 +341,7 @@
     <ClCompile Include="Source\BsScriptObject.cpp" />
     <ClCompile Include="Source\BsScriptObject.cpp" />
     <ClCompile Include="Source\BsScriptObjectImpl.cpp" />
     <ClCompile Include="Source\BsScriptObjectImpl.cpp" />
     <ClCompile Include="Source\BsScriptPixelData.cpp" />
     <ClCompile Include="Source\BsScriptPixelData.cpp" />
+    <ClCompile Include="Source\BsScriptPixelUtility.cpp" />
     <ClCompile Include="Source\BsScriptResourceManager.cpp" />
     <ClCompile Include="Source\BsScriptResourceManager.cpp" />
     <ClCompile Include="Source\BsScriptSceneObject.cpp" />
     <ClCompile Include="Source\BsScriptSceneObject.cpp" />
     <ClCompile Include="Source\BsManagedSerializableArray.cpp" />
     <ClCompile Include="Source\BsManagedSerializableArray.cpp" />

+ 6 - 0
SBansheeEngine/SBansheeEngine.vcxproj.filters

@@ -255,6 +255,9 @@
     <ClInclude Include="Include\BsScriptTexture3D.h">
     <ClInclude Include="Include\BsScriptTexture3D.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\BsScriptPixelUtility.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptTexture2D.cpp">
     <ClCompile Include="Source\BsScriptTexture2D.cpp">
@@ -443,5 +446,8 @@
     <ClCompile Include="Source\BsScriptTexture3D.cpp">
     <ClCompile Include="Source\BsScriptTexture3D.cpp">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\BsScriptPixelUtility.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 139 - 0
SBansheeEngine/Source/BsScriptPixelUtility.cpp

@@ -0,0 +1,139 @@
+#include "BsScriptPixelUtility.h"
+#include "BsMonoManager.h"
+#include "BsMonoClass.h"
+#include "BsMonoUtil.h"
+#include "BsDebug.h"
+#include "BsScriptPixelData.h"
+
+namespace BansheeEngine
+{
+	ScriptPixelUtility::ScriptPixelUtility(MonoObject* instance)
+		:ScriptObject(instance)
+	{ }
+
+	void ScriptPixelUtility::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("Internal_GetMemorySize", &ScriptPixelUtility::internal_getMemorySize);
+		metaData.scriptClass->addInternalCall("Internal_HasAlpha", &ScriptPixelUtility::internal_hasAlpha);
+		metaData.scriptClass->addInternalCall("Internal_IsFloatingPoint", &ScriptPixelUtility::internal_isFloatingPoint);
+		metaData.scriptClass->addInternalCall("Internal_IsCompressed", &ScriptPixelUtility::internal_isCompressed);
+		metaData.scriptClass->addInternalCall("Internal_IsDepth", &ScriptPixelUtility::internal_isDepth);
+		metaData.scriptClass->addInternalCall("Internal_GetMaxMipmaps", &ScriptPixelUtility::internal_getMaxMipmaps);
+		metaData.scriptClass->addInternalCall("Internal_ConvertFormat", &ScriptPixelUtility::internal_convertFormat);
+		metaData.scriptClass->addInternalCall("Internal_Compress", &ScriptPixelUtility::internal_compress);
+		metaData.scriptClass->addInternalCall("Internal_GenerateMipmaps", &ScriptPixelUtility::internal_generateMipmaps);
+		metaData.scriptClass->addInternalCall("Internal_Scale", &ScriptPixelUtility::internal_scale);
+		metaData.scriptClass->addInternalCall("Internal_ApplyGamma", &ScriptPixelUtility::internal_applyGamma);
+	}
+
+	void ScriptPixelUtility::internal_getMemorySize(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format, UINT32* value)
+	{
+		*value = PixelUtil::getMemorySize(width, height, depth, format);
+	}
+
+	void ScriptPixelUtility::internal_hasAlpha(PixelFormat format, bool* value)
+	{
+		*value = PixelUtil::hasAlpha(format);
+	}
+
+	void ScriptPixelUtility::internal_isFloatingPoint(PixelFormat format, bool* value)
+	{
+		*value = PixelUtil::isFloatingPoint(format);
+	}
+
+	void ScriptPixelUtility::internal_isCompressed(PixelFormat format, bool* value)
+	{
+		*value = PixelUtil::isCompressed(format);
+	}
+
+	void ScriptPixelUtility::internal_isDepth(PixelFormat format, bool* value)
+	{
+		*value = PixelUtil::isDepth(format);
+	}
+
+	void ScriptPixelUtility::internal_getMaxMipmaps(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format, UINT32* value)
+	{
+		*value = PixelUtil::getMaxMipmaps(width, height, depth, format);
+	}
+
+	MonoObject* ScriptPixelUtility::internal_convertFormat(MonoObject* source, PixelFormat newFormat)
+	{
+		ScriptPixelData* sourceScriptPixelData = ScriptPixelData::toNative(source);
+		if (sourceScriptPixelData == nullptr)
+			return nullptr;
+
+		PixelDataPtr sourcePixelData = sourceScriptPixelData->getInternalValue();
+		PixelDataPtr outputData = bs_shared_ptr<PixelData>(sourcePixelData->getWidth(), sourcePixelData->getHeight(), 
+			sourcePixelData->getDepth(), newFormat);
+		outputData->allocateInternalBuffer();
+
+		PixelUtil::bulkPixelConversion(*sourcePixelData, *outputData);
+
+		return ScriptPixelData::create(outputData);
+	}
+
+	MonoObject* ScriptPixelUtility::internal_compress(MonoObject* source, CompressionOptions options)
+	{
+		ScriptPixelData* sourceScriptPixelData = ScriptPixelData::toNative(source);
+		if (sourceScriptPixelData == nullptr)
+			return nullptr;
+
+		PixelDataPtr sourcePixelData = sourceScriptPixelData->getInternalValue();
+		PixelDataPtr outputData = bs_shared_ptr<PixelData>(sourcePixelData->getWidth(), sourcePixelData->getHeight(), 
+			sourcePixelData->getDepth(), options.format);
+		outputData->allocateInternalBuffer();
+
+		PixelUtil::compress(*sourcePixelData, *outputData, options);
+
+		return ScriptPixelData::create(outputData);
+	}
+
+	MonoArray* ScriptPixelUtility::internal_generateMipmaps(MonoObject* source, MipMapGenOptions options)
+	{
+		ScriptPixelData* sourceScriptPixelData = ScriptPixelData::toNative(source);
+		if (sourceScriptPixelData == nullptr)
+			return nullptr;
+
+		PixelDataPtr sourcePixelData = sourceScriptPixelData->getInternalValue();
+		Vector<PixelDataPtr> mipmaps = PixelUtil::genMipmaps(*sourcePixelData, options);
+
+		UINT32 numElements = (UINT32)mipmaps.size();
+		MonoArray* outputArray = mono_array_new(MonoManager::instance().getDomain(),
+			ScriptPixelData::getMetaData()->scriptClass->_getInternalClass(), numElements);
+
+		for (UINT32 i = 0; i < numElements; i++)
+		{
+			MonoObject* managedPixelData = ScriptPixelData::create(mipmaps[i]);
+
+			mono_array_set(outputArray, MonoObject*, i, managedPixelData);
+		}
+
+		return outputArray;
+	}
+
+	MonoObject* ScriptPixelUtility::internal_scale(MonoObject* source, PixelVolume newSize, PixelUtil::Filter filter)
+	{
+		ScriptPixelData* sourceScriptPixelData = ScriptPixelData::toNative(source);
+		if (sourceScriptPixelData == nullptr)
+			return nullptr;
+
+		PixelDataPtr sourcePixelData = sourceScriptPixelData->getInternalValue();
+		PixelDataPtr outputData = bs_shared_ptr<PixelData>(sourcePixelData->getWidth(), sourcePixelData->getHeight(),
+			sourcePixelData->getDepth(), sourcePixelData->getFormat());
+		outputData->allocateInternalBuffer();
+
+		PixelUtil::scale(*sourcePixelData, *outputData, filter);
+
+		return ScriptPixelData::create(outputData);
+	}
+
+	void ScriptPixelUtility::internal_applyGamma(MonoObject* source, float gamma)
+	{
+		ScriptPixelData* sourceScriptPixelData = ScriptPixelData::toNative(source);
+		if (sourceScriptPixelData == nullptr)
+			return;
+
+		PixelDataPtr pixelData = sourceScriptPixelData->getInternalValue();
+		PixelUtil::applyGamma(pixelData->getData(), gamma, pixelData->getSize(), PixelUtil::getNumElemBits(pixelData->getFormat()));
+	}
+}