瀏覽代碼

WIP: Updating & cleaning up framework docs

BearishSun 7 年之前
父節點
當前提交
5086aa542b

+ 26 - 2
Documentation/Manuals/Native/User/events.md

@@ -45,7 +45,7 @@ public:
 
 # Subscribing to events
 
-An external object can register itself with an event by calling @ref bs::TEvent<RetType, Args> "Event::connect". 
+An external object can register itself with an event by calling @ref bs::TEvent<RetType, Args> "Event::connect()". 
 ~~~~~~~~~~~~~{.cpp}
 // Define a couple of methods that trigger when events are triggered
 auto playerJumpedCallback = [&]()
@@ -124,4 +124,28 @@ class MyEventSubscriber
 		playerController.onPlayerJumped.connect(callback);
 	}
 };
-~~~~~~~~~~~~~
+~~~~~~~~~~~~~
+
+Alternatively, you can wrap the class function call in a lambda function while capturing *this*.
+~~~~~~~~~~~~~{.cpp}
+// Alternative version of the above example, using lambda instead of std::bind
+class MyEventSubscriber
+{
+	void playerJumpedCallback() // Has a hidden "this" pointer parameter
+	{
+		gDebug().logDebug("Player jumped!");
+	}
+	
+	void subscribeToEvents(MyPlayerController& playerController)
+	{
+		// Wrap our class method call in a lambda function
+		auto callback = [this]()
+		{
+			playerJumpedCallback();
+		};
+		
+		// Register the callback without the event needing to know about "this" pointer parameter
+		playerController.onPlayerJumped.connect(callback);
+	}
+};
+~~~~~~~~~~~~~

+ 15 - 10
Documentation/Manuals/Native/User/fileSystem.md

@@ -9,9 +9,9 @@ Path myPath = "C:/Path/To/File.txt";
 ~~~~~~~~~~~~~
 
 Some of the things you can do with a **Path**:
- - Retrieve the filename using @ref bs::Path::getFilename "Path::getFilename"
- - Retrieve the filename extension using @ref bs::Path::getExtension "Path::getExtension"
- - Get last element of path, either file or directory using @ref bs::Path::getTail "Path::getTail"
+ - Retrieve the filename using @ref bs::Path::getFilename "Path::getFilename()"
+ - Retrieve the filename extension using @ref bs::Path::getExtension "Path::getExtension()"
+ - Get last element of path, either file or directory using @ref bs::Path::getTail "Path::getTail()"
  - Iterate over directories, get drive, combine paths, convert relative to absolute paths and vice versa, and more. See the API reference for a complete list.
  
 For example:
@@ -26,12 +26,17 @@ Path a("C:/Path/To/");
 Path b("File.txt");
 Path combined = a + b; // // Path is now "C:/Path/To/File.txt"
 ~~~~~~~~~~~~~
- 
-All **Path** methods that return strings come in two variants, one that returns a narrow (8-bit) character string like **Path::getFilename**, and one that contains wide character string like **Path::getWFilename**.
 
+**Path** can always be converted back to a string by calling @ref bs::Path::toString "Path::toString()".
+
+~~~~~~~~~~~~~{.cpp}
+Path path("C:/Path/To/");
+String str = path.toString();
+~~~~~~~~~~~~~
+ 
 When setting paths be careful with setting backslashes or slashes at the end of the path. Path with a no backslash/slash on the end will be interpreted as a file path, and path with a backslash/slash will be interpreted as a folder path. For example:
- - "C:/MyFolder" - "MyFolder" interpreted as a file, **Path::getFilename** returns "MyFolder"
- - "C:/MyFolder/" - "MyFolder" interpreted as a folder, **Path::getFilename** returns an empty string
+ - "C:/MyFolder" - "MyFolder" interpreted as a file, **Path::getFilename()** returns "MyFolder"
+ - "C:/MyFolder/" - "MyFolder" interpreted as a folder, **Path::getFilename()** returns an empty string
  
 # File system
 File system operations like opening, creating, deleting, moving, copying files/folders are provided by the @ref bs::FileSystem "FileSystem" class. Check the API reference for a complete list of operations.
@@ -64,9 +69,9 @@ fileStream->close();
 bs_free(myBuffer);
 ~~~~~~~~~~~~~
 
-Once you are done with a stream make sure to close it by calling @ref bs::DataStream::close "DataStream::close". Stream will also be automatically closed when it goes out of scope.
+Once you are done with a stream make sure to close it by calling @ref bs::DataStream::close "DataStream::close()". Stream will also be automatically closed when it goes out of scope.
 
