Pārlūkot izejas kodu

Add render target to C# camera and fixed a recursive mutex lock in resource listener

Marko Pintera 11 gadi atpakaļ
vecāks
revīzija
1792480359

+ 0 - 2
BansheeCore/Source/BsResourceListenerManager.cpp

@@ -97,7 +97,6 @@ namespace BansheeEngine
 		for (auto& listener : relevantListeners)
 		{
 #if BS_DEBUG_MODE
-			BS_LOCK_MUTEX(mMutex);
 			assert(mActiveListeners.find(listener) != mActiveListeners.end() && "Attempting to notify a destroyed IResourceListener");
 #endif
 
@@ -117,7 +116,6 @@ namespace BansheeEngine
 		for (auto& listener : relevantListeners)
 		{
 #if BS_DEBUG_MODE
-			BS_LOCK_MUTEX(mMutex);
 			assert(mActiveListeners.find(listener) != mActiveListeners.end() && "Attempting to notify a destroyed IResourceListener");
 #endif
 

+ 50 - 21
MBansheeEngine/Camera.cs

@@ -21,119 +21,137 @@ namespace BansheeEngine
 
     public class Camera : Component
     {
-        public float aspectRatio
+        public float AspectRatio
         {
             get { return Internal_GetAspect(mCachedPtr); }
             set { Internal_SetAspect(mCachedPtr, value); }
         }
 
-        public float nearClipPlane
+        public float NearClipPlane
         {
             get { return Internal_GetNearClip(mCachedPtr); }
             set { Internal_SetNearClip(mCachedPtr, value); }
         }
 
-        public float farClipPlane
+        public float FarClipPlane
         {
             get { return Internal_GetFarClip(mCachedPtr); }
             set { Internal_SetFarClip(mCachedPtr, value); }
         }
 
-        public Degree fieldOfView
+        public Degree FieldOfView
         {
             get { return Internal_GetFieldOfView(mCachedPtr); }
             set { Internal_SetFieldOfView(mCachedPtr, value); }
         }
 
-        public Rect2 viewportRect
+        public Rect2 ViewportRect
         {
             get { return Internal_GetViewportRect(mCachedPtr); }
             set { Internal_SetViewportRect(mCachedPtr, value); }
         }
 
-        public ProjectionType projectionType
+        public ProjectionType ProjectionType
         {
             get { return Internal_GetProjectionType(mCachedPtr); }
             set { Internal_SetProjectionType(mCachedPtr, value); }
         }
 
-        public float orthoHeight
+        public float OrthoHeight
         {
             get { return Internal_GetOrthographicHeight(mCachedPtr); }
             set { Internal_SetOrthographicHeight(mCachedPtr, value); }
         }
 
-        public float orthoWidth
+        public float OrthoWidth
         {
             get { return Internal_GetOrthographicWidth(mCachedPtr); }
         }
 
-        public Color clearColor
+        public Color ClearColor
         {
             get { return Internal_GetClearColor(mCachedPtr); }
             set { Internal_SetClearColor(mCachedPtr, value); }
         }
 
-        public float clearDepth
+        public float ClearDepth
         {
             get { return Internal_GetDepthClearValue(mCachedPtr); }
             set { Internal_SetDepthClearValue(mCachedPtr, value); }
         }
 
-        public UInt16 clearStencil
+        public UInt16 ClearStencil
         {
             get { return Internal_GetStencilClearValue(mCachedPtr); }
             set { Internal_SetStencilClearValue(mCachedPtr, value); }
         }
 
-        public ClearFlags clearFlags
+        public ClearFlags ClearFlags
         {
             get { return Internal_GetClearFlags(mCachedPtr); }
             set { Internal_SetClearFlags(mCachedPtr, value); }
         }
 
-        public int priority
+        public int Priority
         {
             get { return Internal_GetPriority(mCachedPtr); }
             set { Internal_SetPriority(mCachedPtr, value); }
         }
 
-        public UInt64 layers
+        public UInt64 Layers
         {
             get { return Internal_GetLayers(mCachedPtr); }
             set { Internal_SetLayers(mCachedPtr, value); }
         }
 
-        public Matrix4 projMatrix
+        public Matrix4 ProjMatrix
         {
             get { return Internal_GetProjMatrix(mCachedPtr); }
         }
 
-        public Matrix4 projMatrixInv
+        public Matrix4 ProjMatrixInv
         {
             get { return Internal_GetProjMatrixInv(mCachedPtr); }
         }
 
-        public Matrix4 viewMatrix
+        public Matrix4 ViewMatrix
         {
             get { return Internal_GetViewMatrix(mCachedPtr); }
         }
 
-        public Matrix4 viewMatrixInv
+        public Matrix4 ViewMatrixInv
         {
             get { return Internal_GetViewMatrixInv(mCachedPtr); }
         }
 
-        public int widthPixels
+        public int WidthPixels
         {
             get { return Internal_GetWidthPixels(mCachedPtr); }
         }
 
-        public int heightPixels
+        public int HeightPixels
         {
             get { return Internal_GetHeightPixels(mCachedPtr); }
         }
 
+        public RenderTarget Target
+        {
+            get
+            {
+                return target;
+            }
+            set
+            {
+                target = value;
+
+                IntPtr targetPtr = IntPtr.Zero;
+                if (target != null)
+                    targetPtr = target.mCachedPtr;
+
+                Internal_SetRenderTarget(mCachedPtr, targetPtr);
+            }
+        }
+
         public Vector2I WorldToScreen(Vector3 value) { return Internal_WorldToScreen(mCachedPtr, value); }
         public Vector2 WorldToClip(Vector3 value) { return Internal_WorldToClip(mCachedPtr, value); }
         public Vector3 WorldToView(Vector3 value) { return Internal_WorldToView(mCachedPtr, value); }
@@ -154,7 +172,12 @@ namespace BansheeEngine
         public Vector3 ProjectPoint(Vector3 value) { return Internal_ProjectPoint(mCachedPtr, value); }
         public Vector3 UnprojectPoint(Vector3 value) { return Internal_UnprojectPoint(mCachedPtr, value); }
 
-        // TODO - Add RenderTexture
+        private RenderTarget target;
+
+        private void Update()
+        {
+            Internal_UpdateView(mCachedPtr, sceneObject.mCachedPtr);
+        }
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern float Internal_GetAspect(IntPtr instance);
@@ -273,5 +296,11 @@ namespace BansheeEngine
         private static extern Vector3 Internal_ProjectPoint(IntPtr instance, Vector3 value);
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern Vector3 Internal_UnprojectPoint(IntPtr instance, Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetRenderTarget(IntPtr instance, IntPtr rt);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_UpdateView(IntPtr instance, IntPtr parentSO);
     }
 }

+ 6 - 2
SBansheeEngine/Include/BsScriptCamera.h

@@ -22,6 +22,8 @@ namespace BansheeEngine
 		ScriptCamera(MonoObject* managedInstance);
 		~ScriptCamera();
 
+		void updateView(const HSceneObject& parent);
+
 		static float internal_GetAspect(ScriptCamera* instance);
 		static void internal_SetAspect(ScriptCamera* instance, float value);
 		static float internal_GetNearClip(ScriptCamera* instance);
@@ -91,9 +93,11 @@ namespace BansheeEngine
 		static Vector3 internal_ProjectPoint(ScriptCamera* instance, Vector3 value);
 		static Vector3 internal_UnprojectPoint(ScriptCamera* instance, Vector3 value);
 
-		static MonoObject* internal_GetRenderTexture(ScriptCamera* instance);
-		static void internal_SetRenderTexture(ScriptCamera* instance, MonoObject* textureObj);
+		static void internal_SetRenderTarget(ScriptCamera* instance, ScriptRenderTarget* target);
+
+		static void internal_UpdateView(ScriptCamera* instance, ScriptSceneObject* parent);
 
 		SPtr<CameraHandler> mCameraHandler;
+		UINT32 mLastUpdateHash;
 	};
 }

