D3d Study Notes-model Loading

Source: Internet
Author: User

Finally, we started the most exciting moment in 3D. We were always using our program to define the vertex, and then coloring or pasting the texture. It was always so nice, maybe you may have such questions: how can we draw complicated models if we always draw them? For example, a house or chair. Indeed, it is very difficult to draw such a model in the program area. This time we will solve this problem and use the model, it is the model created in some 3D modeling tools such as 3dmax. We import it into our program to show that our world is rich and colorful. Let's take a look at the Code:

 

 

// ================================================ ========================================================

// Desc: Use of the file Grid Model

// ================================================ ========================================================

# Include <d3dx9. h>

 

 

//-----------------------------------------------------------------------------

// Desc: global variable

//-----------------------------------------------------------------------------

Lpdirect3d9 g_pd3d = NULL; // direct3d object

Lpdirect3ddevice9 g_pd3ddevice = NULL; // direct3d device object

 

Lpd3dxmesh g_pmesh = NULL; // mesh model object

D3dmaterial9 * g_pmeshmaterials = NULL; // mesh model material

Lpdirect3dtexture9 * g_pmeshtextures = NULL; // mesh model texture

DWORD g_dwnummaterials = 0l; // Number of Mesh Model Materials

 

 

//-----------------------------------------------------------------------------

// Desc: sets the world matrix.

//-----------------------------------------------------------------------------

Void setworldmatrix ()

{

// Create and set the world Matrix

D3dxmatrixa16 matworld;

D3dxmatrixrotationy (& matworld, timegettime ()/1000.0f );

G_pd3ddevice-> settransform (d3dts_world, & matworld );

}

 

 

//-----------------------------------------------------------------------------

// Desc: sets the observation matrix and projection matrix.

//-----------------------------------------------------------------------------

Void setviewandprojmatrix ()

{

// Create and set the observation matrix

D3dxvector3 veyept (0.0f, 10.0f,-20366f );

D3dxvector3 vlookatpt (0.0f, 0.0f, 0.0f );

D3dxvector3 vupvec (0.0f, 1.0f, 0.0f );

D3dxmatrixa16 matview;

D3dxmatrixlookatlh (& matview, & veyept, & vlookatpt, & vupvec );

G_pd3ddevice-> settransform (d3dts_view, & matview );

 

// Create and set the Projection Matrix

D3dxmatrixa16 matproj;

D3dxmatrixperspectivefovlh (& matproj, d3dx_pi/4, 1.0f, 1.0f, 100366f );

G_pd3ddevice-> settransform (d3dts_projection, & matproj );

}

 

 

//-----------------------------------------------------------------------------

// Desc: Initialize direct3d

//-----------------------------------------------------------------------------

Hresult initd3d (hwnd)

{

// Create a direct3d object used to create a direct3d device object

If (null = (g_pd3d = direct3dcreate9 (d3d_sdk_version )))

Return e_fail;

 

// Set the d3dpresent_parameters structure to create a direct3d device object

D3dpresent_parameters d3dpp;

Zeromemory (& d3dpp, sizeof (d3dpp ));

D3dpp. paiwed = true;

D3dpp. swapeffect = d3dswapeffect_discard;

D3dpp. backbufferformat = d3dfmt_unknown;

D3dpp. enableautodepthstencel = true;

D3dpp. autodepthstencilformat = d3dfmt_d16;

 

// Create a direct3d device object

If (failed (g_pd3d-> createdevice (d3dadapter_default, d3ddevtype_hal, hwnd,

D3dcreate_software_vertexprocessing,

& D3dpp, & g_pd3ddevice )))

{

Return e_fail;

}

 

// Set the ambient light

G_pd3ddevice-> setrenderstate (d3drs_ambient, 0 xffffffff );

 

// Set the observation matrix and Projection Matrix

Setviewandprojmatrix ();

 

Return s_ OK;

}

 

 

//-----------------------------------------------------------------------------

// Desc: extract the texture file name from the absolute path

//-----------------------------------------------------------------------------

Void removepathfromfilename (lpstr fullpath, lpwstr filename)

{

// First convert the fullpath type to lpwstr

Wchar wszbuf [max_path];

Multibytetowidechar (cp_acp, 0, fullpath,-1, wszbuf, max_path );

Wszbuf [MAX_PATH-1] = l'/0 ';

 

Wchar * wszfullpath = wszbuf;

 

// Extract the file name from the absolute path

Lpwstr PCH = wcsrchr (wszfullpath ,'//');

If (PCH)

Lstrcpy (filename, ++ PCH );

Else

Lstrcpy (filename, wszfullpath );

}

 

 

 

