Many beginners of d3d are most confused about how to use d3d to achieve 2D effects, because DirectDraw does not exist anymore (of course you can still use previous versions, however, it may be difficult to use some recent hardware acceleration.) Here I will introduce several methods to compile 2D games using d3d.
Method 1:
Use the d3dx interface id3dxsprite,
Void drawsprite_2d (
Int dx, // X coordinate in the window
Int dy, // y coordinate in the window
Int Sx, // X coordinate in Tex texture
Int Sy, // y coordinate in Tex texture
Int SW, // The width of the subarea in the Tex texture
Int SH, // The height of the subarea in the Tex texture
Idirect3ddevice9 * device,
Id3dxsprite * Sprite,
Idirect3dtexture9 * Tex, // generated texture
Bool trans)
{
D3dxcolor c = d3dcolor_xrgb (255,255,255 );
D3dxmatrix identity;
D3dxmatrixidentity (& identity );
Rect R;
R. Left = SX;
R. Top = sy;
R. Right = SX + SW;
R. Bottom = SY + sh;
Device-> settransform (d3dts_world, & identity );
Device-> settransform (d3dts_view, & identity );
If (trans)
{
Sprite-> begin (d3dxsprite_alphablend );
}
Else
{
Sprite-> begin (0 );
}
// Draw the subarea in the texture on the specified screen Coordinate
Sprite-> draw (Tex, & R, 0, & d3dxvector3 (dx, Dy, 0), C );
Sprite-> end ();
}
Is it easy? However, you must note that d3d has some limitations on the texture size, which must be a power of N of 2. Therefore, if you want to use an image of any size to generate a texture, d3d will automatically convert it to the n-power texture of 2 during the generation process, some pull or sink effects will be generated in some processes, which makes it difficult to display the original effects of some images. The solution here is that when Drawing Images Using Photoshop and other software, it is best to specify the image length and width to x256 and other types, so that the image will not be generated when the id3dxsprite interface is used.
Method 2:
Use a parallel projection camera orthocamera
The program example here uses a four-sided image in a window as an example.
Struct vertex_t
{
Vertex_t ()
{
V = d3dxvector3 (0, 0, 0 );
C = d3dcolor_argb (0, 0, 0 );
}
Vertex_t (float X, float y, float Z)
{
V = d3dxvector3 (x, y, z );
C = d3dcolor_argb (, 0 );
}
Vertex_t (float X, float y, float Z, d3dcolor DIF)
{
V = d3dxvector3 (x, y, z );
C = DIF;
}
D3dxvector3 V;
D3dcolor C;
Static const DWORD fvf;
};
Const DWORD vertex_t: fvf = d3dfvf_xyz | d3dfvf_diffuse;
Void drawrect_2d (
Int X,
Int y,
Int W,
Int H,
D3dxcolor C0,
D3dxcolor C1,
D3dxcolor C2,
D3dxcolor C3,
Idirect3ddevice9 * device,
Bool trans,
Float alpha)
{
Vertex_t V [4];
D3dxmatrix proj, identity;
D3dxmatrixidentity (& identity );
D3dxmatrixorthooffcenterlh (& proj, 0.0f, (float) width,-(float)
Height, 0.0f,-1000000f, 1000000f );
Device-> settransform (d3dts_world, & identity );
Device-> settransform (d3dts_view, & identity );
Device-> settransform (d3dts_projection, & proj );
Device-> setrenderstate (d3drs_zenable, false );
If (trans)
{
Device-> setrenderstate (d3drs_alphablendenable, true );
Device-> setrenderstate (d3drs_srcblend, d3dblend_srcalpha );
Device-> setrenderstate (d3drs_destblend, d3dblend_invsrcalpha );
C0.a = Alpha;
C1.a = Alpha;
C2.a = Alpha;
C3.a = Alpha;
}
V [0] = vertex_t (x,-y, 0, C0 );
V [1] = vertex_t (x + W,-y, 0, C1 );
V [2] = vertex_t (x,-(Y + H), 0, C2 );
V [3] = vertex_t (x + W,-(Y + H), 0, C3 );
Device-> setfvf (vertex_t: fvf );
Device-> drawprimitiveup (d3dpt_trianglestrip, 2, V, sizeof (vertex_t ));
Device-> setrenderstate (d3drs_zenable, true );
Device-> setrenderstate (d3drs_alphablendenable, false );
}
Since there are few codes, the width and height variables in the Code are not described in detail here as the customer width and height of the window.
Method 3:
You can use the rhw of the vertex in the vertex format or d3dfvf_xyzrhw.
Rhw indicates that the vertex contains the data after illumination and coordinate transformation, and the data is the screen coordinate, because you can directly write the screen coordinate in the data structure of the vertex. I seldom use this method, but I have used it for experiment, because some code is not listed for the moment.
Method 4:
It is to draw a picture on a specified plane perpendicular to the camera in 3D space. Because there are two functions, one is to obtain the origin of the camera to a Ray on the screen, the other is the intersection of rays and planes,
With this intersection point, you can draw four sides in 3D space to display 2D images,
The key is the first function. The intersection of rays and planes can be directly obtained by mathematical knowledge.
The following function is used to calculate the rays of the camera origin connected to this point after the mouse clicks the client area of the window.
Ray_t cperspectivecamera: getray (int x, int y)
{
Int W = M_w; // d3d drawing area width
Int H = m_h; // The height of the d3d drawing Area
D3dxmatrix matproj;
Matproj = getprojmatrix (); // obtain the projection matrix.
Point ptcursor;
Ptcursor. x = X;
Ptcursor. Y = y;
D3dxvector3 V;
V. x = (2.0f * ptcursor. X)/W)-1)/matproj. _ 11;
V. Y =-(2.0f * ptcursor. Y)/H)-1)/matproj. _ 22;
V. z = 1.0f;
D3dxmatrix matview, M;
Matview = getviewmatrix ();
D3dxmatrixinverse (& M, null, & matview );
Ray_t _ ray;
_ Ray. dir. x = V. x * M. _ 11 + v. y * M. _ 21 + v. z * M. _ 31;
_ Ray. dir. Y = V. x * M. _ 12 + v. y * M. _ 22 + v. z * M. _ 32;
_ Ray. dir. z = V. x * M. _ 13 + v. y * M. _ 23 + v. z * M. _ 33;
_ Ray.org. x = M. _ 41;
_ Ray.org. Y = M. _ 42;
_ Ray.org. z = M. _ 43;
Return _ ray;
}
As this function is part of the program I have compiled, some functions do not provide the original program here, but it does not affect reading this program. Please forgive me.
The above is the method I know to draw 2D images in d3d. If you have any good methods, please advise.
If any of the preceding errors occurs, please correct them to avoid misleading them.
Thank you.