ZZ: DirectX9 3D quick start 5

xiaoxiao2021-03-05  33

DirectX9 3D quick start 5

The content of this chapter is relatively simple, controlling Mesh movement, rotation, etc., in fact, all this is in the matrix. In DX, there are three types of transformations, one is based on the Word coordinate system, one is based on the VIEW coordinate system, and has a projection-based transformation. These transformations are implemented by the calculation of the matrix, and in the host of the .NET, implement these operations relative to the non-hosting, and do not use each value of the matrix.

There are many articles about the relationship between the array of operations and transformations, and Gameres has a lot of good articles, for example: http: //dev.gameres.com/program/visual/3d/3DGame.mht is very detailed Introduce.

Our article does not study details, because after all, it is rapidly developed, our goal is to control the motion of the read Mesh with a keyboard.

In fact, in the previous article, we have mentioned several functions, just not introduced. Let's take a look at several simple functions to use in this article. From the literal, we can judge what these functions are:

Matrix.Rotatex method: public void rotatex (float angle);

Matrix. Rotatey method: public void rotatey (float angle);

Matrix.Rotatex method: public void rotatez (float angle);

Matrix.Translation method: Public Static Matrix Translation (Float OffsetX, Float Offsety, Float Offsetz);

Ok, we now reopen the project of the last reading of Mesh. We now have to join the new part. Since it is to use the keyboard to control the status of the keyboard to analyze the status:

String status = null; // Used to save status

Protected Override Void onkeyDown (System.Windows.Forms.Keyeventargs E)

{

// handle the escape key for quiting

IF (e.keycode == keys.escape)

{

// Close the form and return

THIS.CLOSE ();

Return;

}

// Handle Left and Right Keys

Else IF ((E.Keycode == Keys.Left) || (E.KEYCODE == Keys.Numpad4)))

{

Status = "left"; / / Rotate left

}

Else IF ((E.Keycode == Keys.right) || (E.KEYCODE == Keys.Numpad6))

{

Status = "right"; // Rotate right

}

Else IF ((e.keycode == keys.up) || (e.keycode == keys.numpad8))

{

Status = "UP"; // Rotate up

}

Else IF ((e.keycode == keys.down) || (E.KeyCode == Keys.Numpad2))

{

Status = "down"; / / rotate down

}

Else if (e.keycode == keys.enter)

{

STATUS = "stop"; // Stop rotation}

Else if (e.keycode == keys.w)

{

Status = "goahead"; // forward

}

Else if (E.Keycode == Keys.s)

{

STATUS = "goback"; //

}

Else if (e.keycode == keys.a)

{

Status = "goeft"; // left

}

Else if (e.keycode == keys.d)

{

Status = "goright"; //

}

}

It is very simple, so that there is nothing to say, let's move on Mesh, because our observation movement is relatively moving, so no matter whether you operate on the camera or the world transformation, it is good. We modify the DrawMesh function, mainly the status of the status, and then transform the corresponding matrix:

Private void Drawmesh (String Stat)

IF (stat == "left")

{

Angle = Angle

0.1f;

Device.Transform.World = Matrix.RotationY (ANE);

}

Else IF (stat == "right")

{

Angle = angle

-0.1f;

Device.Transform.World = Matrix.RotationY (ANE);

}

Else IF (stat == "UP")

{

Angle = Angle

0.1f;

Device.Transform.World = Matrix.RotationX (ANGLE);

}

Else IF (stat == "down")

{

Angle = angle

-0.1f;

Device.Transform.World = Matrix.RotationX (ANGLE);

}

Else IF (stat == "stop")

{

Angle =

0.0F;

//Device.reset ()

}

Else IF (stat == "goahead")

{

v = v

0.1f;

}

Else IF (stat == "goback")

{

v = v

-0.1f;

}

Else IF (stat == "goeft")

{

OFFSETX = OffsetX

0.01F;

Device.Transform.World = Matrix.Translation (Offsetx, 0,0);

}

Else IF (stat == "goright")

{

OFFSETX = Offsetx

-0.01F;

Device.Transform.World = Matrix.Translation (Offsetx, 0,0);

}

For (int i = 0; i

{

Device.material = meshmaterials [i];

Device.Settexture (0, Meshtextures [i]);

Mesh.drawsubset (i);

}

}