-Streams don't need to be read or written to sequentially, use @ref bs::DataStream::seek "DataStream::seek" to move within any position of the stream, and @ref bs::DataStream::tell "DataStream::tell" to find out the current position.
+Streams don't need to be read or written to sequentially, use @ref bs::DataStream::seek "DataStream::seek()" to move within any position of the stream, and @ref bs::DataStream::tell "DataStream::tell()" to find out the current position.
 
 ~~~~~~~~~~~~~{.cpp}
 // Open the file we wrote in the previous example
@@ -86,4 +91,4 @@ bs_free(myBuffer);
 
 Each time you read or write from the stream, the current read/write indices will advance. So subsequent calls to read/write will continue from the last position that was read/written.
 
-Finally, use @ref bs::DataStream::size "DataStream::size" to find out the size of a stream in bytes.
+Finally, use @ref bs::DataStream::size "DataStream::size()" to find out the size of a stream in bytes.

+ 4 - 4
Documentation/Manuals/Native/User/math.md

@@ -33,7 +33,7 @@ float length = a.length();
 ~~~~~~~~~~~~~
 
 ## Integer vectors
-Integer 2D vector type is also provided as @ref bs::Vector2I "Vector2I". It also supports a full range of operators and comes with a few helper methods. Higher level integer vector types can also be created in the form of @ref bs::VectorNI<T> "bs::VectorNI<T>".
+Integer 2D vector type is also provided as @ref bs::Vector2I "Vector2I". It also supports a full range of operators and comes with a few helper methods. Higher level integer vector types can also be created in the form of @ref bs::Vector3I "Vector3I" and @ref bs::Vector4I "Vector4I".
 
 ~~~~~~~~~~~~~{.cpp}
 Vector2I intVec(0, 10);
@@ -177,11 +177,11 @@ Vector3 scale(1.0f, 0.5f, 2.0f);
 Matrix3 d(someQuat, scale);
 ~~~~~~~~~~~~~
 
-To apply a matrix transformation to a 3D vector call @ref bs::Matrix3::transform "Matrix3::transform()".
+To apply a matrix transformation to a 3D vector call @ref bs::Matrix3::multiply() "Matrix3::multiply()".
 
 ~~~~~~~~~~~~~{.cpp}
 Vector3 myVector(1, 0, 0);
-Vector3 transformedVector = b.transform(myVector);
+Vector3 transformedVector = b.multiply(myVector);
 ~~~~~~~~~~~~~
 
 Matrices can be multiplied to combine their transformations.
@@ -341,7 +341,7 @@ bs::f supports a variety of other 3D shapes:
  - @ref bs::Plane "Plane"
  - @ref bs::Capsule "Capsule"
  
-We'll let you deduce how they are used from their API reference, as it should be fairly self explanatory. All of the shapes provide a way be initialized, to be transformed by a world matrix as well a set of intersection tests against rays and other shapes.
+How they work should be self explanatory from their API reference. All of the shapes provide a way be initialized, to be transformed by a world matrix as well a set of intersection tests against rays and other shapes.
 
 ~~~~~~~~~~~~~{.cpp}
 // Axis aligned box created from minimum and maximum corners

+ 4 - 4
Documentation/Manuals/Native/User/memory.md