+ 1 - 0
SBansheeEngine/Include/BsScriptEnginePrerequisites.h

@@ -37,6 +37,7 @@ namespace BansheeEngine
 	class ScriptSceneObject;
 	class ScriptComponent;
 	class ScriptManagedResource;
+	class ScriptRenderTarget;
 	class ManagedComponent;
 	class ManagedSerializableFieldData;
 	class ManagedSerializableFieldKey;

+ 3 - 2
SBansheeEngine/Include/BsScriptRenderTarget.h

@@ -7,6 +7,9 @@ namespace BansheeEngine
 {
 	class BS_SCR_BE_EXPORT ScriptRenderTargetBase : public ScriptObjectBase
 	{
+	public:
+		virtual RenderTargetPtr getNativeValue() const = 0;
+
 	protected:
 		friend class ScriptResourceManager;
 
@@ -15,8 +18,6 @@ namespace BansheeEngine
 		{ }
 
 		virtual ~ScriptRenderTargetBase() {}
-
-		virtual RenderTargetPtr getNativeValue() const = 0;
 	};
 
 	class BS_SCR_BE_EXPORT ScriptRenderTarget : public ScriptObject<ScriptRenderTarget, ScriptRenderTargetBase>

+ 2 - 0
SBansheeEngine/Include/BsScriptSceneObject.h

@@ -15,6 +15,8 @@ namespace BansheeEngine
 		virtual HGameObject getNativeHandle() const { return mSceneObject; }
 		virtual void setNativeHandle(const HGameObject& gameObject);
 
+		HSceneObject getNativeSceneObject() const { return mSceneObject; }
+
 	private:
 		friend class ScriptGameObjectManager;
 

+ 29 - 13
SBansheeEngine/Source/BsScriptCamera.cpp

@@ -6,11 +6,14 @@
 #include "BsMonoUtil.h"
 #include "BsApplication.h"
 #include "BsCameraHandler.h"
+#include "BsScriptSceneObject.h"
+#include "BsSceneObject.h"
+#include "BsScriptRenderTarget.h"
 
 namespace BansheeEngine
 {
 	ScriptCamera::ScriptCamera(MonoObject* managedInstance)
-		:ScriptObject(managedInstance), mCameraHandler(nullptr)
+		:ScriptObject(managedInstance), mCameraHandler(nullptr), mLastUpdateHash(0)
 	{ 
 		ViewportPtr primaryViewport = gApplication().getPrimaryViewport();
 
@@ -93,9 +96,21 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_ProjectPoint", &ScriptCamera::internal_GetAspect);
 		metaData.scriptClass->addInternalCall("Internal_UnprojectPoint", &ScriptCamera::internal_GetAspect);
 
-		// TODO
-		// metaData.scriptClass->addInternalCall("Internal_SetRenderTexture", &ScriptCamera::internal_SetRenderTexture);
-		// metaData.scriptClass->addInternalCall("Internal_GetRenderTexture", &ScriptCamera::internal_GetRenderTexture);
+		metaData.scriptClass->addInternalCall("Internal_SetRenderTarget", &ScriptCamera::internal_SetRenderTarget);
+
+		metaData.scriptClass->addInternalCall("Internal_UpdateView", &ScriptCamera::internal_UpdateView);
+	}
+
+	void ScriptCamera::updateView(const HSceneObject& parent)
+	{
+		UINT32 curHash = parent->getTransformHash();
+		if (curHash != mLastUpdateHash)
+		{
+			mCameraHandler->setPosition(parent->getWorldPosition());
+			mCameraHandler->setRotation(parent->getWorldRotation());
+
+			mLastUpdateHash = curHash;
+		}
 	}
 
 	float ScriptCamera::internal_GetAspect(ScriptCamera* instance)
@@ -355,15 +370,9 @@ namespace BansheeEngine
 		return instance->mCameraHandler->unprojectPoint(value);
 	}
 
-	MonoObject* ScriptCamera::internal_GetRenderTexture(ScriptCamera* instance)
+	void ScriptCamera::internal_SetRenderTarget(ScriptCamera* instance, ScriptRenderTarget* target)
 	{
-		// TODO - Not implemented
-		return nullptr;
-	}
-
-	void ScriptCamera::internal_SetRenderTexture(ScriptCamera* instance, MonoObject* textureObj)
-	{
-		if (textureObj == nullptr)
+		if (target == nullptr)
 		{
 			ViewportPtr primaryViewport = gApplication().getPrimaryViewport();
 
@@ -371,7 +380,14 @@ namespace BansheeEngine
 		}
 		else
 		{
-			// TODO - Not implemented
+			instance->mCameraHandler->getViewport()->setTarget(target->getNativeValue());
 		}
 	}
+
+	void ScriptCamera::internal_UpdateView(ScriptCamera* instance, ScriptSceneObject* parent)
+	{
+		HSceneObject parentSO = parent->getNativeSceneObject();
+
+		instance->updateView(parentSO);
+	}
 }

