\\ Home : Articoli : Stampa
Texture and Resources
Di robydx (del 19/06/2008 @ 20:48:11, in English, linkato 5305 volte)

DirectX memorizes all its resources in memory buffers. We have already seen some types of resources, like vertex buffer.

A fundamental type of resource is now the texture. A texture is a resource which aim is managing images used to cover 3D models. Their utility is enough obvious. We use triangles in order to simulate the shape of an object, and if we would represent every single detail of an object using triangles, their number would be too much high even for a DirectX10 Video card. Then many details that don’t need a depth are represented on a bitmap image wrapped around our object. In this way, an hypothetic snake will be a tube with an image of its skin applied on the model, and won’t have a polygon for each scale. This technique saves the performances of our application both on polygons and on eventual colour or lighting effects.

There are many types of textures, and for each one different way of use.

In DirectX10 there are 3 types of textures, everyone derived from ID3D10Resource class:

ID3D10Texture1D

ID3D10Texture2D

ID3D10Texture3D

The first one represents an image 1 pixel high and with variable length. The second is the classic Bitmap with variable height and length. Finally the third one represent a collection of images put one upon the other.

A texture is loaded from file (generally bitmaps or dedicated formats).

D3D10CreateTextureFromFile(device, pathOfTheFile, info, NULL, &texture);

The arguments are a device, the path of the file, an info structure, an ID3DX10ThreadPump class (it is used to load a texture asynchronously, and will be the subject for other tutorials in the future), and the object to load.

Info is a structure of this type:

D3DX10_IMAGE_LOAD_INFO

Passing this structure allows to modify the image while loading it. Its parameters are the following one:

· Width: the desired length, or 0 if we want the original image length;

· Height: the desired height, or 0 if we want the original image height;

· Depth: the desired depth, or 0 if we want the original image depth:

· FisrtMipLevel: max mipmap level resolution (see more on);

· MipLevels: number of mip levels;

· Usage: the usage of the texture. It is very important because a texture has many usages in DirectX10. This is a D3D10_USAGE enum;

· BindFlags: specify the usage of the resource. In case of texture D3D10_BIND_SHADER_RESOURCE;

· CpuAccessFlags: set the access way to the resource;

· MiscFlag: extra attributes;

· Format: colour format to use;

· Filter: set the way the image will be scaled;

· MipFilter: the way the mip levels are created;

· pSrcInfo: it contains an other D3DX10_IMAGE_LOAD_INFO structure obtained from the D3DX10GetImageInfoFromFile instruction. It contains the original image format in order to allow DirectX to make the right transformations.

Now use D3D10_USAGE_DEFAULT for the usage and 0 for the CpuAccesFlags. I will explain the usage of this details in the memory access tutorial.

Filters, instead, represents the algorithm used when an image is rescaled. The better filter quality, the better the yield, but the worst performances (in this case only while loading).

· D3DX10_FILTER_POINT

· D3DX10_FILTER_LINEAR

· D3DX10_FILTER_TRIANGLE

· D3DX10_FILTER_BOX

· D3DX10_FILTER_MIRROR_U

· D3DX10_FILTER_MIRROR_V

· D3DX10_FILTER_MIRROR_W

· D3DX10_FILTER_MIRROR

With mip (minus in parvis) we mean a DirectX technology consisting in inserting smaller and then smaller copies of the image into the texture (every level dimension is half of the previous). Mip is used with distant objects, which don’t need the max possible texture resolution, so DirectX automatically will use a lower level detail, saving resources. We can specify the number of mip and their settings through the load info structure.

Once a texture is loaded, it is keep in memory for device usages. But it cannot be used directly in shaders (as in DirectX9) without being associated with a “view”. With view I mean a manager which let the passage of buffers towards the shaders.

D3D10_TEXTURE2D_DESC desc;

texture ->GetDesc( &desc );

D3D10_SHADER_RESOURCE_VIEW_DESC viewDesc;

ZeroMemory( & viewDesc, sizeof(viewDesc) );

viewDesc.Format = desc.Format;

viewDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;

viewDesc.Texture2D.MipLevels = desc.MipLevels;

ID3D10ShaderResourceView* textureView;

device->CreateShaderResourceView( texture, & viewDesc, &textureView);

Using GetDesc we obtain the texture description used to create the viewDesc (we need format, dimension and number of mip levels information).

The view will be passed to the shader.

It is even possible to create the resources in a faster way:

D3DX10CreateShaderResourceViewFromFile(device, filePath, textureView);

If then you need the texture, simply use GetResource.

Texture coordinates system

In DirectX a texture is not managed in pixel, but in texture coordinates. A bi-dimensional image has coordinates varying from (0, 0) (left top corner) to (1, 1) (bottom right corner).

The working way is very simple:

Let’s take a triangle and then apply an area of the image. First choose any triangular zone of our image and take 3 vertices in texture coordinates (in the example they are 1-0, 0-1, 1-1). These 3 couples of values will be passed to our buffer in the usual way creating a new semantic row.

The zone between the 3 points will be apply to the triangle. It doesn’t matter if the triangle cut off from the image is different from the 3D one: the image will be deformed in order to respect the 3 vertices. What we have selected from the image will be apply on the triangle.

Defining all the texture coordinates we could “map” our object and then apply the texture to a whole 3D model.

Texture coordinates for an image vary between 0 and 1. What happens if their range change into [0, 2]? Simply, once gone over 1, the texture will be repeated. In this way, if we render a wall compound of a rectangle we will use texture coordinates between 0 and 10 in order to repeat ten times our image. With texture1D and texture3D the way of reasoning is the same. In case of texture1D we have only one coordinate which retrieves the position along the unique dimension. In case of texture3D we have 3 coordinates, the third one that retrieves a value indicating at which height our image is in the stack of images.

In the next tutorial we will render a 3D model with textures applied.

A special thanks goes to J@ck who translate this lesson.