@@ -2,11 +2,11 @@ Memory allocation 						{#memory}
 ===============
 When allocating memory in bs::f it is prefered (but not required) to use bs::f allocator functions instead of the standard *new* / *delete* operators or *malloc* / *free*.
 
-Use @ref bs::bs_new "bs_new" instead of *new* and @ref bs::bs_delete "bs_delete" instead of *delete*.
-Use @ref bs::bs_newN "bs_newN" instead of *new[]* and @ref bs::bs_deleteN "bs_deleteN" instead of *delete[]*.
-Use @ref bs::bs_alloc "bs_alloc" instead of *malloc* and @ref bs::bs_free "bs_free" instead of *free*.
+- Use @ref bs::bs_new "bs_new" instead of *new* and @ref bs::bs_delete "bs_delete" instead of *delete*.
+- Use @ref bs::bs_newN "bs_newN" instead of *new[]* and @ref bs::bs_deleteN "bs_deleteN" instead of *delete[]*.
+- Use @ref bs::bs_alloc "bs_alloc" instead of *malloc* and @ref bs::bs_free "bs_free" instead of *free*.
 
-This ensures the bs::f can keep track of all allocated memory, which ensures better debugging and profiling tools and ensures the internal memory allocation method can be changed in the future.
+This ensures the bs::f can keep track of all allocated memory, which ensures better debugging and profiling, as well as ensuring that internal memory allocation method can be changed in the future.
 
 ~~~~~~~~~~~~~{.cpp}
 // Helper structure

+ 1 - 1
Documentation/Manuals/Native/User/offscreenRendering.md

@@ -6,7 +6,7 @@ When we talked about how to set up a **Camera** component we have shown that we
 We call rendering to a texture offscreen rendering. By rendering offscreen you can achieve advanced graphical effects by manipulating the contents of the rendered-to texture before presenting them to the user. 
 
 # Creation
-Render texture must contain at least one color surface, and may optionally also contain a depth-stencil surface. Both of those surfaces are **Texture** objects, created with either **TU_RENDERTARGET** or **TU_DEPTHSTENCIL** usage flags, respectively, which we talked about earlier. 
+Render texture must contain at least one color surface, and may optionally also contain a depth-stencil surface. Both of those surfaces are **Texture** objects, created with either **TU_RENDERTARGET** or **TU_DEPTHSTENCIL** usage flags, respectively, which we mentioned earlier. 
 
 To create a render texture call @ref bs::RenderTexture::create(const RENDER_TEXTURE_DESC&) "RenderTexture::create()" with a populated @ref bs::RENDER_TEXTURE_DESC "RENDER_TEXTURE_DESC" structure. This structure expects a reference to one or more color surface textures, and an optional depth-stencil surface texture. For each of those you must also specify the face and mip level onto which to render, in case your texture has multiple.
 

+ 1 - 1
Documentation/Manuals/Native/User/profiling.md

@@ -54,7 +54,7 @@ HProfilerOverlay profilerOverlay = profilerOverlaySO->addComponent<CProfilerOver
 ~~~~~~~~~~~~~
 
 ## Threads
-The profiler is thread-safe, but if you are profiling code on threads not managed by the engine, you must manually call @ref bs::ProfilerCPU::beginThread "ProfilerCPU::beginThread" before any sample calls, and @ref bs::ProfilerCPU::endThread "ProfilerCPU::endThread" after all sample calls.
+The profiler is thread-safe, but if you are profiling code on threads not managed by the engine, you must manually call @ref bs::ProfilerCPU::beginThread "ProfilerCPU::beginThread()" before any sample calls, and @ref bs::ProfilerCPU::endThread "ProfilerCPU::endThread()" after all sample calls.
 
 ## Overhead
 Profiler code itself will introduce a certain amount of overhead which will slightly skew profiling results. The profiler attempts to estimate this error, which is reported in the returned reports. You can choose to take this into consideration if you need really precise results.

+ 2 - 2
Documentation/Manuals/Native/User/smartPointers.md

@@ -1,7 +1,7 @@
 Smart pointers						{#smartPointers}
 ===============
 
-Smart pointers allow the user to allocate objects dynamically (i.e. like using *new* or *malloc*), but without having to worry about freeing the object. They are prefered to normal memory allocation as they prevent memory leaks when the user might forget to free memory. They are also very useful in situations when object ownership is not clearly defined and it might not be clear who is responsible for freeing the object, or when.
+Smart pointers allow the user to allocate objects dynamically, but without having to worry about freeing the object. They are prefered to normal memory allocation as they prevent memory leaks when the user might forget to free memory. They are particularily very useful in situations when object ownership is not clearly defined and it might not be clear who is responsible for freeing the object, or when.
 
 # Unique pointers
 Unique pointers hold ownership of a dynamically allocated object, and automatically free it when they go out of scope. As their name implies they cannot be copied - in other words, only one pointer to that object can exist. They are mostly useful for temporary allocations, or for places where object ownership is clearly defined to a single owner.
@@ -50,5 +50,5 @@ SPtr<MyStruct> ptr = bs_shared_ptr_new<MyStruct>(123, false);
 SPtr<MyStruct> anotherPtr = ptr;
 
 // Object will be freed after both "ptr" and "anotherPtr" go out of scope. 
-// Normally you'd want to pass a copy of the pointer to some other system, otherwise we could have used a unique ptr
+// Normally you'd want to pass a copy of the pointer to some other system, otherwise we could have used a unique ptr in this particular example
 ~~~~~~~~~~~~~

+ 26 - 2
Documentation/Manuals/Native/advMemAlloc.md

@@ -69,8 +69,32 @@ bs_frame_mark();
 bs_frame_clear(); // Frees memory for the vector
 ~~~~~~~~~~~~~
 
-# Static allocator {#advMemAlloc_c}
-@ref bs::StaticAlloc<BlockSize, MaxDynamicMemory> "StaticAlloc<BlockSize, MaxDynamicMemory>" is the only specialized type of allocator that is used for permanent allocations. It works by pre-allocating a user-defined number of bytes. It then tries to use this pre-allocated buffer for any allocations requested from it. As long as the number of allocated bytes doesn't exceed the size of the pre-allocated buffer, allocations are basically free. If you exceed the size of the pre-allocated buffer the allocator will fall back on dynamic allocations.
+# Pool allocator {#advMemAlloc_c}
+@ref bs::PoolAlloc<ElemSize, ElemsPerBlock, Alignment> "PoolAlloc<ElemSize, ElemsPerBlock>" is a specialized type of allocator that can be used for permanent allocations. It performs fast allocations with very low fragmentation. Its downside is that it is only able to allocate memory in chunks of specific size, making it suitable for creation of many instances of the same object.
+
+When creating it you need to specify the size of the object you need to allocate, as well as the default number of objects it can contain. If the allocator exceeds the number of objects it can contain it will dynamically allocate another block capable of handling more objects.
+
+~~~~~~~~~~~~~{.cpp}
+struct MyData
+{
+	int foo;
+	float bar;
+};
+
+// Pool allocator capable of holding 128 objects of type MyData
+PoolAlloc<sizeof(MyData), 128> allocator;
+
+// Allocate a single object from the pool
+MyData* obj = (MyData*)allocator.alloc();
+
+// ... do something with the data ...
+
+// When done return the memory back to the pool
+allocator.free(obj);
+~~~~~~~~~~~~~
+
+# Static allocator {#advMemAlloc_d}
+@ref bs::StaticAlloc<BlockSize, MaxDynamicMemory> "StaticAlloc<BlockSize, MaxDynamicMemory>" is a specialized type of allocator that can be used for permanent allocations. It works by pre-allocating a user-defined number of bytes. It then tries to use this pre-allocated buffer for any allocations requested from it. As long as the number of allocated bytes doesn't exceed the size of the pre-allocated buffer, allocations are basically free. If you exceed the size of the pre-allocated buffer the allocator will fall back on dynamic allocations.
 
 The downside of this allocator is that the pre-allocated buffer will be using up memory, whether that memory is is actually required or not. Therefore it is important to predict a good static buffer size so that not much memory is wasted, and that most objects don't exceed the static buffer size. This kind of allocator is mostly useful when you have many relatively small objects, each of which requires dynamic allocation of a different size.
 

+ 0 - 0
Documentation/Manuals/Native/User/advancedRtti.md → Documentation/Manuals/Native/advancedRtti.md


+ 2 - 2
Documentation/Manuals/Native/coreThread.md

@@ -2,9 +2,9 @@ Core Thread								{#coreThread}
 ===============
 [TOC]
 
-bs::f is a multi-threaded engine that has two primary threads. One is the main thread on which the application is started, this is where your game code runs and what majority of users will be working with, we call this the **simulation** thread. The second thread is the rendering thread, this is where all calls to render API (like Vulkan/DirectX/OpenGL) are made. This thread also deals with the OS (like the main message loop). We call this the **core** thread.
+bs::f is a multi-threaded framework that has two primary threads. One is the main thread on which the application is started, this is where your game code runs and what majority of users will be working with, we call this the **simulation** thread. The second thread is the rendering thread, this is where all calls to render API (like Vulkan/DirectX/OpenGL) are made. This thread also deals with the OS (like the main message loop). We call this the **core** thread.
 
-Various other operations can use threads other than the two primary ones (async resource loading, physics, animation, etc.) in the form of worker threads or tasks. But we won't touch on those as they act as standard threads and the system using them has full control.
+Various other operations can use threads other than the two primary ones (async resource loading, physics, animation, etc.) in the form of worker threads or tasks. But we won't touch on those as they act as standard threads and require no special handling.
 
 Dealing with the core thread on the other hand requires some knowledge of how it interacts with the simulation thread. The core threads deals with:
  - Render API calls (Vulkan/DirectX/OpenGL)

+ 1 - 0
Documentation/Manuals/Native/devManuals.md

@@ -26,6 +26,7 @@ Developer manuals									{#devManuals}
 - [Advanced materials](@ref advMaterials)
 - [Threading](@ref threading)
 - [Plugins](@ref plugins)
+- [Advanced RTTI](@ref advancedRtti)
 - **Renderer**
  - [Renderer extensions](@ref rendererExtensions)
  - [Creating a renderer plugin](@ref customRenderer)

+ 1 - 1
Documentation/Manuals/Native/geometry.md

@@ -77,7 +77,7 @@ UINT32 vertexSize = props.getVertexSize(0);
 ~~~~~~~~~~~~~
 
 # Index buffer {#geometry_c}
-Finally, before drawing you want to also bind an index buffer. Index buffers are optional, but you will usually want to use them. Each entry in an index buffer points to a vertex in the vertex buffer, and sequential indexes are used for form primitives for rendering (e.g. every three indices will form a triangle). This ensures you can re-use same vertex in multiple primitives, saving on memory and bandwidth, as well as create more optimal vertex order for GPU processing. Without an index buffer the vertices are instead read sequentially in the order they are defined in the vertex buffer.
+Finally, before drawing you will usually also want to also bind an index buffer. Index buffers are optional, but should be used in most cases. Each entry in an index buffer points to a vertex in the vertex buffer, and sequential indices are used to form primitives for rendering (e.g. every three indices will form a triangle). This ensures you can re-use same vertex in multiple primitives, saving on memory and bandwidth, as well as create more optimal vertex order for GPU processing. Without an index buffer the vertices are instead read sequentially in the order they are defined in the vertex buffer.
 
 To create an index buffer call @ref bs::ct::IndexBuffer::create "ct::IndexBuffer::create()" with a populated @ref bs::INDEX_BUFFER_DESC "INDEX_BUFFER_DESC" structure. The call requires a number of indices and their type. Indices can be either 16- or 32-bit. 
 

+ 4 - 4
Documentation/Manuals/Native/gpuPrograms.md

@@ -12,7 +12,7 @@ In bs::f they are represented with the @ref bs::ct::GpuProgram "ct::GpuProgram"
 To create a GPU program call @ref bs::ct::GpuProgram::create() "ct::GpuProgram::create()" with a @ref bs::GPU_PROGRAM_DESC "GPU_PROGRAM_DESC" structure. The structure needs to have the following fields populated:
  - @ref bs::GPU_PROGRAM_DESC::source "GPU_PROGRAM_DESC::source" - Source code of the GPU program. This should be in a language supported by the current render API (e.g. HLSL for DirectX, GLSL for OpenGL/Vulkan).
  - @ref bs::GPU_PROGRAM_DESC::entryPoint "GPU_PROGRAM_DESC::entryPoint" - Name of the entry point into the GPU program. This is the name of the function that will be called when the program is ran. Must be "main" for OpenGL & Vulkan.
- - @ref bs::GPU_PROGRAM_DESC::language "GPU_PROGRAM_DESC::language" - Language the source code is written in. This can be "hlsl" or "glsl".
+ - @ref bs::GPU_PROGRAM_DESC::language "GPU_PROGRAM_DESC::language" - Language the source code is written in. This can be "hlsl", "glsl" or "vksl".
  - @ref bs::GPU_PROGRAM_DESC::type "GPU_PROGRAM_DESC::type" - @ref bs::GpuProgramType "GpuProgramType" of the GPU program (vertex, fragment, etc.).
  
 For example if we wanted to create a HLSL fragment program (HLSL source not shown):
@@ -95,7 +95,7 @@ You generally don't need to use this information directly. It is instead automat
 
 ## GpuParams {#gpuPrograms_c_a}
 **GpuParams** is a container for all parameters required by a single GPU pipeline (graphics or compute). It allows you to set primitive/texture/sampler/buffer parameters used by the GPU programs, which it stores in an internal buffer. You can then bind it
-to a **RenderAPI** similar to how you bind the pipeline themselves. Assigned parameter will then be using with the current pipeline in any following *draw* or *dispatch* calls.
+to a **RenderAPI** similar to how you bind the pipeline themselves. Assigned parameter will then be used with the current pipeline in any following *draw* or *dispatch* calls.
 
 To create a **GpuParams** object call @ref bs::ct::GpuParams::create "ct::GpuParams::create()" with either a graphics or a compute pipeline state as a parameter.
 
@@ -190,7 +190,7 @@ params->setParamBlockBuffer(GPT_FRAGMENT_PROGRAM, "myParamBlock", buffer);
 
 After it is bound you we free to set primitive parameters and they will be stored in the bound buffer. This buffer can then be shared between multiple GPU programs and/or GPU pipelines.
 
-> You can also write to **GpuParamBlockBuffer** directly by calling its @ref bs::ct::GpuParamBlockBuffer::write "ct::GpuParamBlockBuffer::write()" method. In this case you must be careful to respect the layout of the variables in the buffer as expected by the shader. This layout can be determined by examining the other entries in **GpuParamDesc** structure.
+> You can also write to **GpuParamBlockBuffer** directly by calling its @ref bs::ct::GpuParamBlockBuffer::write "ct::GpuParamBlockBuffer::write()" method. In this case you must be careful to respect the layout of the variables in the buffer as expected by the render backend. This layout can be determined by examining the other entries in **GpuParamDesc** structure.
 
 ## Binding GPU params {#gpuPrograms_c_c}
 Once **GpuParams** has been created and populated with necessary data, you can bind it to the GPU by calling @ref bs::ct::RenderAPI::setGpuParams "ct::RenderAPI::setGpuParams()". 
@@ -212,7 +212,7 @@ Input declaration can be used for creating meshes or vertex buffers that provide
 
 > Note: This method is only available on the core thread version of **GpuProgram**.
 
-## GLSL specifics {#gpuPrograms_d_a}
+# GLSL specifics {#gpuPrograms_e}
 When declaring vertex inputs for a GPU program written in GLSL you should use the following variable names depending on the input usage:
  - bs_position - Vertex position
  - bs_normal - Vertex normal

+ 0 - 3
Documentation/Manuals/Native/manuals.md

@@ -74,6 +74,3 @@ User manuals									{#manuals}
  - [Measuring time](@ref time)
  - [Cursors](@ref cursors)
  - [Profiling](@ref cpuProfiling)
-- **Other**
- - [Advanced RTTI](@ref advancedRtti)
- - [Prefabs](@ref prefabs)

+ 3 - 3
Documentation/Manuals/Native/renderTargets.md

@@ -26,19 +26,19 @@ rapi.setViewport(Rect2(0.25f, 0.25f, 0.5f, 0.5f));
 
 ## Advanced binding {#renderTargets_a_a}
 **ct::RenderAPI::setRenderTarget()** also has a couple of parameters to control more advanced behaviour:
- - @p readOnlyDepthStencil - Guarantees that the depth/stencil portion of the render target will not be written to. This allows the depth/stencil texture to be bound both as a render target, as well as a normal GPU program input.
+ - @p readOnlyFlags - Combination of one or more elements of @ref bs::FrameBufferType "FrameBufferType" denoting which buffers will be bound for read-only operations. This is useful for depth or stencil buffers which need to be bound both for depth/stencil tests, as well as shader reads. If you don't specify this the render backend will assume you will be writing to the render target which will result in undefined behaviour if you also try reading from that same texture.
  - @p loadMask - Mask described by @ref bs::RenderSurfaceMaskBits "RenderSurfaceMaskBits" which controls if current contents of any of the render target surfaces should be preserved. By default the system doesn't guarantee the contents will be preserved and data is instead undefined. In certain cases (like blending operations) you want to preserve the contents, in which case specify the necessary flags to tell the system which surfaces need their contents preserved.
 
 ~~~~~~~~~~~~~{.cpp}
 // Bind a render target with read-only depth/stencil, and preserve the existing contents of depth-stencil buffer on bind
 RenderAPI& rapi = RenderAPI::instance();
-rapi.setRenderTarget(target, true, RT_DEPTH);
+rapi.setRenderTarget(target, FBT_DEPTH | FBT_STENCIL, RT_DEPTH_STENCIL);
 ~~~~~~~~~~~~~
  
 # Clearing {#renderTargets_b}
 Usually a render target will be re-used many times. Unless you are sure that every use will completely overwrite the render target contents, it can be beneficial (and in some cases necessary) to clear the render target to some value. Call @ref bs::ct::RenderAPI::clearRenderTarget "ct::RenderAPI::clearRenderTarget()" to clear the currently bound render target. 
 
-The first parameter represents a @ref bs::FrameBufferType "FrameBufferType" of which portions of the target to clear. Second, third and fourth parameters represent the clear values for the color, depth and stencil surfaces, respectively. In case you want to clear only a specific color surface (in case they are multiple), you can use the fifth parameter as a bitmask of which color surfaces to clear.
+The first parameter represents a **FrameBufferType** of which portions of the target to clear. Second, third and fourth parameters represent the clear values for the color, depth and stencil surfaces, respectively. In case you want to clear only a specific color surface (in case they are multiple), you can use the fifth parameter as a bitmask of which color surfaces to clear.
 
 ~~~~~~~~~~~~~{.cpp}
 // Clear color and depth surfaces. All color surfaces are cleared to blue color, while depth is cleared to the value of 1

+ 1 - 1
Source/BansheeEditor/SceneView/BsScenePicking.cpp

@@ -62,7 +62,7 @@ namespace bs
 		{
 			Matrix3 rotation;
 			selectedObjects[0]->getTransform().getRotation().toRotationMatrix(rotation);
-			data->normal = rotation.inverse().transpose().transform(data->normal);
+			data->normal = rotation.inverse().transpose().multiply(data->normal);
 		}
 		
 		return selectedObjects[0];

+ 1 - 1
Source/BansheeUtility/Math/BsMatrix3.cpp

@@ -138,7 +138,7 @@ namespace bs
 		return prod;
 	}
 
-	Vector3 Matrix3::transform(const Vector3& vec) const
+	Vector3 Matrix3::multiply(const Vector3& vec) const
 	{
 		Vector3 prod;
 		for (UINT32 row = 0; row < 3; row++)

+ 1 - 1
Source/BansheeUtility/Math/BsMatrix3.h

@@ -147,7 +147,7 @@ namespace bs
 		friend Matrix3 operator* (float lhs, const Matrix3& rhs);
 
 		/** Transforms the given vector by this matrix and returns the newly transformed vector. */
-		Vector3 transform(const Vector3& vec) const;
+		Vector3 multiply(const Vector3& vec) const;
 
 		/** Returns a transpose of the matrix (switched columns and rows). */
 		Matrix3 transpose () const;

+ 1 - 1
Source/BansheeUtility/Math/BsMatrix4.cpp

@@ -244,7 +244,7 @@ namespace bs
 
 		// Make the translation relative to new axes
 		Matrix3 rotT = rot.transpose();
-		Vector3 trans = (-rotT).transform(position);
+		Vector3 trans = (-rotT).multiply(position);
 
 		// Make final matrix
 		*this = Matrix4(rotT);

+ 1 - 1
Source/BansheeUtility/Math/BsPlane.cpp

@@ -103,7 +103,7 @@ namespace bs
 		xform[2][0] = -normal.z * normal.x;
 		xform[2][1] = -normal.z * normal.y;
 		xform[2][2] = 1.0f - normal.z * normal.z;
-		return xform.transform(point);
+		return xform.multiply(point);
 
 	}
 

+ 1 - 1
Source/BansheeUtility/Math/BsQuaternion.cpp

@@ -276,7 +276,7 @@ namespace bs
 		//       an intermediate matrix.
 		Matrix3 rot;
 		toRotationMatrix(rot);
-		return rot.transform(v);
+		return rot.multiply(v);
 	}
 
 	void Quaternion::lookRotation(const Vector3& forwardDir)

+ 140 - 140
Source/BansheeUtility/Math/BsVector2I.h

@@ -21,12 +21,12 @@ namespace bs
 		{ }
 
 		inline Vector2I(INT32 _x, INT32 _y )
-            :x(_x), y(_y)
-        { }
+			:x(_x), y(_y)
+		{ }
 
-        explicit Vector2I(int val)
-            :x(val), y(val)
-        { }
+		explicit Vector2I(int val)
+			:x(val), y(val)
+		{ }
 
 		/** Exchange the contents of this vector with another. */
 		void swap(Vector2I& other)
@@ -42,26 +42,26 @@ namespace bs
 		}
 
 		INT32 operator[] (size_t i) const
-        {
-            assert(i < 2);
+		{
+			assert(i < 2);
 
-            return *(&x+i);
-        }
+			return *(&x+i);
+		}
 
 		INT32& operator[] (size_t i)
-        {
-            assert(i < 2);
+		{
+			assert(i < 2);
 
-            return *(&x+i);
-        }
+			return *(&x+i);
+		}
 
-        Vector2I& operator= (const Vector2I& rhs)
-        {
-            x = rhs.x;
-            y = rhs.y;
+		Vector2I& operator= (const Vector2I& rhs)
+		{
+			x = rhs.x;
+			y = rhs.y;
 
-            return *this;
-        }
+			return *this;
+		}
 
 		Vector2I& operator= (int val)
 		{
@@ -71,129 +71,129 @@ namespace bs
 			return *this;
 		}
 
-        bool operator== (const Vector2I& rhs) const
-        {
-            return (x == rhs.x && y == rhs.y);
-        }
+		bool operator== (const Vector2I& rhs) const
+		{
+			return (x == rhs.x && y == rhs.y);
+		}
+
+		bool operator!= (const Vector2I& rhs) const
+		{
+			return (x != rhs.x || y != rhs.y);
+		}
+
+		Vector2I operator+ (const Vector2I& rhs) const
+		{
+			return Vector2I(x + rhs.x, y + rhs.y);
+		}
+
+		Vector2I operator- (const Vector2I& rhs) const
+		{
+			return Vector2I(x - rhs.x, y - rhs.y);
+		}
+
+		Vector2I operator* (int val) const
+		{
+			return Vector2I(x * val, y * val);
+		}
+
+		Vector2I operator* (const Vector2I& rhs) const
+		{
+			return Vector2I(x * rhs.x, y * rhs.y);
+		}
+
+		Vector2I operator/ (int val) const
+		{
+			assert(val != 0);
+
+			return Vector2I(x / val, y / val);
+		}
+
+		Vector2I operator/ (const Vector2I& rhs) const
+		{
+			return Vector2I(x / rhs.x, y / rhs.y);
+		}
+
+		const Vector2I& operator+ () const
+		{
+			return *this;
+		}
+
+		Vector2I operator- () const
+		{
+			return Vector2I(-x, -y);
+		}
+
+		friend Vector2I operator* (int lhs, const Vector2I& rhs)
+		{
+			return Vector2I(lhs * rhs.x, lhs * rhs.y);
+		}
+
+		friend Vector2I operator/ (int lhs, const Vector2I& rhs)
+		{
+			return Vector2I(lhs / rhs.x, lhs / rhs.y);
+		}
+
+		Vector2I& operator+= (const Vector2I& rhs)
+		{
+			x += rhs.x;
+			y += rhs.y;
+
+			return *this;
+		}
+
+		Vector2I& operator-= (const Vector2I& rhs)
+		{
+			x -= rhs.x;
+			y -= rhs.y;
+
+			return *this;
+		}
+
+		Vector2I& operator*= (INT32 val)
+		{
+			x *= val;
+			y *= val;
 
-        bool operator!= (const Vector2I& rhs) const
-        {
-            return (x != rhs.x || y != rhs.y);
-        }
-
-        Vector2I operator+ (const Vector2I& rhs) const
-        {
-            return Vector2I(x + rhs.x, y + rhs.y);
-        }
-
-        Vector2I operator- (const Vector2I& rhs) const
-        {
-            return Vector2I(x - rhs.x, y - rhs.y);
-        }
-
-        Vector2I operator* (int val) const
-        {
-            return Vector2I(x * val, y * val);
-        }
-
-        Vector2I operator* (const Vector2I& rhs) const
-        {
-            return Vector2I(x * rhs.x, y * rhs.y);
-        }
-
-        Vector2I operator/ (int val) const
-        {
-            assert(val != 0);
-
-            return Vector2I(x / val, y / val);
-        }
-
-        Vector2I operator/ (const Vector2I& rhs) const
-        {
-            return Vector2I(x / rhs.x, y / rhs.y);
-        }
-
-        const Vector2I& operator+ () const
-        {
-            return *this;
-        }
-
-        Vector2I operator- () const
-        {
-            return Vector2I(-x, -y);
-        }
-
-        friend Vector2I operator* (int lhs, const Vector2I& rhs)
-        {
-            return Vector2I(lhs * rhs.x, lhs * rhs.y);
-        }
-
-        friend Vector2I operator/ (int lhs, const Vector2I& rhs)
-        {
-            return Vector2I(lhs / rhs.x, lhs / rhs.y);
-        }
-
-        Vector2I& operator+= (const Vector2I& rhs)
-        {
-            x += rhs.x;
-            y += rhs.y;
-
-            return *this;
-        }
-
-        Vector2I& operator-= (const Vector2I& rhs)
-        {
-            x -= rhs.x;
-            y -= rhs.y;
-
-            return *this;
-        }
-
-        Vector2I& operator*= (INT32 val)
-        {
-            x *= val;
-            y *= val;
-
-            return *this;
-        }
-
-        Vector2I& operator*= (const Vector2I& rhs)
-        {
-            x *= rhs.x;
-            y *= rhs.y;
-
-            return *this;
-        }
-
-        Vector2I& operator/= (INT32 val)
-        {
-            assert(val != 0);
-
-            x /= val;
-            y /= val;
-
-            return *this;
-        }
-
-        Vector2I& operator/= (const Vector2I& rhs)
-        {
-            x /= rhs.x;
-            y /= rhs.y;
-
-            return *this;
-        }
-
-        /** Returns the square of the length(magnitude) of the vector. */
-        INT32 squaredLength() const
-        {
-            return x * x + y * y;
-        }
-
-        /** Calculates the dot (scalar) product of this vector with another. */
+			return *this;
+		}
+
+		Vector2I& operator*= (const Vector2I& rhs)
+		{
+			x *= rhs.x;
+			y *= rhs.y;
+
+			return *this;
+		}
+
+		Vector2I& operator/= (INT32 val)
+		{
+			assert(val != 0);
+
+			x /= val;
+			y /= val;
+
+			return *this;
+		}
+
+		Vector2I& operator/= (const Vector2I& rhs)
+		{
+			x /= rhs.x;
+			y /= rhs.y;
+
+			return *this;
+		}
+
+		/** Returns the square of the length(magnitude) of the vector. */
+		INT32 squaredLength() const
+		{
+			return x * x + y * y;
+		}
+
+		/** Calculates the dot (scalar) product of this vector with another. */
 		INT32 dot(const Vector2I& vec) const
-        {
-            return x * vec.x + y * vec.y;
-        }
+		{
+			return x * vec.x + y * vec.y;
+		}
 
 		static const Vector2I ZERO;
 	};