Objective:
The color of an entity is determined by the color of the vertex that makes up the entity, and the object is composed of Tugenso. So if we're going to draw a triangle with a color, we need to attach a color attribute to the triangle element vertex.
The color representation in 1.direct3d:
In Direct3D, colors are expressed in RGB (as we all know, cough.) The unobstructed human color can be divided into red (red), Green, Blue (bule). These three components are blended to achieve the desired color for the purpose. RGB data can be stored in two ways, one is D3dcolor, the other is: DWORD. This is because d3dcolor is exactly the same as DWORD(in MSDN:
typedef DWORD D3DCOLOR;) The alpha component is not described first. Because that's not going to work.
To specify a value for each color component and insert it into d3dcolor, you need to use the D3DCOLOR_ARPG macro. This macro helps us to implement the binary operation.
How to use:
D3dcolor brightred = D3dcolor_argb (255, 255, 0, 0);
Also describes the storage structure of another color data:D3dcolorvalue。
typedef struct _D3DCOLORVALUE { float R; float g; float B; float A;} D3dcolorvalue;
A single-precision number is used to measure the luminance value of each component, and the value range is 0~1.
But this structure is seldom used. Because the d3dcolorvalue structure can be converted to D3dcolor, and D3dcolor is more powerful than the function methods that d3dcolorvalue contains.
2. Coloring:
Here's the first thing to say about Rasterization: a simple understanding, in real life, if you draw a triangle, each line is made up of countless infinitely small points. But in the computer, there is no this infinitesimal processing method, the triangle on the screen is composed of many point pixels, the process of using discrete pixels to represent a continuous image is rasterization.
During rasterization, the triangles need to be shaded. shading Specifies how vertex colors are used to calculate the color of the constituent pixels. There are two shading modes in Direct3D:
The first: Planar shading: the pixels of each element are uniformly assigned the color of the first vertex of the entity.
The second kind: Gouraud coloring: The color values of each pixel of a soil element are linearly interpolated by the color of the vertex.
So then we'll use these two shading modes to draw two triangles:
Action to complete:
1. Define the vertex structure:
struct Vertex//vertex structure {Vertex () {}vertex (float x, float y, float z, d3dcolor color) {_x = x; _y = y; _z = Z;_color = color;} Float _x, _y, _z;d3dcolor _color;static const DWORD fvf;};/ /Vertex format: Description The vertex structure corresponding to the vertex format contains the positional and diffuse color properties///To note that the specified order of the flexible vertex format tags must be consistent with the order of the corresponding type data in the vertex structure. Const DWORD VERTEX::FVF = D3DFVF_XYZ | D3dfvf_diffuse;
2. Create a vertex cache to write data such as vertex colors:
Create a vertex cache Device->createvertexbuffer (3 * sizeof (VERTEX), d3dusage_writeonly, VERTEX::FVF, d3dpool_managed, & Triangle, 0);//access vertex cache, write cube vertex data to vertex* vertices; Triangle->lock (0, 0, (void**) &vertices, 0); Vertices[0] = Vertex ( -1.0f, 0.0f, 2.0f, D3dcolor_xrgb (255, 0, 0)); VERTICES[1] = Vertex (0.0f, 1.0f, 2.0f, D3dcolor_xrgb (0, 255, 0)); vertices[2] = Vertex (1.0f, 0.0f, 2.0f, D3dcolor_xrgb (0, 0 , 255)); Triangle->unlock ();
3. Projection Transformation:
When the camera is positioned and facing arbitrarily, it is cumbersome to perform some operations that are inefficient. To simplify the operation, we transform the camera to the origin of the world coordinate system and rotate the camera so that its optical axis is aligned with the z axis of the world coordinate system. It is important to note that all objects in the world will be transformed with the camera to ensure that the camera's field of view is constant.
Let's start with d3dxmatrixlookatlh(...). function to get a framing transformation matrix, and then use::settransform(..) Method settings:
Projection transform d3dxmatrix proj;d3dxmatrixperspectivefovlh (&proj, D3dx_pi * 0.5f, (float) Width/(float) Height, 1.0f, 1000.0f);D evice->settransform (d3dts_projection, &proj);
4. Set the drawing status:
Device->setrenderstate (d3drs_lighting, true); By default, lighting is enabled, which is disabled here because we are not using it.
But the display designation is not a major hindrance.
Sets the drawing state Device->setrenderstate (d3drs_lighting, false);
5. Display:
In drawing, we are going to draw two triangles, then the position information of the set triangle is controlled by world transformation Matrix Worlds:
Draw device->clear (0, 0, d3dclear_target | D3dclear_zbuffer, 0xFFFFFFFF, 1.0f, 0);//Screen clear, set to black background device->beginscene ();D EVICE->SETFVF (VERTEX::FVF); Set flexible vertex format//use SetStreamSource to set the source of the vertex input stream, link the vertex cache to the data stream//essence is to transfer the geometry information to the drawing line Device->setstreamsource (0, Triangle , 0, sizeof (VERTEX));//Use the flat shading mode to draw the left triangle//Set position d3dxmatrixtranslation (&worldmatrix, -1.25f, 0.0f, 0.0f);D evice- >settransform (D3dts_world, &worldmatrix);//Draw Device->setrenderstate (D3drs_shademode, D3DSHADE_FLAT);D Evice->drawprimitive (d3dpt_trianglelist, 0, 1);//Use Grouaud mode to draw the right triangle d3dxmatrixtranslation (&worldmatrix, 1.25f, 0.0f, 0.0f);D evice->settransform (D3dts_world, &worldmatrix);//Draw Device->setrenderstate (D3drs_ Shademode, D3dshade_gouraud);D evice->drawprimitive (d3dpt_trianglelist, 0, 1);D evice->endscene ();D evice-> Present (0, 0, 0, 0);
Full code: (Can run)
#include <d3d9.h> #include <d3dx9math.h> #include <windows.h> idirect3ddevice9* Device = 0; A C + + object that represents the physical hardware device we use to display 3D graphics idirect3dvertexbuffer9* Triangle = 0;//vertex cache d3dxmatrix Worldmatrix;const int Width = 640 ; The width of the window is const int Height = 480; Height//-----------------------------vertex struct----------------------------------struct Vertex//Vertex structure {Vertex () {}vertex ( float x, float y, float z, d3dcolor color) {_x = x; _y = y; _z = Z;_color = color;} Float _x, _y, _z;d3dcolor _color;static const DWORD fvf;};/ /Vertex format: Description The vertex structure corresponding to the vertex format contains the positional and diffuse color properties///To note that the specified order of the flexible vertex format tags must be consistent with the order of the corresponding type data in the vertex structure. Const DWORD VERTEX::FVF = D3DFVF_XYZ | d3dfvf_diffuse;//------------------------------The following is a window procedure---------------------------------LRESULT CALLBACK WndProc ( HWND hwnd, UINT MSG, WPARAM WPARAM, LPARAM LPARAM)//Window procedure {switch (msg) {case wm_destroy://destroy PostQuitMessage (0);//Termination request break;} Invokes the default window procedure to provide default processing for any window message that the application does not process. This function ensures that every message gets processed return::D Efwindowproc (hwnd, MSG, WParam, LParam);}----------------------------The following is the initialization window information---------------------------------bool Initwindow (HINSTANCE hinstance, HWND &hwnd, int width, int height) {//define window style wndclass Wc;wc.style = Cs_hredraw | Cs_vredraw;wc.lpfnwndproc = Wndproc;wc.cbclsextra = 0;wc.cbwndextra = 0;wc.hinstance = HInstance;wc.hIcon = LoadIcon (0, I di_application); wc.hcursor = loadcursor (0, idc_arrow); wc.hbrbackground = (Hbrush) getstockobject (WHITE_BRUSH); Wc.lpszmenuname = 0;wc.lpszclassname = "LSZDX";//Window Registration RegisterClass (&WC);//Create Window hwnd =:: CreateWindow ("Lszdx", "Lsz DX ", Ws_overlappedwindow, 0, 0, width, height, 0, 0, hinstance, 0);//Draw Update window ShowWindow (hwnd, sw_show); UpdateWindow (HWND); return true;} ----------------------------The following is the initialization of the Direct3D----------------------------------------//Note that the HWND of the function is a reference to bool Initd3d (HInstance &hinstance, HWND &hwnd, int width, int height, bool windowed, D3ddevtype DeviceType, idirect3ddevice9** Device) {//Get idirect3d9 pointer idirect3d9* d3d9 = 0;D3D9 = Direct3dcreate9 (d3d_sdk_version);//Verify hardware vertex operations D3dcaps9 caps;d3d9->getdevicecaps (D3dadapter_default, DeviceType, &caps), int vp = 0;IF ( Caps. Devcaps & d3ddevcaps_hwtransformandlight) VP = D3DCREATE_HARDWARE_VERTEXPROCESSING;ELSEVP = D3DCREATE_SOFTWARE_ vertexprocessing;//fills the d3dpresent_parameters structure d3dpresent_parameters D3DPP;D3DPP. Backbufferwidth = WIDTH;D3DPP. Backbufferheight = HEIGHT;D3DPP. Backbufferformat = D3DFMT_A8R8G8B8;D3DPP. BackBufferCount = 1;D3DPP. MultiSampleType = D3DMULTISAMPLE_NONE;D3DPP. Multisamplequality = 0;D3DPP. SwapEffect = D3dswapeffect_discard;d3dpp.hdevicewindow = HWND;D3DPP. windowed = WINDOWED;D3DPP. EnableAutoDepthStencil = TRUE;D3DPP. Autodepthstencilformat = D3DFMT_D24S8;D3DPP. Flags = 0;D3DPP. FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;D3DPP. Presentationinterval = d3dpresent_interval_immediate;//Create IDirect3DDevice9 interface D3d9->createdevice (D3DADAPTER_ DEFAULT, DeviceType, hwnd, VP, &D3DPP, Device);d 3d9->release (); return true;} Projection transform//Set drawing state bool Inittr () {//create vertexCache Device->createvertexbuffer (3 * sizeof (VERTEX), d3dusage_writeonly, VERTEX::FVF, d3dpool_managed, &triangle, 0);//access vertex cache, write cube vertex data to vertex* vertices; Triangle->lock (0, 0, (void**) &vertices, 0); Vertices[0] = Vertex ( -1.0f, 0.0f, 2.0f, D3dcolor_xrgb (255, 0, 0)); VERTICES[1] = Vertex (0.0f, 1.0f, 2.0f, D3dcolor_xrgb (0, 255, 0)); vertices[2] = Vertex (1.0f, 0.0f, 2.0f, D3dcolor_xrgb (0, 0 , 255)); Triangle->unlock ();//Projection transform D3dxmatrix proj;d3dxmatrixperspectivefovlh (&proj, D3dx_pi * 0.5f, (float) Width/( float) Height, 1.0f, 1000.0f);D evice->settransform (d3dts_projection, &proj);//Set drawing state device-> SetRenderState (d3drs_lighting, False); return true;} -----------------------the following to draw the cube-------------------------------------bool Display () {msg msg; ZeroMemory (&msg, sizeof (msg)), and//filling messages with zeros can be likened to: memset () function while (msg.message! = wm_quit)//exit {//peekmessage function is to view the party Gets the message from the system//and places the message (if it exists) in the specified structure if (PeekMessage (&msg, 0, 0, 0, pm_remove)) {//pm_remove:peekmessWhen age is processed, the message is removed from the queue. The TranslateMessage function converts a virtual key message to a character message. The character message is sent to the calling thread's message queue, or the next time the thread calls the function GetMessage or peekmessage. TranslateMessage can only be used to convert messages that are received by a getmessage or PeekMessage call. TranslateMessage (&msg);//dispatchmessage function//The function distributes a message to the window program. Usually the message is obtained from the GetMessage function. The message is distributed to the callback function (the procedure function), the function is to pass the message to the operating system,//and then the operating system calls our callback function, which means we process the message DispatchMessage (&msg) in the form's procedure function;} Else{if (Device) {//Draw device->clear (0, 0, d3dclear_target | D3dclear_zbuffer, 0xFFFFFFFF, 1.0f, 0);//Screen clear, set to white background device->beginscene ();D EVICE->SETFVF (VERTEX::FVF); Set flexible vertex format//use SetStreamSource to set the source of the vertex input stream, link the vertex cache to the data stream//essence is to transfer the geometry information to the drawing line Device->setstreamsource (0, Triangle , 0, sizeof (VERTEX));//Use the flat shading mode to draw the left triangle//Set position d3dxmatrixtranslation (&worldmatrix, -1.25f, 0.0f, 0.0f);D evice- >settransform (D3dts_world, &worldmatrix);//Draw Device->setrenderstate (D3drs_shademode, D3DSHADE_FLAT);D Evice->drawprimitive (d3dpt_trianglelist, 0, 1);//Use Grouaud mode to draw the right triangle D3DXMatrixTranslation (&worldmatrix, 1.25f, 0.0f, 0.0f);D evice->settransform (D3dts_world, &worldmatrix);//Draw Device->setrenderstate (D3drs_ Shademode, D3dshade_gouraud);D evice->drawprimitive (d3dpt_trianglelist, 0, 1);D evice->endscene ();D evice-> Present (0, 0, 0, 0);}}} return true;} -------------------------main function-----------------------------------------------int WINAPI WinMain (hinstance HINSTANCE, HInstance previnstance, PSTR cmdline, int showcmd) {hwnd hwnd = 0;//1. Window creation Initwindow (HINSTANCE, HWND, Width, H Eight)//2. Initialize Direct3D Initd3d (HINSTANCE, hwnd, Width, Height, True, D3ddevtype_hal, &device),//3. Initialize cube information inittr ();//4. Rendering display ();//5. Release pointer Device->release (); return 0;}
Operating effect:
DirectX Learning Note (v): Draw a color-based triangle with flat shading and Gouraud shading modes