In the previous tutorial, we used to generate vertices and index data directly in modelclass. Simple triangles, cubes, and so on. After all, it is relatively simple. How can we display complex 3D objects? In particular, when using existing 3D files, such as OBJ, 3DS, md2, X, and other formats, we need to use these 3D format Resolvers. In this tutorial, we use the open asset import library to display 3D files in various formats (for animation files, do not consider static 3D files for the moment ).
Open asset import library is an open-source model imported into the database. It supports many formats. Its download and installation will not be described. Next I will introduce it on the basis of mytutoriald3d11_35, add the code to import 3D files using the assimp library.
An assimpmodelclass class is added, in which the vertex format is:
{
D3dxvector3 position;
D3dxvector3 normal; // normal
D3dxvector2 texture; // texture coordinate
D3dxvector4 KD; // material diffuse reflection coefficient
D3dxvector4 KS; // The highlight coefficient of the material.
};
The function that generates vertex and index buffering is assimpmodelclass. We use this function to generate vertex buffering and index buffering.
Bool assimpmodelclass: loadmodel (id3d11device * device, STD: String filename)
{
Hresult result;
Note: first, we will define an assimp importer class to read the model file using this class. We will perform two loops. The first loop will get the number of vertices and indexes, then create a temporary cache for the vertex and index to save the vertex and index data. The second loop reads the vertex and index data from the model file, and finally creates the vertex and index buffer.
Assimp: importer;
Vertextype * vertices;
Unsigned long * indices;
D3d11_buffer_desc vertexbufferdesc, indexbufferdesc;
D3d11_subresource_data vertexdata, indexdata;
Const aiscene * scene = importer. readfile (filename, aiprocesspreset_targetrealtime_quality );
If (! Scene)
{
Messageboxa (null, importer. geterrorstring (), "error", mb_ OK );
Return false;
}
Int m = 0;
// The first scan to obtain the vertex and index count
For (m = 0; m <scene-> mnummeshes; ++ m)
{
// The MTH Mesh
Aimesh * aimesh = scene-> mmeshes [m];
M_vertexcount + = aimesh-> mnumvertices;
M_indexcount + = aimesh-> mnumfaces * 3;
}
// Create a temporary vertex buffer.
Vertices = new vertextype [m_vertexcount];
If (! Vertices)
{
Return false;
}
// Create an index temporary buffer.
Indices = new unsigned long [m_indexcount];
If (! Indices)
{
Return false;
}
// Temporary vertex and index pointer
Int index1 = 0;
Int index2 = 0;
Int I = 0;
// The second loop to obtain the value of each vertex and Index
For (m = 0; m <scene-> mnummeshes; ++ m)
{
// The MTH Mesh
Aimesh * aimesh = scene-> mmeshes [m];
If (! Aimesh-> hasnormals () |! Aimesh-> hastexturecoords (0 ))
{
MessageBox (null, l "the model file does not contain texture coordinates or normal information", l "error", mb_ OK );
Return false;
}
Int vertexcount = aimesh-> mnumvertices;
For (I = 0; I <vertexcount; ++ I)
{
Vertices [index1]. Position = d3dxvector3 (aimesh-> mvertices [I]. X, aimesh-> mvertices [I]. Y, aimesh-> mvertices [I]. z );
Vertices [index1]. Normal = d3dxvector3 (aimesh-> mnormals [I]. X, aimesh-> mnormals [I]. Y, aimesh-> mnormals [I]. z );
Vertices [index1]. Texture = d3dxvector2 (aimesh-> mtexturecoords [0] [I]. X, aimesh-> mtexturecoords [0] [I]. y );
Vertices [index1]. Kd = d3dxvector4 (1.0, 1.0, 1.0, 1.0 );
Vertices [index1]. Ks = d3dxvector4 (0.2, 0.2, 0.2, 1.0 );
Index1 ++;
}
For (I = 0; I <aimesh-> mnumfaces; ++ I)
{
Const aiface & face = aimesh-> mfaces [I];
// Assert (face. mnumindices = 3 );
Indices [index2] = face. mindices [0];
Index2 ++;
Indices [index2] = face. mindices [1];
Index2 ++;
Indices [index2] = face. mindices [2];
Index2 ++;
}
}
// Set the vertex buffer description
Vertexbufferdesc. Usage = d3d11_usage_default;
Vertexbufferdesc. bytewidth = sizeof (vertextype) * m_vertexcount;
Vertexbufferdesc. bindflags = d3d11_bind_vertex_buffer;
Vertexbufferdesc. cpuaccessflags = 0;
Vertexbufferdesc. miscflags = 0;
Vertexbufferdesc. structurebytestride = 0;
// Point to the temporary buffer for storing vertex data.
Vertexdata. psysmem = vertices;
Vertexdata. sysmempitch = 0;
Vertexdata. sysmemslicepitch = 0;
// Create a vertex buffer.
Result = device-> createbuffer (& vertexbufferdesc, & vertexdata, & m_vertexbuffer );
If (failed (result ))
{
HR (result );
Return false;
}
// Set the index buffer description.
Indexbufferdesc. Usage = d3d11_usage_default;
Indexbufferdesc. bytewidth = sizeof (unsigned long) * m_indexcount;
Indexbufferdesc. bindflags = d3d11_bind_index_buffer;
Indexbufferdesc. cpuaccessflags = 0;
Indexbufferdesc. miscflags = 0;
Indexbufferdesc. structurebytestride = 0;
// Point to the temporary index buffer.
Indexdata. psysmem = indices;
Indexdata. sysmempitch = 0;
Indexdata. sysmemslicepitch = 0;
// Create an index buffer.
Result = device-> createbuffer (& indexbufferdesc, & indexdata, & m_indexbuffer );
If (failed (result ))
{
HR (result );
Return false;
}
// Release the temporary buffer.
Delete [] vertices;
Vertices = 0;
Delete [] indices;
Indices = 0;
Return true;
}
Then in graphicsclass, we will add the assimpmodelclass variable and use lighttexshader to render the model loaded by this class. The main code is as follows:
1. Initialization code
// Create an assimp model object
M_assimpmodel = new assimpmodelclass;
If (! M_assimpmodel)
{
Return false;
}
// Initialize the coordinate assimp model object. Faerie. md2, Tiny. x
Result = m_assimpmodel-> initialize (m_d3d-> getdevice (), "Tiny. X ");
If (! Result)
{
MessageBox (hwnd, l "cocould not initialize the axis model object.", l "error", mb_ OK );
Return false;
}
2. Rendering code:
D3dxmatrixscaling (& worldmatrix4, 0.02, 0.02, 0.02 );
M_assimpmodel-> render (m_d3d-> getdevicecontext ());
// Use light shader, faerie2.bmp, tiny_skin.dds
Result = m_lighttexshader-> render (m_d3d-> getdevicecontext (), m_assimpmodel-> getindexcount (), worldmatrix4, viewmatrix, projectionmatrix,
Light, material, camera, m_texmanager-> createtex (m_d3d-> getdevice (), string ("tiny_skin.dds ")));
If (! Result)
{
Return false;
}
After the program is executed:
Mount tiny. x
Load the md2 Format File faerie. md2
Complete code can be found:
Project File mytutoriald3d11_64
Download Code:
Provided later