Document directory
- Source program download
- 1. Create an empty form
- 2. Join the earth:
- 3. rotating the earth
- 4. Joining the moon
- 5. Interaction with the mouse
- Vi. Conclusion
Source program download 1. Create an empty form to create a project, add references, and import the namespace. Add a device object variable: Private Microsoft. directX. direct3d. device device = NULL; Add the initialization graph function and instantiate the device object here: Public void initializegraphics () {presentparameters presentparams = new presentparameters (); presentparams. required wed = true; presentparams. swapeffect = swapeffect. flip; presentparams. autodepthstencilformat = depthformat. d16; presentparams. enableautodepthstencel = true; device = new Microsoft. directX. direct3 D. device (0, Microsoft. directX. direct3d. devicetype. hardware, this, createflags. hardwarevertexprocessing, presentparams);} when the program is executed, You need to draw the scenario. The code is in this function: Public void render () {// clear the device and prepare to display the next frame. Device. clear (clearflags. target | clearflags. zbuffer, color. black, 1.0f, 0); // set the camera position setupcamera (); // start scene device. beginscene (); If (meshloaded) {mesh. render (meshloc);} device. endscene (); // display the device content. Device. present ();} sets the camera location: Private void setupcamera () {Device. transform. projection = matrix. perspectivefovlh (float) math. PI/4, this. width/This. height, 1.0f, 1000.00f); device. transform. view = matrix. lookatlh (New vector3 (0.0f, 0.0f, 20366f), new vector3 (0.0f, 0.0f, 0.0f), new vector3 (, 0);} change the main function now, call the initialization function we wrote and display the scenario: [stathread] Static void main () {using (form1 earthform = new form1 () {ear Thform. initializegraphics (); earthform. show (); While (earthform. created) {earthform. render (); application. doevents ();} earthform. dispose ();} run the program. An empty form is displayed. 2. Add the earth: In this step, you need to create a 3D Grid Object to serve as the earth to be displayed. Therefore, add a class Earth to the project, this class can contain the information of the created Grid Object. Add related variables. For meanings, see comments: public class Earth: baseearth {private material [] mmaterials; // Save the material private texture [] mtextures; // Save the texture private matrix locationoffset; // used to save the relative position of the mesh object private mesh mmesh = NULL; // The Triangle Mesh object private device meshdevice; // the device on which the object needs to be displayed .} In the constructor, copy the device to a private member variable so that it can be used in other methods of this class. In addition, assign a value to the location variable: public Earth (ref device, matrix location): Base (ref device) {meshdevice = device; locationoffset = location;} The following function is loaded. X file. Public bool loadmesh (string meshfile) {extendedmaterial [] mtrl; try {// Load file mmesh = mesh. fromfile (meshfile, meshflags. managed, meshdevice, out mtrl); // if there are materials, load them if (mtrl! = NULL) & (mtrl. length> 0) {mmaterials = new material [mtrl. length]; mtextures = new texture [mtrl. length]; // obtain the material and texture for (INT I = 0; I <mtrl. length; I ++) {mmaterials [I] = mtrl [I]. material3d; If (mtrl [I]. texturefilename! = NULL) & (mtrl [I]. texturefilename! = String. empty) {// The texture Path obtained above is the relative path, and the absolute path needs to be saved. Through the Application Path, mtextures [I] = textureloader can be obtained. fromfile (meshdevice ,@".. /.. /"+ mtrl [I]. texturefilename) ;}}return true;} catch {return false ;}} in this method, use mesh. fromfile () method, found from the given file name. X file, and load the relevant data. Once the data format is set, you can find the material and texture information in the file, store it in the array, and use the File Path, obtain the path of the texture file, and finally return the true value. If an error occurs throughout the process, the false value is returned. The render () method below is to display this object, that is, the earth on the device object. This method is relatively simple. Through deformation operations, the X, Y, and zcoordinates of the Grid Object are obtained, set the material and texture of the mesh object, and apply each material and texture to each mesh. Public void render (matrix worldtransform) {/changes the position to the world coordinate meshdevice. transform. world = matrix. multiply (locationoffset, worldtransform); // draw the grid for (INT I = 0; I <mmaterials. length; I ++) {meshdevice. material = mmaterials [I]; meshdevice. settexture (0, mtextures [I]); mmesh. drawsubset (I) ;}} now return to the form code and add the variable that references the Grid Object: Private Earth mesh = NULL; private matrix meshloc; private bool meshloaded = false; In functions, You need to initialize the Grid Object. Add the following code: meshloc = matrix. identity; meshloc. m41 = 2.0f; mesh = New Earth (ref device, meshloc); If (mesh. loadmesh (@".. /.. /Earth. X ") {meshloaded = true;} the first sentence of the Code sets the position of the Grid Object as the origin, and then offsets the X axis in two units. Then, this is obtained from the file. X file. If it is set successfully, meshloaded is set to true. Note that there is a. X file in the source code. In the camera setting function, add a light: device. lights [0]. type = lighttype. directional; device. lights [0]. diffuse = color. white; device. lights [0]. direction = new vector3 (0,-1,-1); device. lights [0]. update (); device. lights [0]. enabled = true; this light is relatively simple. It is only a direct white light. Finally, in the render () method, call the render () method of the Grid Object to display the earth. 3. Before the Earth rotates, a grid object is used to create the earth. However, there are no methods such as translation, rotation, and scaling. The following describes these methods because these methods are universal, therefore, you can create a new class and write these methods in these classes so that the earth object becomes its derived class. Add a new class in the project: baseearth; Add the variable for translation, rotation, and scaling: Private float xloc = 0.0f; private float yloc = 0.0f; private float zloc = 0.0f; private float xrot = 0.0f; private float yrot = 0.0f; private float Zrt = 0.0f; private float XScale = 1.0f; private float yscale = 1.0f; private float zscale = 1.0f; add the corresponding Property Code: public float xloc {get {return xloc;} set {xloc = value ;}}............ In the render () virtual function, apply translation, rotation, and scaling. Public Virtual void render () {objdevice. multiplytransform (transformtype. world, matrix. translation (xloc, yloc, zloc); objdevice. multiplytransform (transformtype. world, matrix. rotationaxis (New vector3 (1.0f, 0.0f, 0.0f), xrot); objdevice. multiplytransform (transformtype. world, matrix. rotationaxis (New vector3 (0.0f, 1.0f, 0.0f), yrot); objdevice. multiplytransform (transformtype. world, matrix. rotationaxis (n EW vector3 (0.0f, 0.0f, 1.0f), Zrt); objdevice. multiplytransform (transformtype. world, matrix. scaling (XScale, yscale, zscale); return;} Now back to the ground ball, you need to change it to the derived class of the new class, and change the constructor. In addition, in the render () method, you should first call the render () method of the base class: Public override void render () {base. render (); // change the location to the world coordinate // meshdevice. transform. world = matrix. multiply (locationoffset, worldtransform); // draw a grid ......} Now, because the object location can be set in the base class, you can comment out the variables and statements related to locationoffset. 4. Adding the moon to the moon in this step is actually creating a new grid object instance. You just need to change the texture to make the code more efficient, place the two objects in a new class cmodel, add a class cmodel in the project, and declare the object instance. Public class cmodel {private cmeshobject mesh1 = NULL; private cmeshobject mesh2 = NULL; private bool modelloaded;} Put the load () event in the window code in the cmodel. This time, not only the earth is generated, and the moon is generated. Public void load (ref device) {mesh1 = New Earth (ref device); mesh2 = New Earth (ref device); If (mesh1.loadmesh (@".. /.. /earth2.x ") {modelloaded = true;} else {modelloaded = false;} If (mesh2.loadmesh (@".. /.. /moon. X ") {mesh2.xloc + = 20.0f; modelloaded = true ;}else {modelloaded = false ;}} in the update () method below, the dir parameter is used to determine whether the rotation is clockwise or counter-clockwise. In addition, the angle size of the earth and the moon around the Y axis is different, which determines the rotation speed of the two. Public void Update (int dir) {If (dir> 0) {mesh1.yrot + = 0.02f; mesh2.yrot + = 0.05f;} else if (DIR <0) {mesh1.yrot-= 0.02f; mesh2.yrot-= 0.05f ;}} in the render () method below, generate the lunar and earth display: Public void render (ref device) {Device. transform. world = matrix. identity; If (modelloaded) {mesh1.render (); mesh2.render () ;}} puts the method of adding the window code to the light in this class: Public void loadlights (ref device) {Device. lights [0]. type = Lighttype. directional; device. lights [0]. diffuse = color. white; device. lights [0]. position = new vector3 (0.0f, 0.0f, 25366f); device. lights [0]. direction = new vector3 (0, 0,-1);} public void light (ref device) {Device. lights [0]. update (); device. lights [0]. enabled = true;} 5. to interact with the keyboard and mouse, add a new class: cmouse and reference Microsoft. directX. directinput and add a namespace. Add related variables: Private Microsoft. directX. directinput. device mouse = NULL; public system. threading. autoresetevent mouseupdated; private float x, y, z = 0.0f; private byte [] buttons; in the following constructor code, first create a mouse device and initialize the callback event: public cmouse (system. windows. forms. control) {mouse = new Microsoft. directX. directinput. device (systemguid. mouse); mouse. setcooperativelevel (control, cooperativelevelflags. background | coope Rativelevelflags. nonexclusive); mouse. properties. axismodeabsolute = false; mouseupdated = new system. threading. autoresetevent (false); mouse. seteventnotification (mouseupdated); mouse. acquire (); Update () ;}the following update () method obtains the coordinate value of the mouse and assigns it to the private member variable: Public void Update () {mousestate state = mouse. currentmousestate; X = state. x; y = state. y; Z = state. z; buttons = state. getmousebuttons ();} also needs a function to check whether the left mouse button is pressed: P Ublic bool leftbuttondown {get {bool a; Return A = (buttons [0]! = 0) ;}} 6. The final stage is now ready. Return to the window code and make some adjustments to the Code: create a cmodel class and a cmouse class in the graphic initialization function: Private cmodel model = NULL; private cmouse mouse = NULL; private bool leftbuttondown = false; private float mousexloc; add the initialization method for the mouse: Public void initializeinput () {mouse = new cmouse (this);} Add the updateinputstate () method. When you press the left mouse button, set the leftbuttondown value to true, when you move the mouse up, set mousexloc to 0: Private void updateinputstate () {mouse. update (); If (mouse. l Eftbuttondown) {If (leftbuttondown = false) {mousexloc = 0.0f; leftbuttondown = true;} else {mousexloc =-mouse. X ;}} else {leftbuttondown = false; mousexloc = 0.0f ;}} in this program, only the X value is operated, that is, only the left and right conversion is allowed. The render () method is updated as follows: public void render () {updateinputstate (); device. clear (clearflags. target | clearflags. zbuffer, color. darkgray, 1.0f, 0); setupcamera (); device. beginscene (); Model. update (INT) mousexloc); Model. light (ref device); Model. render (ref device); device. endscene (); device. present ();} finally changed main () main function: static void main () {using (form1 earthform = new form1 () {earthform. initializegraphics (); e Arthur form. initializeinput (); earthform. show (); While (earthform. created) {earthform. render (); application. doevents ();} earthform. dispose ();} run the program. Press the left mouse button and drag it to rotate the Moon and the Earth.