Public: void rotatex; public function rotatex (Angle: float); Here we handle the movement of the car before and after the move, but the camera is used to operate, which is very understandable, in order to achieve this Outcome, I have modified the setupcamera function of the SETUPCAMERA function:

Private void setupcamera (Float Deep)

{

Device.Transform.Projection = Matrix.Perspectivefovlh (FLOAT) Math.pi / 4, this.width / this.height,

1.0f,

10000.0f);

Device.Transform.View = Matrix.lookatlh (New Vector3 (0, 0,

10.0f deep), new vector3 (), new vector3 (0, 1, 0));

Device.lights [0] .type = lightttype.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;

}

I added a parameter, this parameter is the location of the camera in the Z-axis. We only need to modify the camera in the Z-axis, you can achieve perspective effect, using this method to implement our simple demand is very appropriate.

Here is the 2 functions of this here:

Device.Transform.Projection is used to get or set a projection transform matrix, which is also a Matrix type variable. Matrix.PerspectiveFovLH method:

Public Static Matrix PerspectiveFovlh (Float FieldofViewy, Visual range, radians, namely Y direction "horror horns FLOAT Aspectratio, // Visual range as long as float znearplane, // close-up reduction plane float zfarplane // far Cutting plane);

Compared with the non-hosting, only one parameter is only. The definition of the aspect ratio is that if the user changes the size of the window, then the size of the object can be displayed correctly. The last two parameters are near-far cut planes, and 2 Z values ​​must be specified for these two planes. In general, it is assumed that the object will be in the Z axis.

1.0F and

When exercising between 1000f, the two parameters are set to

1.0f,

1000.0f.

Let's take another way: Matrix.lookatlh method. After using the observation matrix to create a stereo camera model, the player is allowed to see the world through a series of different observation points, using the camera model established by the Matrix.lookATLH method, is a very efficient camera model, but pay attention, this The model cannot be rotated around all axes.

Public Static Matrix Lookatlh (Vector3 CameraPosition, // Camera Location Vector3 Cameratarget, // Camera's Direction Vector3 Cameraupvector // Camera UP Vector);

The second parameter is the face direction of the camera, assuming that the camera faces the direction of the Z axis, then set to (0, 0, 1). Ok, now someone is going to ask, what if the opposite is the negative direction of the z-axis? This is the purpose of the third parameter, the third parameter set up a UP vector, so if the camera is pushed, then the third parameter should be (0, 1, 0), if it is put it, it is (0, -1, 0). Therefore, if the negative direction of Z is facing, the third parameter is (0, -1, 0). With this method, we can easily build a follow-up camera, such as implementing the first person's viewing angle, just pointing the second parameter to the direction of the object, setting the camera position as the object around this object. We mentioned before, such cameras cannot rotate themselves.

Ok, let's simply implement this feature, we want the car to keep the camera to follow it, first of all, we must get the read Mesh X, Y, Z. You can provide the first parameter to the camera. Second, we have to determine the head, here, it is very good, because the car is open to the Z direction, it is ok, we can write the code. In order to get the position of the Mesh, you should use the Mesh built-in point buffer.

.......................................... ..

Loadmesh (@ "../../ sr.x");

VB = Mesh.vertexBuffer; // Get the center of reading in Mesh

Try

{

Vector3 max;

Vector3 min;

GraphicsStream GS = VB.LOCK (0, 0, Lockflags.none);

Geometry.computeBoundingBox (GS, Mesh.Numbervertices, Mesh.VertexFormat, Out min, out max); // Get the Border of Mesh

FLOAT TX = (Max.x - min.x) / 2;

FLOAT TY = (Max.y - min.y) / 2;

FLOAT TZ = (Max.Z - min.z);

Pos.x = TX

-0.9f; // Try out, so that the camera will approximate in the center of the car

POS.Y = TY

0.6F;

Pos.z = tz

-1.8F;

// Float CameraHeadingh =

Lookat = New Vector3 (0,0,1);

}

Finally

{

vb.unlock ();

vb.dispose ();

}

Modify KeyDown and modify the setupcamera function to determine the choice of the camera.

Private void setupcamera (Float Deep)

{

Device.Transform.Projection = Matrix.Perspectivefovlh (FLOAT) Math.pi / 4, this.width / this.height,

1.0f,

10000.0f);

IF (CAMERA% 2! = 0)

Device.Transform.View = Matrix.lookatlh (New Vector3 (0, 0,

10.0f deep), new vector3 (), new vector3 (0, 1, 0));

Else

Device.Transform .View = Matrix.lookatlh (POS, New Vector3 (0, 1, 0), New Vector3 (0, 1, 0));

Device.lights [0] .type = lightttype.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 completes this feature, but here is just simply simulated, only the effect is only in the back of the back, but because there is no reference, it does not see the changes in the picture during the forward retreat. The complete code is posted below:

Using system;

Using system.drawing;

Using system.collections;

Using system.componentmodel;

Using system.windows.forms;

Using system.data;

Using Microsoft.directX;

Using Microsoft.directx.direct3d;

Namespace Chapter5code

{

///

/// summary description for Form1.

///

Public Class Form1: System.Windows.Forms.form

{

PRIVATE DEVICE DEVICE = NULL;

PresentParameters Presentparams = NULL;

PRIVATE MESH MESH = NULL;

Private Material [] Meshmaterials;

PRIVATE TEXTURE [] Meshtextures;

PRIVATE MESH MESH2 = NULL;

Material [] meshmaterials2;

TEXTURE [] Meshtextures2;

String status = NULL; // Car status, turn left or turn right to right, or stop

Private VertexBuffer VB = NULL;

Vector3 POS;

Vector3 lookat;

INT Camera = 1;

Float angle =

0.0F;

Float v =

0.1f;

Float offsetx =

0.1f;

///

/// Required Designer Variable.

///

Private system.componentmodel.Container Components = NULL;

Public Form1 ()

{

//

// Required for Windows Form Designer Support

//

InitializationComponent ();

This.SetStyle (ControlStyles.allpaintingInwmpaint | Controlstyles.opaque, true);

}

///

/// We Will Initialize Our Graphics Device Here

///

Public void initializegraphics ()

{

// setur presentation parameters

PresentParameters Presentparams = New Presentparameters ();

Presentparams.windowed = true;

Presentparams.swapeffect = swapeffect.discard; presentparams.autodepthstencilformat = depthformat.d16;

Presentparams.enableAutodepthstencil = true;

// Create Our Device

Device = New Device (0, DeviceType.hardware, this, createflags.softwarevertexprocessing, presentparams);

// loading ou Mesh

Loadmesh (@ "../../ sr.x");

VB = Mesh.vertexBuffer; // Get the center of reading in Mesh

Try

{

Vector3 max;

Vector3 min;

GraphicsStream GS = VB.LOCK (0, 0, Lockflags.none);

Geometry.comPuteBOUNDINGBOX (GS, Mesh.Numbervertices, Mesh.vertexFormat, Out min, Out max);

FLOAT TX = (Max.x - min.x) / 2;

FLOAT TY = (Max.y - min.y) / 2;

FLOAT TZ = (Max.Z - min.z);

Pos.x = TX

-0.9f;

POS.Y = TY

0.6F;

Pos.z = tz

-1.8F;

// Float CameraHeadingh =

Lookat = New Vector3 (0,0,1);

}

Finally

{

vb.unlock ();

vb.dispose ();

}

}

Private void loadmesh (string file)

{

ExtendedMaterial [] mtrl;

// loading ou Mesh

Mesh = Mesh.fromfile (File, Meshflags.Managed, Device, Out mtrl);

// if we have any matials, store them

IF ((mtrl! = null) && (mtrl.length> 0))))

{

Meshmaterials = new massial [mtrl.length];

Meshtextures = new texture [mtrl.length];

// Store Each Material and Texture

For (int i = 0; i

{

Meshmaterials [i] = mtrl [i] .MATERIAL3D;

IF ((mtrl [i] .texturefilename! = null) && (mtrl [i] .textureFileName! = String.empty)))))

{

// WE Have a Texture, Try to loading IT

Meshtextures [i] = textureloader.fromfile (device, @ "../../" mtrl [i] .textureFileName);

}

}

}

}