+ 0 - 18
TODO.txt

@@ -45,14 +45,6 @@ dependant resources (including from scripts)
 
 -----------------
 
-Port SceneCameraController to C#
-Port RenderTexture to C# and likely extend Texture2D so it accepts renderable flags. While at it add TextureCube and Texture3D as well.
- - Actually Texture2D doesn't seem to be implemented at all. Will also need to add PixelData wrapper.
- - Will I need to add support for readable textures? e.g. what happens when you try to read a texture from C#?
-   - Almost certainly. It's very useful to be able to read textures.
-   - I can't sync the threads when reading, it would be too slow. Have an AsyncOp similar to c++ code? 
-   - Also DX11 already creates a temporary staging buffer when reading from a texture, so keeping yet another CPU
-     copy seems like a waste.
 Ensure that EditorWindow resize callback works properly.
  - Perhaps add OnResizeEnd callback that can be used for updating the render texture
 Create a C# wrapper around ProjectSettings
@@ -77,16 +69,6 @@ IMPROVE SceneGrid LOOK
  - LIKELY USE PIXEL SceneGrid WITH AA
  - OR (better) instead of drawing rows and columns of lines, just draw a plane with procedural texture
 
----------------------------------------------------------------------
-Render textures in C#:
- - In C# have Texture2D, TextureCube, TextureVolume. They should have a common Texture base.
-   - Each of those can be created with a Renderable flag
- - Render textures mirror what we have in C++
-   - RenderTexture and MultiRenderTexture (since we have these separate representation we don't need RenderBuffer that Unity has)
-   - You can provide an existing texture from types listed above, or create a new render target and
-      create a basic 2D texture (multiple constructors)
- - Both RT types should have their color buffer (s) and depth buffer accessible as a texture to be used for rendering, or for reading
-
 ----------------------------------------------------------------------
 Handles