浏览代码

More work on user-facing manuals

BearishSun 9 年之前
父节点
当前提交
4d85ab293d

二进制
Documentation/Manuals/Native/Images/DragonWireframe.png


+ 115 - 0
Documentation/Manuals/Native/User/importingMeshes.md

@@ -0,0 +1,115 @@
+Importing meshes 						{#importingMeshes}
+===============
+
+Meshes are used for defining surfaces of 2D and 3D objects, and are the primary building blocks of the scene. They are represented with a set of vertices and triangles. Those vertices and triangles are then transformed by the graphics card when rendering, by converting them to pixels on the screen. 
+
+Each vertex can have one or multiple properties like texture coordinates (used for mapping textures onto mesh surface), normals, tangents, and at minimum, a position property. These properties are used by materials for customizing how a mesh is rendered (explained later).
+
+Vertices are connected into triangles via indices, where every three sequential indices specify which three vertices form a triangle. That information is then used by the graphics card for rendering.
+
+In Banshee meshes are represented with the @ref bs::Mesh "Mesh" class. A mesh is a resource, meaning it can be imported, saved and loaded as we described in the Resource manuals.
+
+![Wireframe mesh](DragonWireframe.png) 
+
+# Importing a mesh
+Meshes can be imported from various third party formats, using the importer.
+
+~~~~~~~~~~~~~{.cpp}
+// Import a mesh named "dragon.fbx" from the disk
+HMesh mesh = gImporter().import<Mesh>("dragon.fbx");
+~~~~~~~~~~~~~
+
+Supported formats are:
+ - FBX
+ - DAE
+ - OBJ
+ 
+# Mesh properties
+Once a mesh has been imported, you can retrieve its properties like vertex & index counts, as well as its bounds by calling @ref bs::Mesh::getProperties "Mesh::getProperties()", which returns a @ref bs::MeshProperties "MeshProperties" object.
+
+~~~~~~~~~~~~~{.cpp}
+// Retrieve and print out various mesh properties
+auto& props = mesh->getProperties();
+
+gDebug().logDebug("Num. vertices: " + toString(props.getNumVertices()));
+gDebug().logDebug("Num. indices: " + toString(props.getNumIndices()));
+gDebug().logDebug("Radius: " + toString(props.getBounds().getSphere().getRadius()));
+~~~~~~~~~~~~~
+
+# Rendering meshes
+**Mesh** can be assigned to a **Renderable** component, along with a **Material** in order to be rendered. We'll cover rendering in a later chapter.
+
+# Customizing import
+Mesh import can be customized by providing a @ref bs::MeshImportOptions "MeshImportOptions" object to the importer.
+
+~~~~~~~~~~~~~{.cpp}
+auto importOptions = MeshImportOptions::create();
+// Set required options here (as described below)
+
+HMesh mesh = gImporter().import<Mesh>("dragon.fbx", importOptions);
+~~~~~~~~~~~~~
+
+Lets see some of the options you can use for customizing import.
+
+## Scale
+@ref bs::MeshImportOptions::setImportScale "MeshImportOptions::setImportScale" allows you to apply a uniform scale value to the mesh upon import. Although you can scale the size of a rendered mesh by adjusting the **SceneObject** transform when its placed in the scene, sometimes it is more useful to be able to do it once at import instead of every time you place it.
+
+~~~~~~~~~~~~~{.cpp}
+// Reduce the size of the mesh to 10% of its original size
+importOptions->setImportScale(0.1f);
+~~~~~~~~~~~~~
+
+## Normals
+@ref bs::MeshImportOptions::setImportNormals "MeshImportOptions::setImportNormals" controls whether normal vectors are imported from the mesh file. 
+
+Normal vectors are used in lighting and are required for any meshes placed in the 3D scene (unless rendering them manually using some custom method). They allow the mesh to appear smooth even though its surface is made out of triangles.
+
+Most 3D authoring tools generate normals for their meshes, but if normals are not present in the mesh file, Banshee will attempt to generate normals automatically when this option is turned on.
+
+~~~~~~~~~~~~~{.cpp}
+// Import or generate normals for the mesh
+importOptions->setImportNormals(true);
+~~~~~~~~~~~~~
+
+## Tangent
+@ref bs::MeshImportOptions::setImportTangents "MeshImportOptions::setImportTangents" controls whether tangent vectors are imported from the mesh file. 
+
+Tangent vectors (along with normal vectors) are required if your rendering shader uses normal maps. Similar to normals, if tangents are not present in the mesh file, Banshee will attempt to generate them automatically.
+
+~~~~~~~~~~~~~{.cpp}
+// Import or generate normals for the mesh
+importOptions->setImportTangents(true);
+~~~~~~~~~~~~~
+
+## Caching
+Similar as with textures, sometimes you need to import a mesh you don't want to only use for rendering, but rather for manually reading its contents. When that's the case you can enable the @ref bs::MeshImportOptions::setCPUCached "MeshImportOptions::setCPUCached" option.
+
+This will allow you to call @ref bs::Mesh::readCachedData "Mesh::readCachedData" and to manually read individual vertices and indices of the mesh.
+
+Note that caching a mesh means its data will be available in system memory, essentially doubling its memory usage.
+
+~~~~~~~~~~~~~{.cpp}
+// Enable caching
+importOptions->setCPUCached(true);
+
+// Import mesh
+HMesh mesh = gImporter().import<Mesh>("dragon.fbx", importOptions);
+
+// Allocate a buffer to hold mesh contents
+//// Specify vertex properties. Assuming just a single property of a 3D position
+SPtr<VertexDataDesc> vertexDesc = VertexDataDesc::create();
+vertexDesc->addVertElem(VET_FLOAT3, VES_POSITION);
+
+//// Create enough room for 8 vertices of specified properties, and 36 indices (12 triangles)
+SPtr<MeshData> meshData = MeshData::create(8, 36, vertexDesc);
+
+// Read cached data
+mesh->readCachedData(*meshData);
+
+// Read vertex positions
+Vector<Vector3> vertices(8);
+meshData->getVertexData(VES_POSITION, vertices.data(), vertices.size() * sizeof(Vector3));
+...
+~~~~~~~~~~~~~
+
+> We will explain **MeshData** and mesh manipulation in detail, in a later chapter.

+ 76 - 16
Documentation/Manuals/Native/User/importingTextures.md

@@ -1,7 +1,7 @@
 Importing textures 						{#importingTextures}
 Importing textures 						{#importingTextures}
 ===============
 ===============
 
 
-Textures are images that are applied to meshes in order to achieve greater surface detail. In Banshee they are represented with the @ref bs::Texture "Texture" class. A texture is a resource, meaning it can be imported, saved and loaded as we described in Resource manuals.
+Textures are images that are applied to meshes in order to achieve greater surface detail. In Banshee they are represented with the @ref bs::Texture "Texture" class. A texture is a resource, meaning it can be imported, saved and loaded as we described in the Resource manuals.
 
 
 ![Mesh without (left) and with (right) a texture](TexturedMesh.png)  
 ![Mesh without (left) and with (right) a texture](TexturedMesh.png)  
 
 
@@ -27,6 +27,22 @@ Supported formats are:
  - TARGA
  - TARGA
  - TIFF
  - TIFF
  
  
+# Texture properties
+Once a texture has been imported, you can retrieve its properties like width, height and format by calling @ref bs::Texture::getProperties "Texture::getProperties()", which returns a @ref bs::TextureProperties "TextureProperties" object.
+
+~~~~~~~~~~~~~{.cpp}
+// Retrieve and print out various texture properties
+auto& props = texture->getProperties();
+
+gDebug().logDebug("Width: " + toString(props.getWidth()));
+gDebug().logDebug("Height: " + toString(props.getHeight()));
+gDebug().logDebug("Format: " + toString(props.getFormat()));
+gDebug().logDebug("Num. mip maps: " + toString(props.getNumMipmaps()));
+~~~~~~~~~~~~~
+
+# Rendering using textures
+Once imported a texture can be assigned to a **Material** in order to be used for rendering. We will cover materials in a later chapter. 
+ 
 # Customizing import
 # Customizing import
 Texture import can be customized by providing a @ref bs::TextureImportOptions "TextureImportOptions" object to the importer.
 Texture import can be customized by providing a @ref bs::TextureImportOptions "TextureImportOptions" object to the importer.
 
 
@@ -40,29 +56,73 @@ HTexture texture = gImporter().import<Texture>("myTexture.jpg", importOptions);
 A variety of properties can be customized on import, the most important of which being image format, mip-map generation, sRGB state and caching.
 A variety of properties can be customized on import, the most important of which being image format, mip-map generation, sRGB state and caching.
 
 
 ## Image format
 ## Image format
-// TODO
+@ref bs::TextureImportOptions::setFormat "TextureImportOptions::setFormat" allows you to specify which format should the texture pixels be in after import. Any of the formats provided in @ref bs::PixelFormat "PixelFormat" are supported.
+
+~~~~~~~~~~~~~{.cpp}
+// Set format as uncompressed RGB with an alpha channel
+importOptions->setFormat(PF_R8G8B8A8);
+~~~~~~~~~~~~~
 
 
+Formats can be split into two main categories:
+ - Uncompressed - Contain raw texture data with no quality loss, but with high memory cost. Great for textures used on 2D elements like GUI or sprites, for which compressed formats normally introduce visible artifacts.
+ - Compressed - Compressed texture data with a slight quality loss, but with considerably smaller (~4x) memory cost compared to raw texture data. Great for textures used on 3D surfaces in the scene.
+
+Some of most common formats are:
+ - PF_R8G8B8 - Uncompressed RGB data, without an alpha channel. 
+ - PF_R8G8B8A8 - Uncompressed RGB data, with an alpha channel. 
+ - PF_BC1 - Compressed RGB data, without an alpha channel. 
+ - PF_BC3 - Compressed RGB data, with an alpha channel. 
+ - PF_BC5 - Compressed 2-channel format. 
+ 
+> If importing normal maps, use the BF_BC5 format as other compression formats produce visible artifacts in the normal map. Optionally if memory is not a concern, use an uncompressed format.
+ 
 ## Mip-maps
 ## Mip-maps
-// TODO
+@ref bs::TextureImportOptions::setGenerateMipmaps "TextureImportOptions::setGenerateMipmaps" allows you to specify should mip-maps for the texture be generated. Mipmaps ensure that textures applied to 3D surfaces look good when they're viewed from far away (i.e. when the pixel size they take up on screen is considerably less than the actual texture resolution).
 
 
-## sRGB
-// TODO
+Enabling mip-maps will increase the memory use of the texture by 33%, but it is pretty much essential for any texture applied on a 3D object. It should not be enabled for textures used on 2D elements like GUI or sprites, as it will have no benefit.
+
+~~~~~~~~~~~~~{.cpp}
+// Enable mipmap generation
+importOptions->setGenerateMipmaps(true);
+~~~~~~~~~~~~~
+
+## Gamma correction
+Most images output by modern cameras and image editing software will be stored in what's called a gamma (sRGB) space. This ensures that the image has more quality in the blacks, but it does not represent the actual image you see on the screen (when you open it in some image viewing program). This is because your monitor performs gamma-correction on the image, before displaying it to you.
+
+However game engines don't like their data in gamma space, because it's not linear which means that all lighting and similar operations don't operate exactly as they should. Essentially the image ends up looking more "washed-out" than it should.
+
+For this reason Banshee provides @ref bs::TextureImportOptions::setSRGB "TextureImportOptions::setSRGB" toggle, which you can set for images in gamma (sRGB) space. The engine will then know to convert to linear space before performing any relevant operations, ensuring the final rendering looks good.
+
+~~~~~~~~~~~~~{.cpp}
+// Tell the engine this image is in gamma space
+importOptions->setSRGB(true);
+~~~~~~~~~~~~~
+
+> How do you know when an image is in gamma space and when in linear space? As a general rule an albedo (diffuse) images are in gamma space, and normal maps are in linear space. For other types of images you need to consult the tool you use to create/save them, but in most cases they will be in gamma space.
 
 
 ## Caching
 ## Caching
-// TODO
+Sometimes you need to import a texture you don't want to only use for rendering, but rather for manually reading its contents. When that's the case you can enable the @ref bs::TextureImportOptions::setCPUCached "TextureImportOptions::setCPUCached" option.
 
 
-# Texture properties
-Once a texture has been imported, you can retrieve its properties like width, height and format by calling @ref bs::Texture::getProperties "Texture::getProperties()", which returns a @ref bs::TextureProperties "TextureProperties" object.
+This will allow you to call @ref bs::Texture::readCachedData "Texture::readCachedData" and to manually read individual pixels of the texture.
+
+Note that caching a texture means its data will be available in system memory, essentially doubling its memory usage.
 
 
 ~~~~~~~~~~~~~{.cpp}
 ~~~~~~~~~~~~~{.cpp}
-// Retrieve and print out various texture properties
-auto& props = texture->getProperties();
+// Enable caching
+importOptions->setCPUCached(true);
 
 
-gDebug().logDebug("Width: " + toString(props.getWidth()));
-gDebug().logDebug("Height: " + toString(props.getHeight()));
-gDebug().logDebug("Format: " + toString(props.getFormat()));
-gDebug().logDebug("Num. mip maps: " + toString(props.getNumMipmaps()));
+// Import texture
+HTexture texture = gImporter().import<Texture>("myTexture.jpg", importOptions);
+
+// Allocate a buffer to hold texture contents
+SPtr<PixelData> pixelData = PixelData::create(1024, 1024, 1, PF_R8G8B8A8);
+
+// Read cached data
+texture->readCachedData(*pixelData);
+
+// Read pixels
+Color color = pixelData->getColorAt(50, 50);
+...
 ~~~~~~~~~~~~~
 ~~~~~~~~~~~~~
 
 
-# Rendering using textures
-Once imported a texture can be assigned to a **Material** in order to be used for rendering. We will cover materials in a later chapter.
+> We will explain **PixelData** and texture manipulation in general, in a later chapter.

+ 24 - 0
Documentation/Manuals/Native/User/simpleMaterial.md

@@ -0,0 +1,24 @@
+Materials 						{#simpleMaterial}
+===============
+
+Materials are objects that control how are objects rendered. They are represented using the @ref bs::Material "Material" class. For example, if you wish to render a mesh with a texture, you must create a material that supports textures, bind the texture to the material and bind both to a **Renderable** which will then render the mesh using the supplied material.
+
+Internally material contains a **Shader** and a set of parameters. A **Shader** object must be provided on material contruction, while parameters can be set during program execution.
+
+A shader is a group of GPU programs and render states that fully control the rendering of an object. Shader also exposes a set of parameters the user can change in order to control the operation of the GPU programs. Which parametes are available is controlled by the GPU programs themselves. We will delay further discussion of shaders and GPU programs until later, and for examples in this chapter we will use one of the shaders built into Banshee.
+
+The parameters exposed by the shader can be modified by the interface provided by the material - in fact the main task of the **Material** class is to provide methods for setting those parameters. Essentially materials can be thought of as shader "instances", and shaders can be tought of material "templates". There is always a one shader object (per type), and multiple material instances of that shader, each with different parameters. 
+
+# Material creation
+To create a material use the @ref bs::Material::create "Material::create" method, which expects a **Shader** as a parameter.
+
+~~~~~~~~~~~~~{.cpp}
+HShader shader = gBuiltinResources().getBuiltinShader(BuiltinShader::Standard);
+HMaterial material = Material::create(shader);
+~~~~~~~~~~~~~
+
+# Setting parameters
+
+// TODO
+
+

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

@@ -14,6 +14,7 @@ Manuals									{#manuals}
  - [Cameras](@ref cameras)
  - [Cameras](@ref cameras)
  - [Importing textures](@ref importingTextures)
  - [Importing textures](@ref importingTextures)
  - [Importing meshes](@ref importingMeshes)
  - [Importing meshes](@ref importingMeshes)
+ - [Materials](@ref simpleMaterials)
  
  
 # Developer guides
 # Developer guides
 
 

+ 1 - 1
Source/BansheeEngine/Include/BsBuiltinResources.h

@@ -87,7 +87,7 @@ namespace bs
 		/**	Returns the default application icon. */
 		/**	Returns the default application icon. */
 		const PixelData& getBansheeIcon();
 		const PixelData& getBansheeIcon();
 
 
-		/**	Returns a shader used for rendering only a diffuse texture. */
+		/**	Returns one of the builtin shader types. */
 		HShader getBuiltinShader(BuiltinShader type) const;
 		HShader getBuiltinShader(BuiltinShader type) const;
 
 
 		/**	Creates a material used for textual sprite rendering (for example text in GUI). */
 		/**	Creates a material used for textual sprite rendering (for example text in GUI). */

+ 3 - 0
Source/BansheeGLRenderAPI/Source/BsGLRenderAPI.cpp

@@ -1460,6 +1460,9 @@ namespace bs
 
 
 	void GLRenderAPI::setScissorTestEnable(bool enable)
 	void GLRenderAPI::setScissorTestEnable(bool enable)
 	{
 	{
+		if (mActiveRenderTarget == nullptr)
+			return;
+
 		const RenderTargetProperties& rtProps = mActiveRenderTarget->getProperties();
 		const RenderTargetProperties& rtProps = mActiveRenderTarget->getProperties();
 
 
 		// If request texture flipping, use "upper-left", otherwise use "lower-left"
 		// If request texture flipping, use "upper-left", otherwise use "lower-left"