Protected Override Void onkeyDown (System.Windows.Forms.Keyeventargs E)

{

// handle the escape key for quiting

IF (e.Keycode == Keys.escape) {

// Close the form and return

THIS.CLOSE ();

Return;

}

// Handle Left and Right Keys

Else IF ((E.Keycode == Keys.Left) || (E.KEYCODE == Keys.Numpad4)))

{

STATUS = "Left";

}

Else IF ((E.Keycode == Keys.right) || (E.KEYCODE == Keys.Numpad6))

{

Status = "right";

}

Else IF ((e.keycode == keys.up) || (e.keycode == keys.numpad8))

{

STATUS = "UP";

}

Else IF ((e.keycode == keys.down) || (E.KeyCode == Keys.Numpad2))

{

Status = "Down";

}

Else if (e.keycode == keys.enter)

{

Status = "stop";

}

Else if (e.keycode == keys.w)

{

Status = "goahead";

}

Else if (E.Keycode == Keys.s)

{

STATUS = "goback";

}

Else if (e.keycode == keys.a)

{

STATUS = "goeft";

}

Else if (e.keycode == keys.d)

{

Status = "goright";

}

Else if (e.keycode == keys.c)

{

Camera ;

}

}

Private void setupcamera (Float Deep)

{

Device.Transform.Projection = Matrix.Perspectivefovlh (FLOAT) Math.pi / 4, this.width / this.height,

1.0f,

10000.0f);

