DirectX graphics interface Guide Author: Translation: In355Hz Translator Disclaimer: These guidelines are progressively translated in my reading of DirectX8.1 SDK. This should be good to get your information for the programmer of the first time contact DirectX Graphics. In fact, I have begun to Direct3D8.1 from these guidelines; because this is the first translation of English materials, the words are not good, the words are not intended, some terms are also very reluctant, please forgive me. In addition, you need to reprint this article, keep the following parts: ----------------------------------- --------------------------------- DirectX Graphic Interface Guide Translator: In355Hz Email: In355Hz@hotmail.com -------------------------------------------------- --------------------- DirectX Graphical Interface Guide: (Applicable to DirectX 8.1 C / C Programming) This area guide explains how to in the C / C program Complete some normal work with Microsoft Direct3D and Direct3dx. These work are always broken down into several necessary steps. In some cases, in order to make the expression more clear, some steps are also subjected to several sub-steps. The guidelines provided in this region include: Guide 1: Create equipment · Guide 2: Demo Vertex · Guide 3: Use Matrix · Guide 4: Create and Use Light Source · Guide 5: Use Texture Mapping · Guide 6: Using Mesh Model Tips: Guide The sample code that appears from the present comes from the source file in each guide. The source code in these guidelines is written in C . If you use a C compiler, you must change these files to make them compile. At least, you need to add VTABLE and use it to reference the interface function. Some of the annotations included in the sample code may differ from the source code from the Microsoft Platform Software Development Kit (SDK). These changes are only to simplify the expression and are limited to the annotation, which prevents behavior of the sample program from being changed. Guide 1: Creating a device In order to use Microsoft Direct3D, you first need to create an application window and then create and initialize the Direct3D object. You should use the COM interface provided by these objects to manipulate them, and create other objects that depict one scenario. The CreateDevice example included in this guide will illustrate and describe the following work: Create a Direct3D device and draw a simple blue screen. This guide uses the following steps: initialize Direct3D, draw a scene, and final cleaning and closing. Step 1: Create a window · Step 2: Initialize Direct3D · Step 3: Processing System Messages • Step 4: Drawing and Display Scenes • Step 5: Close and Clear Note: CreateDevice Sample Program Path: (SDK Root) / Samples / MULTIMEDIA / DIRECT3D / TUTORIALS / TUT01_CREATEDEVICE. Step 1: Creating a window Anything you must do in the Microsoft Windows program is to create an application window and display it to the user.
To do this, the CreateDevice routine will first implement its WinMain function. The following sample code completes the initialization of the window. INT WINAPI WinMain (HINSTANCE hInst, HINSTANCE, LPSTR, INT) {// Register the window class. WNDCLASSEX wc = {sizeof (WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle (NULL), NULL, NULL, NULL, NULL , "D3D Tutorial", NULL}; RegisterClassEx (& wc); // Create the application's window HWND hWnd = CreateWindow ( "D3D Tutorial",. "D3D Tutorial 01: CreateDevice", WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, GetDesktopWindow () NULL, WC.HINSTANCE, NULL; the aforementioned sample code is a standard Windows programming. The example starts and registers a window class name "D3D Tutorial". After class registration, sample code creates a fund-level window with a registered class, with 300 pixels wide, 300 pixels wide. This window does not have a menu or sub-window. The example uses the WS_OVERLAPPEDWINDOW property to create a normal window including maximizing, minimizing, and closing buttons. (If the routine will run in full screen mode, the preferred window property should be WS_EX_TOPMOST, which specifies the created window to be placed and kept before all non-TopMost windows, even in the event of windows. Once the window is created, the code calls the standard Microsoft Win32 function display and update the window. After the application window is ready, you can start setting a specific Microsoft Direct3D object, see: Step 2: Initializing Direct3D Step 2: Initializing the Direct3D CreateDevice example After creating a window in WinMain, calling the program defined function initd3d completed Microsoft Direct3D initialization process. After the window is created, the program is ready to initialize the Direct3D object you will use to draw the scene. This process includes creating a Direct3D object, setting present parameters, and finalizing Direct3D devices. After you have created the Direct3D object, you can create a Direct3D device with the iDirect3d8 :: createDevice method immediately. You can also enumerate your device, type, mode, and other things using Direct3D objects. The code segment of these work should be located after using the Direct3DCReate8 function to create a Direct3D object. If (null == (g_pd3d = direct3dcreate8 (d3d_sdk_version))) Return E_FAIL; the unique parameter passed to Direct3DCReate8 should always be D3D_SDK_Version, which tells Direct3D currently used header file information. In any case, the header or other changes will result in this value to increase and force the application of this value to recompile.
If this version does not match, call Direct3DCREATE8 will fail. The next step is to use the interface IDirect3D8 :: GetAdapterDisplayMode find the current display mode, as follows: D3DDISPLAYMODE d3ddm; if (FAILED (g_pD3D-> GetAdapterDisplayMode (D3DADAPTER_DEFAULT, & d3ddm))) return E_FAIL; D3DDISPLAYMODE structure variables will be used for Format Create a Direct3D device. If it is running in window mode, the Format parameter is usually used to create a back buffer that matches the current mode of the adapter. When assigning parameters to D3DPresent_Parameters, you must specify how your application works in 3D. This CreateDevice routine Sets the D3DPresent_Parameters structure Windowed to true, swapect is d3dswapeffect_discard, backbufferformat is D3DDM.FORMAT. D3DPRESENT_PARAMETERS d3dpp; ZeroMemory (& d3dpp, sizeof (d3dpp)); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = d3ddm.Format; last step, using IDirect3D8 :: CreateDevice function to create Direct3D device, as follows: if (FAILED (g_pD3D-> CreateDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, & d3dpp, & g_pd3dDevice))) preceding code creates a device using defaulted adapters use D3DADAPTER_DEFAULT flag. In a very large number, there is only one adapter unless it has a plurality of graphics acceleration cards. By setting the DeviceType parameter to D3DDEVTYPE_HAL, you want to get an actual hardware device instead of software virtual devices (Software Device). The sample code also uses the D3DCREATE_SOFTWARE_VERTEXPROCESSING flag notification system to use software vertex processing. Note that if you specify the D3DCREATE_HARDWARE_VERTEXPROCESSING flag notification system Using Hardware Vertex Process, you can get a large performance increase on the graphics acceleration card that supports the hardware vertex. Now Direct3D has been initialized, the next step is to make sure your program has a mechanism to handle system messages, see below: Step 3: Processing system message Step 3: Processing System Messages Complete Creating Program Window and Initializing Direct 3D, you have prepared It is good to draw a scene. In most cases, the Microsoft Windows program monitors the system message in their message loops, and draws the screen frame when there is no message in the queue. However, the CreateDevice routine notifies all parts of the window when it is waited until a WM_Paint appears in the queue.
// The message loop. Msg msg; while (getMessage (& MSG, NULL, 0, 0)) {TranslateMessage (& MSG); DispatchMessage (& MSG);} When each loop is once, DispatchMessage calls MsgProc, the latter is responsible for handling the queue Message, when the WM_Paint message is entered the team, call the program's own defined function render (), which will be responsible for redrawing the window. The Microsoft Win32 function validaterect is then executed and sets the entire customer area to be valid. Examples of the message processing function are as follows: LResult WinAPI MsgProc (HWND HWND, UINT MSG, WPARAM WPARAM, LPARAM LPARAM) {Switch (MSG) {Case WM_DESTROY: PostquitMessage (0); Return 0; Case WM_Paint: Render (); ValidateERECT HWND, NULL); RETURN 0;} Return DEFWINDOWPROC (HWND, MSG, WPARAM, LPARAM);} Now, the application handles the system message, the next step is to draw the display, see: Step 4: Draw and display the scene Step 4: Drawing and displaying scenarios in order to depict and display the required scenarios, this routine is filled with back buffer in this step, then pass the contents of the back buffer to the foreground buffer, and will prospects The buffer is submitted to the screen. Clear the surface, call IDirect3ddevice8 :: CLEAR function: // clear the back buffer to a blue color g_pd3ddevice-> clear (0, null, d3dclear_target, d3dcolor_xrgb (0, 0, 255), 1.0F, 0); CLEAR () Accepted by The first two parameters notified the base and size of the rectangular area array that Microsoft Direct 3D cleared, the rectangular area array describes the area that needs to be cleared in the render Target Surface. In most cases, only a single rectangle covers the entire drawing target surface. This way you only need to set the first parameter of 0 and the second parameter as NULL. The third parameter will determine the behavior of the method, you can use a specific flag to clear the render Target Surface, the associated Z buffer, the stencil buffer, and any of these three Mixing of people. This guide does not use Z buffer, so only the D3DCLEAR_TARGET flag is used. The last three parameters are used to set the corresponding drawing target surface, the Z buffer, and the reflection value of the template buffer. The CreateDevice routine sets the clear pad color of the drawing destination to blue (D3DCOLOR_XRGB (0, 0, 255). Because the corresponding flag is not set, the last two parameters are ignored by CLEAR ().
After clearing the viewport, the CreateDevice routine tells the Direct3D drawing will start, and then immediately notify this draw complete, see the following code segment: // begin the scene. G_pd3ddevice-> beginscene (); // Rendering of Scene Objects happens here. // End the scene. g_pd3ddevice-> endscene (); When drawing start or completion, iDirect3ddevice8 :: beginscene and iDirect3ddevice8 :: EndScene functions will use the signal notification system. You can only call other drawing functions between these two functions. Even if the calling function fails, you should call EndScene before reinterping Beginscene. After drawing, call IDirect3dDevice8 :: Present Displaying the scene: g_pd3ddevice-> present (NULL, NULL, NULL, NULL); Present () The first two parameters accepted are raw rectangular and target rectangles. In this step, the routine settings these two parameters are NULL and submit the entire back buffer to the foreground buffer. The third parameter is used to set the target window of the submit. Because this parameter is set to NULL, the actual window is the HWndDeviceWindow member of D3DPresent_Parameters. The fourth is the DirtyRegion parameters, which should be set to NULL in most cases. The final step of this guide is to close the app, see: Step 5: Close and clear Step 5: Close and clearing at a number of times the execution, your application must be turned off immediately. Turning off a Direct3D application does not mean you have to destroy the program window, and you also want to release any Direct3D objects used in the program and invalidate their pointers. When a WM_DESTROY message is received, the CreateDevice routine handles these work by calling a local defined function cleanup (). Void cleanup () {if (g_pd3dde! = Null) g_pd3dde.com-> Release (); if (g_pd3d! = Null) g_pd3d-> release ();} The above function calls the iUnknown :: release method to each object to release them itself . Since DirectX follows the COM rules, most objects are automatically released from memory when their reference count falls to 0, and DirectX will automatically release this object from memory. For other closing programs, it may happen in the usual execution of the program - such as the user changes the parameters or color depth of the desktop - you might need to revoke and rebuild the Microsoft Direct3D object in use. So a good idea is to put your release code together so that you can call it at any time when you need it. This guide has explained how to create a device, guide 2: Render Vertex, will tell you how to create a geometry in the vertex (Vertex). Guide 2: Demo Vertex) Microsoft Direct3D written application uses vertex (Vertex) to construct geometric objects. Each three-dimensional space (3D) scene includes one or several such geometric objects. The Vertices routine constructs a simple object, a triangle, and draws it to the display.
This guide explains how to construct a triangle from the vertex: • First step: Define a custom vertex type • Step 2: Set the vertex buffer • Step 3: Draw to the display Note: The path to the Vertices sample program is: (SDK root) / Samples / MultiMedia / Direct3D / Tutorials / TUT02_VERTITICES. The sample code of the Vertices program is the same as the code of CreateDevice. This "Render Vertex" guide is only focused on those unique, regardless of the apex code, without including the initialization of Direct3D, processing Microsoft Windows messages, drawings, and cleaning. For information on these tasks, please refer to Guide 1: Create a device. The first step: Define a custom vertex type Vertices routine uses three vertices to construct a 2D triangle. Here, the concept of vertex buffering is mentioned, which is a Microsoft Direct3D object for saving and demonstrating a large number of vertices. The vertex can be defined by specifying a custom vertex structure and the corresponding variable vector format (FVF). The vertex format used by this Vertices routine is defined in the following code snippet. Struct CustomvertEX {Float X, Y, Z, RHW; // The Transformed Position for the Vertex. DWORD COLOR; // The Vertex Color.}; The above structure illustrates the format of the custom vertex type. The next step is to define FVF to describe the vertex content in the vertex buffer. The following code snippet defines an FVF and conforms to the type of custom vertex. #Define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE) Variable Vertex Format Tag Description Use the custom vertex type in use. The aforementioned sample code uses the D3DFVF_XYZRHW and D3DFVF_DIFFUSE flags, which will tell the vertex buffer, the custom vertex type contains a set of converted point coordinates and follows a color parameter. Now custom vector format and FVF have been specified, the next step will use the vertex to fill the top buffer, see: Step 2: Set the vertex buffer. Note: The vertices in the Vertices routine are converted. With another sentence, they have been under the 2D window coordinate system. This means that the seat point (0,0) is located in the upper left corner, and the positive X semi-axial right, the positive Y semi-axis is down. These vertices are also illuminated, which indicates that their coloration does not replace themselves by Direct3D lighting. Step 2: Set the vertex buffer now the custom vertex format has been completed, and the initialization is at the time. The Vertices routine creates the required Microsoft Direct3D object to call the function initvb () within this program within this program. The following code segment will initialize the value of three custom vertices. CustomvertEX G_Vertices [] = {{150.0F, 50.0F, 0.5F, 1.0F, 0xFFFF0000,}, // x, y, z, rhw, color {250.0F, 250.0F, 0.5F, 1.0F, 0xFF00FF00,} {50.0F, 250.0F, 0.5F, 1.0F, 0xFF00FFFF,},}; the aforementioned code snippet fills three Vertex with three vertices of triangles and specifies the color of the scattered light of each vertex. The first vertex is located (150, 50), scattered red (0xffff0000). The second vertex is located in (250, 250), which is green (0xFF00FF00). The third point is located in (50, 250) and scattered blue green (0xFF00FFFF).
Every point has the same 0.5 z value and 1.0 RHW parameters. For other information on these vector formats, see SDK: Transformed and Lit Vertices. The next step will be called IDirect3DDevice8 :: CreateVertexBuffer creating vertex buffer, as shown in the following code segment: if (FAILED (g_pd3dDevice-> CreateVertexBuffer (3 * sizeof (CUSTOMVERTEX), 0 / * Usage * /, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, & g_pVB)) Return E_FAIL; CREATEVERTEXBUFFER's head two parameters tell the Direct3D new vertex buffer expected size and usage. The two parameters that specify the vector format and storage location of the new buffer. The vector format here is D3DFVF_CUSTomVertex, which is the FVF value previously defined by the routine. The D3DPool_Default tag tells Direct3D to create this vertex buffer in the most appropriate location. The last parameter returns to create the completed vertex buffer object address. After creating a vertex buffer, as shown in the following code segment, starting the data in the custom format in the vertex population buffer. Void * pvertices; if (Failed (G_PVB-> Lock (0, SizeOf (g_vertices), (byte **) & pvertices, 0)) Return E_FAIL; Memcpy (Pvertices, g_vertices, sizeof (g_vertices)); g_pvb-> unlock (); First call iDirect3dvertExbuffer8 :: Lock lock the vertex buffer. The first parameter of the function is the offset of the lock vertex data, and calculates by byte. The second parameter is the length of the vertex data that needs to be locked, and the same is calculated by byte. The third parameter is an address of a Byte type pointer to return the address of the vertex data. The fourth parameter informed the vertex buffer how to lock the data. By using Memcpy, the vertex is copied to the vertex buffer. After placing the vertex into the buffer, call the idirect3dvertExbuffer8 :: UNLOCK to unlock the vertex buffer. This lock-unlock mechanism is required because the vertex buffer that is being used may be located in the device memory. Now the vertex buffer has been filled in the vertices, and when drawing to the display, see Description: Step 3: Draw to the display. Step 3: Draw to the display Now the buffer has been filled in the vertices and now you need to draw it to the display. Before drawing the screen, remove the background as blue and call Beginscene. G_pd3ddevice-> Clear (0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB (0, 0, 255), 1.0F, 0L); g_pd3ddevice-> beginscene (); draws vertex data from the vertex buffer require some steps. First, you need to set the stream data source; in the current case, use the 0th stream. The stream of data is set by calling iDirect3ddevice8 :: setStreamSource. G_pd3ddevice-> setStreamSource (0, g_pvb, sizeof (customvertex)); The first parameter of SetStreamSource tells the Microsoft Direct3D device to set the index of the data stream. The second parameter is a vertex buffer bound to the stream. The third parameter is the size of the data unit, represented by bytes. In the sample code above, the size of Customvertex will be used as the size of the data unit.
Next, by calling IDirect3DDevice8 :: setvertexshader makes Direct3D to understand the Vertex Shader. For overall, the custom vertex processor is a high-level topic, but in most cases, the vertex processor is only equal to the FVF code. This enables Direct3D to know the vertex type in the process. The following code snippet sets the FVF to the current vertex processor: g_pd3ddevice-> setvertexshader (D3DFVF_CUSTomVertex); setVertexShader () unique parameter is the handle of the current set vertex processor. The value of this parameter can be the handle returned from idirect3ddevice8 :: CreatevertexShader, or FVF code. Here, the parameters used are defined as the FVF code for D3DFVF_CUSTomVertex. For more information on the vertex processor, please see the SDK: Vertex Shader. Next Using iDirect3DDevice8 :: DrawPrimitive to draw the vertices in the vertex buffer, see the following code snippet: g_pd3ddevice-> DrawPrimitive (D3DPT_TRIANGLIST, 0, 1); the first parameter accepted by DRAWPRIMTIVE is a tag, it notifies Direct3D which type PRITIVE. This routine is specified as a triangular sequence using the D3DPT_TRIANGLIST tag. The second parameter is the index of the first vertex. The number of items drawn by the third parameter notification. This example only draws a triangle, this value is 1. For more information on different kinds of objects, it can be seen that the final step of the SDK: 3-D Primitive is the end of the scene and immediately submits the rear back buffer as the foreground buffer. These are written in the following code snippet: g_pd3ddevice-> endscene (); g_pd3ddevice-> present (null, null, null, null); After the back buffer is submitted to the foreground buffer, the customer window will display a three point color. Different triangles. This guide already guides you how to use the vertex structure geometry shape. Guide 3: Use matrices to introduce the concept of matrices and how to use them. Guide 3: Using Matrix This guide introduces the concept of matrix and demonstrates how to use them. The Vertices routine draws a triangle by presenting 2D vertices. However, in this guide, you will work in a 3-D environment through the vertex. Matrices and transformations are also used to set up the photographic head and viewport. Before the Matrice routine presents a geometric object, it calls a program Custom Function SetupMatrice created and sets a matrix transform for demonstrating a 3-D triangle. As a representative, three types of transformations are simultaneously set to a 3-D scene. The steps to create these typical transformations are as follows: • First step: Define the World Transform Matrix • Step 2: Define Observation Transformation Matrices • Define Mapp Transform Matrices Note: The path to the Matrices sample program: (SDK root) / Samples / MultiMedia / Direct3D / Tutorials / TUT03_Matrice. Creating these three transformations does not affect the output of the scene element. In any case, Direct3D uses the following order to use the matrix on the scene: (1) World, (2) observation, (3) mapping. The sample code of the Matrice project is almost the same as the code of the Vertices project. The "Use Matrix" Guide only focuses on those about matrices, not repeated initialization Direct3D, processes Microsoft Windows messages, demos, and clears.
For information on these work, please see Guide 1: Create a device. This guide uses a custom vertex format and a single vertex buffer to deliver a geometric model, regarding more about selecting a custom vertex type and performing information on the vertex buffer, see Guide 2: Demo the vertices. The first step: Define the World Transformation Matrix World Transformation Matrix defines how to convert, zoom, and rotate the geometric objects in the 3-D simulation space. The following code snippet sets the current world transformation for Microsoft Direct3D devices and rotates the triangle around the Y-axis. D3DXMatrix Matworld; D3DXMatrixRotationy (& MatWorld, TimegetTime () / 150.0F); g_pd3ddevice-> setTransform (D3DTS_WORLD, & MATWORLD); The first step is to rotate the triangle around the Y-axis by calling the D3DXMAMATRIXROTATIONY function. The first parameter of the function is a pointer to the D3Dmatrix structure for returning the results. The second parameter is an angle of rotation indicated by radians. The next step is to call IDirect3dDevice8 :: setTransform to set the world transformation to Direct3D devices. The first parameter accepted by SetTransform is notified which conversion is set. This example is specified with a D3DTS_WORLD macro is a world transformation. The second parameter is a pointer to the matrix set to the current transformation. For more information on world transformation, see: SDK: World Transformation After the World Transformation of the Facture Field, you can prepare to observe the transform matrix. Once again please: Define the order in which any transformation is not the key. In any case, Direct3D uses these matrices on the scene in the following order: (1) World, (2) observation, (3) mapping. Define observation transformation matrices, please refer to the second step: Define the observation transformation matrix Step 2: Define the View Transformation Matrix observer that the transform matrix defines the position and rotation angle of the observation. This observation matrix is equivalent to the scene of the scene. The following code snippet creates an observation shift matrix and set it to the current observation matrix of the Microsoft Direct 3D device. D3DXMATRIX matView; D3DXMatrixLookAtLH (& matView, & D3DXVECTOR3 (0.0f, 3.0f, -5.0f), & D3DXVECTOR3 (0.0f, 0.0f, 0.0f), & D3DXVECTOR3 (0.0f, 1.0f, 0.0f)); g_pd3dDevice-> SetTransform ( D3DTS_VIEW, & MATVIEW); The first step is to define the observation matrix by calling D3DXMatrixLookatlh. The first parameter is a pointer to the D3DXMatrix structure to accept the results. Second, third, four parameters define observations, gaze, and direction "on". It sets this to the observation point for the 5 unit in the z-axis opposite direction, and the point is the origin of the origin, and as the "upper" direction is the Y-axis. The next step is to call IDirect3DDevice8 :: setTransform to set the matrix to the Direct3D device. The first parameter accepted by SetTransform is notified which transformation will be set. This routine is specified as a viewing matrix using the D3DTS_VIEW tag. The second parameter is a pointer to the matrix, which is set to the current transformation. For more information on the observation matrix, see: SDK: View Transformation After defining the world transformation of the scene, you can start preparing to map transform matrices. Once again, define the order of each transform is not critical.
In any case, Direct3D always applies the matrix to the scene in the following order: (1) World, (2) observation, (3) mapping. Defining the work of the mapping transformation matrix is described in the third step: Define the Mapping Matrix Step 3: Defining the Matrix Matrix matrix matrix definition of 3-D observation space to 2-D vision space Geometric method. The following code snippet creates a mapping transform matrix and sets it to the current mapping transformation of the Microsoft Direct 3D device. D3DXMATRIX matProj; D3DXMatrixPerspectiveFovLH (& matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f); g_pd3dDevice-> SetTransform (D3DTS_PROJECTION, & matProj); D3DXMatrixPerspectiveFovLH first step is to call the set mapping matrix. The first parameter of the function is a structure that points to D3DXMatrix for accepting the operation. The second parameter defines the field of view, which indicates how the object is reduced as the distance. A typical field of view is 1/4 π, just like this example. The third parameter defines the screen aspect ratio. This example uses a typical aspect ratio 1. The fourth and fifth parameters define the nearest and farthest shear planes. This is used to determine which geometry outside the distance is not needed. This MATRICES example sets its recent shear plane to 1, the farthest shear plane is 100. The next step is to call IDirect3dDevice8 :: setTransfrom to transform Direct3D application. The first parameter accepted by SetTransFrom notifies how Direct3D is set. This routine uses the D3DTS_PROJECTION flag to specify the mapping transformation will be set. The second parameter is a pointer to the matrix, which will be set to the current transformation. For more information on mapping transformation, see: "Mapping" This guide already prompts you how to use matrices. Guide 4: Creating and using the light source will reveal how to add a light source in your scene to increase authenticity. Guide 4: Creating and using the light source Microsoft Direc3d lighting system provides more authenticity to the 3-D object. When using it, geometric objects in each scene will be illuminated, based on their position and the type of light used. The routine of this guide will introduce the subject of light and material. This guide contains the following steps for creating material and illumination: • Step: Creating Scene geometry • Step 2: Setting Materials & Lights Note: Lights Sample Program The path is: (SDK root) / Samples / MultiMedia / Direct3D / Tutorials / tut04_lights. Note: The code in the Lights routine is almost exactly the same as the code of the Matrice routine. "Creating and Using the Light Source" guide simply focusing on creating and using the unique code of light, and does not repeat the contents of setting Direct3D, processing Microsoft Windows messages, draw, or cleaning. For additional information about these tasks, see: Guide 1: Create a device. This guide uses a custom vertex and the vertex buffer to deliver a geometric body. For more information on selecting a custom vertex format and performs vertex buffering, see: Guide 2: Demo the vertices. This guide uses a matrix transform geometric object. For more information on matrices and transformations, see: Guide 3: Use matrices. The first step: a premise of creating a scenario geometric use of illumination is that each surface should have a normal vector. To do this, the Lights routine uses a slightly different custom vertex format, the new custom vertex format has a 3-D position coordinate and a surface method vector.
This surface method is used for the core of Microsoft Direct3D light. struct CUSTOMVERTEX {D3DXVECTOR3 position; // The 3-D position for the vertex D3DXVECTOR3 normal; // The surface normal for the vertex..};. // Custom FVF #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL) vector is now suitable format definition Ok, the Lights routine calls InIgEMetry (), a program-defined function to create a cylinder. The initial step is to create a vertex buffer and save each point of this cylinder. , 0 / * usage * /, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, & G_PVB)) Return E_FAIL; Next is to fill the top buffer using the vertex of the cylinder. Note the following sample code, each point is defined in a location and a method of normal. For (dword i = 0; i <50; i ) {float theta = (2 * D3DX_PI * i) / (50-1); PVertices [2 * i 0] .position = d3dxvector3 (SINF (Theta), 1.0F, COSF (Theta)); Pvertices [2 * i 0] .NORMAL = D3DXVector3 (SINF (Theta), 0.0F, COSF (Theta)); Pvertices [2 * i 1] .position = d3dxvector3 (sinf (Theta), 1.0F, COSF (Theta)); PVertices [2 * i 1] .NORMAL = D3DXVector3 (SINF (Theta), 0.0F, COSF (Theta));} Fill in the aforementioned routine After the vertex buffer, this vertex buffer is ready to presented. But first, the material of this scene must be set before drawing the cylinder. These descriptions are in the second step: set the material and light. Step 2: Set the material and light to use light in Microsoft Direct 3D, you must create one or more light sources. In order to determine the light of a geometric object to radiate, the material must be created to draw the geometric object. Before drawing this scene, the Lights routine calls setuplights, a program custom function to set the material and a directional light source. Creating a material is defined as a color that is reflected when a bunch of illumination to the geometric object. The following code snippet uses the D3DMATERIAL8 structure to create a yellow material. D3DMaTerial8 mtrl; zeromemory (& mtrl, sizeof (d3dmaterial8)); mtrl.diffuse.r = mtrl.ambient.r = 1.0f; mtrl.diffuse.g = mtrl.Ambient.g = 1.0F; mtrl.diffuse.b = mtrl .Ambient.b = 0.0f; mtrl.diffuse.a = mtrl.ambient.a = 1.0f; g_pd3ddevice-> setmaterial (& mtrl); the diffused light color of this material is set to yellow.
The call to the idirect3ddevice8 :: setMaRial function will apply this material to the Microsoft Direct3D device for drawing the scene. The only parameter accepted by SetMaTerial () is a pointer to the material. After this call is completed, each item will use this material to draw until another call to SetMaTerial, specify a different material. Now the material has been applied to the scene, the next step is to create a light source. Create a light source Microsoft Direct3D has three available light sources: point light source, direction shape light source, and spotlight light source. This example code creates a direction-shaped light source that illuminates in one direction and the direction of transforming the lighting. The following codes use the D3DLight8 structure to create a directional light source. D3DXVECTOR3 VECDIR; D3DLIGHT8 Light; ZeromeMory (& Light, SizeOf (D3Dlight8)); Light.Type = D3DLight_Directional; The following code is set up the diffuse light of the light source is white. Light.diffuse.r = 1.0f; light.diffuse.g = 1.0f; light.diffuse.b = 1.0F; The following code chip rotates the direction of the light source within one ring. vecDir = D3DXVECTOR3 (cosf (timeGetTime () / 360.0f), 0.0f, sinf (timeGetTime () / 360.0f)); D3DXVec3Normalize ((D3DXVECTOR3 *) & light.Direction, & vecDir); D3DXVec3Normalize function call to the normalized Direction vector and initialize the direction of the light source. You can set a range telling Direct3D how far the source can affect how far. This member parameter is invalid to the directional light source. The following code chip specifies that this source range is 1000 units. Light.Range = 1000.0f; The following code is assigned to the current Direct3D device, by calling idirect3ddevice8 :: setLight. G_pd3ddevice-> setlight (0, & light); The first parameter accepted by Setlight is the index number assigned by this source. Note If there is a light source in this index, it will be overwritten by the new source. The second parameter is a pointer to the new defined light source data structure. This Lights routine sets this light source located in an index. The following Code is activated by calling IDirect3DDevice8 :: Lightenable. G_pd3ddevice-> lightenable (0, true); LIGHTENABLE accepts the first parameter is an index of the active light source. The second parameter is a booler to notify this light source is a TRUE or a false. In the above routine, the light source on the index 0 is opened. The following code notifies Direct3D to deliver this light source, by calling idirect3ddevice8 :: setRenderstate. G_pd3ddevice-> setrenderstate (d3drs_lighting, true); SETRENDERSTATE The first two parameters accepted are which device status variables are rewritten, and what is written. This routine sets the D3DRS_Lighting device variable to TRUE, which will enable the device to demonstrate the light effect. The last step of this routine is to open the environment illumination light by calling SetRenderstate again. G_pd3ddevice-> setrenderstate (D3DRS_AMBIENT, 0X00202020); the current code segment sets the D3DRS_AMBIENT device variable as a light gray (0x00202020). Environmental lighting will illuminate all objects using the color.
For more information on lighting and materials, see SDK: Lights and Materials. This example will explain how to use lighting and material. Guide 5: Use the texture mapping to explain how to add textures to the surface of the object. Guide 5: Use texture mapping although illumination and material greatly increases the real feeling of scenes, it is not more realistic than adding textures on the surface. Texture can be imagined to be tightly packaged in a sticker on the surface. You can place a layer of wooden texture on a cube makes it look like wood made of wood. This Texture routine will be in the guide 4: create and add a texture similar to bananas using a cylinder constructed in light. The contents of this guide describes how to load textures, set textures, and an object with texture. This guide uses the following steps to implement texture: • First step: Define a custom vertex format · Step 2: Initialization Screen Geometry · Step 3: Demonstration Scene Note: The path to the texture sample program: (SDK root) / Samples / MultiMedia / Direct3D / tutorials / tut05_textures. Note: In addition to the texture examples do not create materials and illumination, the sample code in the Texture project is almost exactly the same as the Lights project. This "Use Texture Map" guide simply focused on the unique code of the texture, and does not repeat the contents of the initialization Microsoft Direct 3D, processing Microsoft Windows messages, demonstrations, or cleaning. For information on these work, see: Guide 1: Create a device. This guide uses a custom vertex and a vertex buffer to display geometric objects. For more information on selecting a custom vertex format and performs vertex buffering, see: Guide 2: Demo the vertices. This guide uses a matrix to geometric transform. For more information on matrices and transformations, see: Guide 3: Use matrices. Step 1: Define a custom vertex format Before using the texture, you must use the custom vertex format containing the texture coordinates. Texture coordinates tell Microsoft Direct3D how to position textures on each vertex on the object. The texture coordinate range from 0.0 to 1.0, (0.0, 0.0) represents the left upper corner of the texture map (1.0, 1.0) represents the lower right corner of the texture map. The following sample code describes how the Texture routine contains texture coordinates by setting its custom vertex format. struct CUSTOMVERTEX {D3DXVECTOR3 position;. // The position D3DCOLOR color;. // The color FLOAT tu, tv; // The texture coordinates.};. // The custom FVF, which describes the custom vertex structure #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ D3DFVF_DIFFUSE | D3DFVF_TEX1) For further information on texture coordinates, see SDK: Texture Coordinates chapter. The custom vertex format is now ready, the next step will be loaded into a texture and create a cylinder, see Step 2: Initializing the screen geometry. Step 2: Initialization Screen Geometry Before drawing, the Texture routine calls InIitGeometry, a program-defined function is used to create a texture and initialize the geometric parameters of the cylinder. Texture is constructed from file-based images. The following sample code creates a texture from the banana.bmp file using D3DXCREATEXTEXTUREFROMFILE and covers the surface of the cylinder.
IF (Failed (D3DxCreateTextureFromfile (g_pd3ddevice, "banana.bmp", & g_ptexture)))) Return E_FAIL; D3DXCREATEXTUREFROMFILE accepting the first parameter is a pointer to the Microsoft Direct 3D device, which will be used to draw textures. The second parameter is a pointer to the ANSI string that specifies the file name used to create a texture. This routine is specified from this file: "banana.bmp" to load the image. The third parameter is an address pointing to the texture object pointer. When this similar banana texture is loaded and ready, the next step is to create a cylinder. The following example code fills the top buffer with a cylinder. Note that every point has texture coordinates (TU, TV). For (dword i = 0; i <50; i ) {float theta = (2 * D3DX_PI * i) / (50-1); PVertices [2 * i 0] .position = d3dxvector3 (SINF (Theta), 1.0, COSF (Theta)); Pvertices [2 * i 0] .Color = 0xfffffffff; Pvertices [2 * i 0] .tu = ((float) i) / (50-1); pVertices [2 * i 0] .tv = 1.0f; Pvertices [2 * i 1] .position = D3DXVector3 (SINF (Theta), 1.0, COSF (Theta)); Pvertices [2 * i 1] .color = 0xff808080; Pvertices [ 2 * i 1] .TU = ((float) i) / (50-1); PVertices [2 * i 1] .tv = 0.0F;} Each vertex includes location, color, and texture coordinates. The above routines give each point and wrap the cylindrical coordinates for each point. Now the texture and vertex buffer are ready to demonstrate, and now you can present and color graphics, see the third step: demo scene. Step 3: The demo scene is when the scene geometry is initialized, it should be a way of drawing the scene. To draw a textured object, the texture used must be set to one of the current texture. The next step will be the state of setting the ripple memory. Texture Memory Status allows you to define one or more textures that are presented. For example, you can mix multiple textures together. Now the Texture example starts setting the texture you need to use. The following code segments use idirect3ddevice8 :: setTexture to set the texture of the Microsoft Direct3D device for drawing. G_pd3ddevice-> setTexture (0, g_ptexture); The first parameter accepted by SetText is the marker setting the texture memory. A device can support eight initialized textures, so the maximum value of this is 7. This texture example only uses one texture and set it in memory 0. The second parameter is a pointer to the texture object. Here, the Texture example uses the texture created by its program custom function inIitGeometry. The following code is set to the value of the texture memory status, by calling the IDirect3DDevice8 :: SetTextureStageState method.
g_pd3dDevice-> SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE); g_pd3dDevice-> SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); g_pd3dDevice-> SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); g_pd3dDevice-> SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); SetTextureState of The first parameter is an index of a memory that needs to be changed. This example code changes the texture of the memory 0, so this is 0. The next parameter is the texture status to set. See "SDK: D3DTexturestagestateType" regarding all effective texture status and their meaning. Then the next parameter is the parameter set to this texture. The value you put this should depend on the status of the texture memory you want to change. After setting the appropriate value of each texture memory state, this cylinder can be presented, and now the texture will be added on its surface. Other methods of using texture coordinates are to generate them automatically. This is achieved with a texture coordinate index (TCI). TCI uses a texture matrix to transform (X, Y, Z) TCI coordinate (Tu, TV) texture coordinates. In the Texture routine, the vertex position located in the camera space is used to generate texture coordinates. The first step is to create a matrix for converting, demonstrate in the following code segment: D3DXMatrix Mat; Mat._11 = 0.00F; MAT._13 = 0.00F; MAT._14 = 0.00F; MAT ._21 = 0.00F; MAT._23 = 0.00F; MAT._24 = 0.00F; MAT._31 = 0.00F; MAT._32 = 0.00F; MAT._33 = 1.00F; MAT ._34 = 0.00F; MAT._41 = 0.50F; MAT._42 = 0.50F; MAT._43 = 0.00F; MAT._44 = 1.00F; After the matrix is created, it must be set by calling idirect3ddevice8 :: setTransform It is as shown in the following code segment: g_pd3ddevice-> setTransform (D3DTS_TEXTURE0, & MAT); D3DTS_TEXTURE0 flag tells Direct3D to apply this transformation to the texture of the texture memory 0. The next step in this example is to set other memory status values to get the desired effect. These processes are in the following code segments. g_pd3dDevice-> SetTextureStageState (0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); g_pd3dDevice-> SetTextureStageState (0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); the texture coordinates are set, this scene is now ready to be presented up. Note that the current coordinates are automatically set to the cylindrical. Such a precise setting makes the texture when the geometric object is shown is overwritten on the screen. For more information on textures, see SDK: Texture Chapter. This guide has explained how to add textures to the surface. Guide 6: Using the Mesh model will tell you how to apply a complex geometry for the Mesh model.
Guide 6: Complex geometry using the Mesh model often uses a 3-D modeling software constructor and saves as a file. An example is the .x file format. Microsoft Direct3D uses the Mesh object to load these objects from the file. The Mesh object is slightly complicated, but the function containing the Microsoft Direct3DX enables the application Mesh object to become simple. The Meshed routine introduces the topic of Mesh and showing how to load, demonstrate, and uninstall a Mesh object. This guide uses the following steps to explain how to load, demonstrate, and uninstall a Mesh object: • First step: Load a Mesh object · Step 2: Demonstrate an Mesh object · Step 3: Uninstall a Mesh object Note: Methes sample program The path is: (SDK root) / Samples / Multimedia / Direct3D / Tutorials / TUT06_MESH. Note: Example code for this project is almost exactly the same as the Lights project in addition to the sample code in the Meshes project. The "Using the Mesh Model" guide is only focused on the unique code of the Mesh object, and does not repeat the work of setting Microsoft Direct3D, processing Microsoft Windows messages, demonstrations, or cleaning. For information on these work, see: Guide 1: Create a device. This guide uses a custom vertex and a vertex buffer to display geometric objects. For more information on selecting a custom vertex format and performs vertex buffering, see: Guide 2: Demo the vertices. This guide uses a matrix to geometric transform. For more information on matrices and transformations, see: Guide 3: Use matrices. This guide uses texture to cover the surface of the MESH model. For more information on loading and using textures, see: Guide 5: Use texture mapping. Step 1: Mount a Mesh object before use, the Microsoft Direct 3D application must first load a Mesh object. The Meshes routine loads a tiger's Mesh model by calling InIgEMetry, a program-defined function, of course, after the required Direct3D object already loaded. A Mesh object requires a material buffer to save all materials and textures that will be used. So this function initially defines a material buffer, as shown by the following code segment: LPD3DXBuffer PD3DXMTRLBuffer; The following code segment loads the Mesh object using the D3DXLoadMethFromx function. // Load the mesh from the specified file if (FAILED (D3DXLoadMeshFromX ( "tiger.x", D3DXMESH_SYSTEMMEM, g_pd3dDevice, NULL, & pD3DXMtrlBuffer, & g_dwNumMaterials, & g_pMesh))) return E_FAIL;. The first parameter is a pointer to D3DXLoadMeshFromX acceptable character The string of the string tells Microsoft Direct3D to load the file. This routine reads a tiger's MESH model from Tiger.x. The second parameter notifies how Direct3D creates a Mesh object. This example uses a D3DXMESH_SYSTEMMEM tag, which is equal to specifying D3DxMesh_vb_systemmem with d3dxmesh_ib_systemmem, which tells Direct3D to put the index buffer of the Mesh object in the system memory. The third parameter is a pointer to the Direct 3D device that will be used to draw a Mesh object.
The fourth parameter is a pointer to the id3Dxbuffer object. This object is loaded with information about the neighborhoods adjacent to each side. This information is not required in this routine, so this parameter is set to NULL. The fifth parameter also achieves a pointer to id3dxbuffer. After the function is executed, this object will be filled in the D3DXMATERIAL structure used by the Mesh object. The sixth parameter is a pointer. After the function is executed, the number of D3DXMATERIAL structures placed in the PPMATERIALS queue is returned. The seventh parameter is an address of a Mesh object pointer, returns the loaded Mesh object. After loading this Mesh object and related material information, you need to decompose material properties and texture names from the material buffer. This MESH routine first needs to get the material buffer pointer to handle these things. The following code segment uses the ID3DXBuffer :: getBufferPointer function to get this pointer. D3DXMATERIAL * D3DXMATERIALS = (D3DXMATERIAL *) PD3DXMTRLBUFFER-> getBufferPointer (); The following code segment creates a new MESH and texture objects based on the maximum number of materials in the Mesh object. G_pmeshmaterials = new d3dmaterial8 [g_dwnummaterials]; g_pmeshtextures = new lpdirect3dtexture8 [g_dwnummateriality]; the material must be performed in each Mesh object must be made. The first step is to copy material, as shown in the following code segment. G_pmeshmaterials [i] = d3dxmaterials [i] .matd3d; the second step is to set the environment of the material value, see the following code segment. G_pmeshmaterials [i] .Ambient = g_pmeshmaterials [i] .diffuse; the final step is to create textures for the material, as the code segment below. // Create the texture if (FAILED (D3DXCreateTextureFromFile (g_pd3dDevice, d3dxMaterials [i] .pTextureFilename, & g_pMeshTextures [i]))) g_pMeshTextures [i] = NULL;.} Loaded each material after you finished using this cushioning material District, IUNKNOWN :: Release must be called to release it. PD3DXMTRLBUFFER-> Release (); now, the Mesh object, along with its corresponding material and texture, is already loaded. This Mesh object is ready to deliver to the screen, see the second step: demonstrate a Mesh object. Step 2: Demonstrate a Mesh object In the first step, the Mesh object has been presented to be presented. This object is divided into several subsets per material loaded by the Mesh object. To draw each subset, this Mesh object should be drawn in a loop. The first step of the loop is to set the material for each subset, as shown in the following code segment: g_pd3ddevice-> setMaterial (& g_pmeshmateriality-> setmaterial; the second step of the loop is to set the texture for each subset, as shown in the following code segment . G_pd3ddevice-> setTexture (0, g_pmeshtextures [i]); After each subset is set, the subset is drawn by the ID3DXBasemesh :: DrawSubset function, as shown in the following code segment. G_pmesh-> DrawSubset (i); DrawSubset function With a DWORD parameter to specify which subset of the Mesh object is drawn. This routine is added to each of the values of this parameter.