//-----------------------------------------------------------------------------

// Desc: Creates a scene image.

//-----------------------------------------------------------------------------

Hresult initgeometry ()

{

Lpd3dxbuffer pd3dxmtrlbuffer; // buffer object for storing the mesh model material

 

// Load the grid model from the disk file

If (failed (d3dxloadmeshfromx (L "airplane. X", d3dxmesh_managed,

G_pd3ddevice, null,

& Pd3dxmtrlbuffer, null, & g_dwnummaterials,

& G_pmesh )))

{

MessageBox (null, l "cocould not find airplane. X", l "mesh", mb_ OK );

Return e_fail;

}

 

// Extract material attributes and texture file names from the mesh model

D3dxmaterial * d3dxmaterials = (d3dxmaterial *) pd3dxmtrlbuffer-> getbufferpointer ();

G_pmeshmaterials = new d3dmaterial9 [g_dwnummaterials];

 

If (g_pmeshmaterials = NULL)

Return e_outofmemory;

 

G_pmeshtextures = new lpdirect3dtexture9 [g_dwnummaterials];

If (g_pmeshtextures = NULL)

Return e_outofmemory;

 

// Extract grid model material attributes and texture file names one by one

For (DWORD I = 0; I <g_dwnummaterials; I ++)

{

// Material attributes

G_pmeshmaterials [I] = d3dxmaterials [I]. matd3d;

// Set the ambient light reflection coefficient of the model material because the model material itself has not set the ambient light reflection coefficient

G_pmeshmaterials [I]. Ambient = g_pmeshmaterials [I]. Diffuse;

 

G_pmeshtextures [I] = NULL;

If (d3dxmaterials [I]. ptexturefilename! = NULL &&

Strlen (d3dxmaterials [I]. ptexturefilename)> 0)

{

// Obtain the texture file name

Wchar filename [256];

Removepathfromfilename (d3dxmaterials [I]. ptexturefilename, filename );

 

// Create a texture

If (failed (d3dxcreatetexturefromfile (g_pd3ddevice, filename,

& G_pmeshtextures [I])

{

MessageBox (null, l "cocould not find texture file", l "mesh", mb_ OK );

}

}

}

 

// Release the buffer object that saves the model material and texture data created when the model file is loaded.

Pd3dxmtrlbuffer-> release ();

 

Return s_ OK;

}

 

 

//-----------------------------------------------------------------------------

// Desc: Release the created object

//-----------------------------------------------------------------------------

Void cleanup ()

{

// Release the mesh model material

If (g_pmeshmaterials! = NULL)

Delete [] g_pmeshmaterials;

 

// Release the texture of the mesh model

If (g_pmeshtextures)

{

For (DWORD I = 0; I <g_dwnummaterials; I ++)

{

If (g_pmeshtextures [I])

G_pmeshtextures [I]-> release ();

}

Delete [] g_pmeshtextures;

}

 

// Release the mesh model object

If (g_pmesh! = NULL)

G_pmesh-> release ();

// Release the direct3d device object

If (g_pd3ddevice! = NULL)

G_pd3ddevice-> release ();

 

// Release the direct3d object

If (g_pd3d! = NULL)

G_pd3d-> release ();

}

 

 

//-----------------------------------------------------------------------------

// Desc: Rendering scenario

//-----------------------------------------------------------------------------

Void render ()

{

// Clear the buffer

G_pd3ddevice-> clear (0, null, d3dclear_target | d3dclear_zbuffer,

D3dcolor_xrgb (0, 0, 255), 1.0f, 0 );

// Start Rendering scenario

If (succeeded (g_pd3ddevice-> beginscene ()))

{

Setworldmatrix (); // sets the world matrix.

 

// Render the mesh model one by one

For (DWORD I = 0; I <g_dwnummaterials; I ++)

{

// Set materials and textures

G_pd3ddevice-> setmaterial (& g_pmeshmaterials [I]);

G_pd3ddevice-> settexture (0, g_pmeshtextures [I]);

 

// Rendering Model

G_pmesh-> drawsubset (I );

}

 

// Scene Rendering ends

G_pd3ddevice-> endscene ();

}

 

// Display the scenario on the screen

G_pd3ddevice-> present (null, null );

}

 

 

//-----------------------------------------------------------------------------

// Desc: A window process that processes messages.

//-----------------------------------------------------------------------------

Lresult winapi msgproc (hwnd, uint MSG, wparam, lparam)

{

Switch (MSG)

{

Case wm_destroy:

Cleanup ();

Postquitmessage (0 );

Return 0;

}

 

Return defwindowproc (hwnd, MSG, wparam, lparam );

}

 

 

//-----------------------------------------------------------------------------

// Desc: entry function

//-----------------------------------------------------------------------------

Int winapi winmain (hinstance hinst, hinstance, lpstr, INT)

{

// Register the window class

Wndclassex WC = {sizeof (wndclassex), cs_classdc, msgproc, 0l, 0l,

Getmodulehandle (null), null,

L "classname", null };

Registerclassex (& WC );

 

// Create a window

Hwnd = createwindow (L "classname", l "grid model ",

Ws_overlappedwindow, 200,100,500,500,

Getasktopwindow (), null, WC. hinstance, null );

 

// Initialize direct3d

If (succeeded (initd3d (hwnd )))

{

// Create a scene image

If (succeeded (initgeometry ()))

{

// Display window

Showwindow (hwnd, sw_showdefault );

Updatewindow (hwnd );

 

// Enter the message loop

MSG;

Zeromemory (& MSG, sizeof (MSG ));

While (msg. message! = Wm_quit)

{

If (peekmessage (& MSG, null, 0, 0, pm_remove ))

{

Translatemessage (& MSG );

Dispatchmessage (& MSG );

}

Else

{

Render (); // Rendering scenario

}

}

}

}

 

Unregisterclass (L "classname", WC. hinstance );

Return 0;

}

The above Code uses airplane. X file. The extension type of this file is. X is specially developed by Microsoft for d3d learning. In the first phase of learning, we have enough files of this type, this file should be placed in the project directory like the image used last time. However, model files generally contain texture images. Do not forget to put the texture images and files together, there are many online tutorials on model conversion. You can search elsewhere. I will not talk about it here. If you have a conversion method, you can use 3dmax to make a simple model and then export it to an X file.

Looking at this code, there are a lot of unfamiliar things. Well, it doesn't matter. In fact, all these are past accumulation. It's no big deal. Let's take a closer look:

Let's take a look at the global volume:

//-----------------------------------------------------------------------------

// Desc: global variable

//-----------------------------------------------------------------------------

Lpdirect3d9 g_pd3d = NULL; // direct3d object

Lpdirect3ddevice9 g_pd3ddevice = NULL; // direct3d device object

 

Lpd3dxmesh g_pmesh = NULL; // mesh model object

D3dmaterial9 * g_pmeshmaterials = NULL; // mesh model material

Lpdirect3dtexture9 * g_pmeshtextures = NULL; // mesh model texture

DWORD g_dwnummaterials = 0l; // Number of Mesh Model Materials

All the specific explanations are available in the Code. do you understand it now? It's okay. Let's talk about it later.

We can see that there is another function we have never seen before.

 

Hresult initgeometry ()

{

Lpd3dxbuffer pd3dxmtrlbuffer; // buffer object for storing the mesh model material

 

// Load the grid model from the disk file

If (failed (d3dxloadmeshfromx (L "airplane. X", d3dxmesh_managed,

G_pd3ddevice, null,

& Pd3dxmtrlbuffer, null, & g_dwnummaterials,

& G_pmesh )))

{

MessageBox (null, l "cocould not find airplane. X", l "mesh", mb_ OK );

Return e_fail;

}

 

// Extract material attributes and texture file names from the mesh model

D3dxmaterial * d3dxmaterials = (d3dxmaterial *) pd3dxmtrlbuffer-> getbufferpointer ();

G_pmeshmaterials = new d3dmaterial9 [g_dwnummaterials];

 

If (g_pmeshmaterials = NULL)

Return e_outofmemory;

 

G_pmeshtextures = new lpdirect3dtexture9 [g_dwnummaterials];

If (g_pmeshtextures = NULL)

Return e_outofmemory;

 

// Extract grid model material attributes and texture file names one by one

For (DWORD I = 0; I <g_dwnummaterials; I ++)

{

// Material attributes

G_pmeshmaterials [I] = d3dxmaterials [I]. matd3d;

// Set the ambient light reflection coefficient of the model material because the model material itself has not set the ambient light reflection coefficient

G_pmeshmaterials [I]. Ambient = g_pmeshmaterials [I]. Diffuse;

G_pmeshtextures [I] = NULL;

If (d3dxmaterials [I]. ptexturefilename! = NULL &&

Strlen (d3dxmaterials [I]. ptexturefilename)> 0)

{

// Obtain the texture file name

Wchar filename [256];

Removepathfromfilename (d3dxmaterials [I]. ptexturefilename, filename );

 

// Create a texture

If (failed (d3dxcreatetexturefromfile (g_pd3ddevice, filename,

& G_pmeshtextures [I])

{

MessageBox (null, l "cocould not find texture file", l "mesh", mb_ OK );

}

}

}

 

// Release the buffer object that saves the model material and texture data created when the model file is loaded.

Pd3dxmtrlbuffer-> release ();

 

Return s_ OK;

}

In fact, this function is used to load X files on the hard disk to the memory for our use. The lpd3dxmesh used is the polygon network model interface defined by the d3d extended utility library, to represent a complex 3D object model, including vertex data, material data, and texture data.

Lpd3dxbuffer pd3dxmtrlbuffer; // buffer object for storing the mesh model material

This data structure is generated for ease of operation. It stores various types of data such as vertex coordinates, materials, and textures. You can use the interface function getbufferpointer to get the data in the buffer and use getbuffersize to get the data size.

Example of extracting material and texture file names from the mesh model:

D3dxmaterial * d3dxmaterials = (d3dxmaterial *) pd3dxmtrlbuffer-> getbufferpointer (); a forced type conversion mode is provided here, which can be directly converted and very convenient.

 

There is also a function:

D3dxloadmeshfromx (L "airplane. X", d3dxmesh_managed,

G_pd3ddevice, null,

& Pd3dxmtrlbuffer, null, & g_dwnummaterials,

& G_pmesh)

 

This function is used to read X Files from files.

Let's take a closer look:

 

Hresult d3dxloadmeshfromx (

Lpctstr pfilename,

DWORD options,

Lpdirect3ddevice9 pd3ddevice,

Lpd3dxbuffer * ppadjacency,

Lpd3dxbuffer * ppmaterials,

Lpd3dxbuffer * ppeffectinstances,

DWORD * pnummaterials,

Lpd3dxmesh * ppmesh

);

Parameters

Pfilename

X file name, in string format.

Options

It is usually set to d3dxmesh_managed, indicating that the video memory is used.

Pd3ddevice

Environment pointer, which is commonly used

Ppadjacency

Point to the buffer memory address used to store information about the polygon surrounding each polygon. We cannot use this information, so we set it to null.

Ppmaterials

[Out] The buffer address used to store model textures and materials.

Ppeffectinstances

[Out] refers to the buffer address used to store the model effect instance.

Pnummaterials

[Out] Number of materials stored.

Ppmesh

[Out] pointer to the generated d3d mesh model.

 

 

The remaining function is to extract materials, textures, and other information from the obtained pd3dxmtrlbuffer, and set the environment light in the material. The code is simple and you can understand it.

This loading function is explained here. There is also a major change to the function below, which is in the rendering function:

 

Void render ()

{

// Clear the buffer

G_pd3ddevice-> clear (0, null, d3dclear_target | d3dclear_zbuffer,

D3dcolor_xrgb (0, 0, 255), 1.0f, 0 );

// Start Rendering scenario

If (succeeded (g_pd3ddevice-> beginscene ()))

{

Setworldmatrix (); // sets the world matrix.

 

// Render the mesh model one by one

For (DWORD I = 0; I <g_dwnummaterials; I ++)

{

// Set materials and textures

G_pd3ddevice-> setmaterial (& g_pmeshmaterials [I]);

G_pd3ddevice-> settexture (0, g_pmeshtextures [I]);

 

// Rendering Model

G_pmesh-> drawsubset (I );

}

 

// Scene Rendering ends

G_pd3ddevice-> endscene ();

}

 

// Display the scenario on the screen

G_pd3ddevice-> present (null, null );

}

 

 

In this function, we are still familiar with the previous part, that is, after setting the world matrix:

For (DWORD I = 0; I <g_dwnummaterials; I ++)

{

// Set materials and textures

G_pd3ddevice-> setmaterial (& g_pmeshmaterials [I]);

G_pd3ddevice-> settexture (0, g_pmeshtextures [I]);

 

// Rendering Model

G_pmesh-> drawsubset (I );

}

These codes are a bit unfamiliar. Take a closer look, g_pd3ddevice-> setmaterial (& g_pmeshmaterials [I]);

This Code sets the corresponding material. Previously we used g_pd3ddevice-> settexture (0, g_pmeshtextures [I]);

Used to set a texture image.

G_pmesh-> drawsubset (I );

A 3D mesh model is usually composed of several submodels. When a model is created, the material and texture are usually set for each submodel. Therefore, these submodels may use different materials and textures, therefore, you need to set materials and textures for different submodels during rendering. The g_dwnummaterials in the above program indicates the number of materials and textures, which is actually the number of submodels of the 3D model.

Here, the program is about to be introduced. If you have any questions, we can discuss them together.

 

 

This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/luoya263547560/archive/2009/04/05/4049563.aspx

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.