IF (CAMERA% 2! = 0)

Device.Transform.View = Matrix.lookatlh (New Vector3 (0, 0,

10.0f deep), new vector3 (), new vector3 (0, 1, 0));

Else

Device.Transform .View = Matrix.lookatlh (POS, New Vector3 (0, 1, 0), New Vector3 (0, 1, 0));

//Device.renderstate.Ambient = color.darkBlue;

Device.lights [0] .type = lightttype.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;

}

Protected Override void onpaint (system.windows.Forms.painteventargs e) {

Device.clear (Clearflags.target | Clearflags.zbuffer, Color.CornflowerBlue,

1.0F, 0);

Setupcamera (V);

DEVICE.BEGINSCENE ();

// Draw Our Mesh

Drawmesh;

Device.endscene ();

Device.Present ();

THIS.INVALIDATE ();

}

Private void Drawmesh (String Stat)

{

// angle =

0.01F;

// Device.Transform.World = Matrix.RotationYawpitchroll (YAW, Pitch, Roll) * Matrix.translation (x, y, z);

IF (stat == "left")

{

Angle = Angle

0.1f;

Device.Transform.World = Matrix.RotationY (ANE);

}

Else IF (stat == "right")

{

Angle = angle

-0.1f;

Device.Transform.World = Matrix.RotationY (ANE);

}

Else IF (stat == "UP")

{

Angle = Angle

0.1f;

Device.Transform.World = Matrix.RotationX (ANGLE);

}

Else IF (stat == "down")

{

Angle = angle

-0.1f;

Device.Transform.World = Matrix.RotationX (ANGLE);

}

Else IF (stat == "stop")

{

Angle =

0.0F;

//Device.reset ()

}

Else IF (stat == "goahead")

{

v = v

0.1f;

}

Else IF (stat == "goback")

{

v = v

-0.1f;

}

Else IF (stat == "goeft")

{

OFFSETX = OffsetX

0.001F;

Device.Transform.World = Matrix.Translation (Offsetx, 0,0);

//Device.transform .view = matrix.translation (offsetx, 0,0);

// pos.x - = OFFSETX;

// device.transform .view = matrix.lookatlh (POS, New Vector3 (0, 1), New Vector3 (0, 1, 0));

}

Else IF (stat == "goright")

{

OFFSETX = Offsetx

-0.001F;

Device.Transform.World = Matrix.Translation (Offsetx, 0,0);

}

For (int i = 0; i

{

Device.material = meshmaterials [i]; device.settexture (0, Meshtextures [i]);

Mesh.drawsubset (i);

}

}

///

/// Clean Up Any Resources Being Used.

///

Protected Override Void Dispose (Bool Disposing)

{

IF (Disposing)

{

IF (Components! = NULL)

{

Components.dispose ();

}

}

Base.dispose (Disposing);

}

#Region Windows Form Designer Generated Code

///

/// Required Method for Designer Support - Do Not Modify

/// The contents of this method with the code editor.

///

Private vidinitiRizeComponent ()

{

This.Components = new system.componentmodel.container ();

This.size = new size (800, 600);

THIS.TEXT = "Form1";

}

#ndregion

///

/// The main entry point for the application.

///

Static void

Main ()

{

Using (Form1 FRM = New Form1 ())

{

// Show Our Form and Initialize Our Graphics Engine

Frm.show ();

frm.initializegraphics ();

Application.run (frm);

}

}

}

}

Good luck, end.

转载请注明原文地址:https://www.9cbs.com/read-33376.html

New Post(0)