4. Color
This article translated from "Introduction to 3D Game Programming WITH DIRECTX 9.0" Chapter 4 "Color", please ax.
This chapter discusses the color rendering of the object in the scene. Through this chapter, you can achieve the following objectives:
l How to describe the color in Direct3D
l How to understand how color is rendered
4.1. Color performance
In Direct3D, the color is represented by RGB, that is, the value of red, green, blue three original color is required, and the mixed color of these three components is the final color.
We use two structures to represent RGB data. The first is the D3DColor type, actually the DWORD type. This type is divided into four 8-bit parts, which are used to store the components of the color.
One byte is represented, so the brightness range of each color component is from 0 to 255. About the Alpha components in the figure, it is now possible to discuss it in detail when it is described in the Alpha mixed.
Each color component is used
Correctly fill in the individual components in the D3DColor structure requires a bit operation. To this end, D3D provides a macro D3DCOLOR_ARGB, and each component needs to be within 0 ~~ 255.
D3DCOLOR BRIGHTRED = D3DCOLOR_ARGB (255, 255, 0, 0); D3DCOLOR SomeColor = D3DCOLOR_ARGB (255, 144, 87, 201);
In addition, there is a macro D3DCOLOR_XRGB, which is similar to the above macro, but it is not necessary to provide an Alpha parameter value, but set it to 0xFF.
#define D3DColor_XRGB (R, G, B) D3DCOLOR_ARGB (0xFF, R, G, B)
Another structure that represents the color in Direct3D is D3DCOLORVALUE. This structure uses the floating point number to represent the value of each component of the color, ranging from 0.0 to 1.0.
Typedef strunt_d3dcolorvalue {float r; // the red company, Range 0.0-1.0 float g; // the green component, Range 0.0-1.0 float b; // the blue component, range 0.0-1.0 float a; // the alpha Component, Range 0.0-1.0} D3DCOLORVALUE;
Sometimes, use the D3DxColor structure, which contains the same data members as D3DColorValue, as well as a widely useful constructor and overloaded operators, which makes many color operations very convenient. Therefore, it is easy to convert between the two data structures. D3DXColor is defined as follows:
typedef struct D3DXCOLOR {#ifdef __cplusplus public: D3DXCOLOR () {} D3DXCOLOR (DWORD argb); D3DXCOLOR (CONST FLOAT *); D3DXCOLOR (CONST D3DXFLOAT16 *); D3DXCOLOR (CONST D3DCOLORVALUE &); D3DXCOLOR (FLOAT r, FLOAT g, FLOAT b , FLOAT a); // casting operator DWORD () const; operator FLOAT * (); operator cONST FLOAT * () const; operator D3DCOLORVALUE * (); operator cONST D3DCOLORVALUE * () const; operator D3DCOLORVALUE & (); operator cONST D3DCOLORVALUE & () const; // assignment operators D3DXCOLOR & operator = (cONST D3DXCOLOR &); D3DXCOLOR & operator - = (cONST D3DXCOLOR &); D3DXCOLOR & operator * = (FLOAT); D3DXCOLOR & operator / = (FLOAT); // unary operators D3DXCOLOR operator ( ) const; d3dxcolor operator - () const; // binary operator D3DXCOLOR OPERATOR Const; D3DXCOLOR OPERATOR - (Const D3dxColor &) Const; D3DxColor Operator * (Float) const; d3dxc OLOR operator / (FLOAT) const; friend D3DXCOLOR operator * (FLOAT, CONST D3DXCOLOR &); BOOL operator == (CONST D3DXCOLOR &) const; BOOL operator = (CONST D3DXCOLOR &) const;! #Endif // __ cplusplus FLOAT r, g, b , A;} D3DXCOLOR, * LPD3DXCOLOR; Color vector can be added, minus, multiplied by ordinary vectors. In addition, the point and the spending amount is not meaningful to color vectors, and the components are multiplied. The color of the D3DxColor defined is multiplied by the color component, and the symbol x is used:
(C1, C2, C3, C4) x (K1, K2, K3, K4) = (C1K1, C2K2, C3K3, C4K4)
4.2. Vertex color
The color of the geometry is determined by the color of the vertex constituting it. Therefore, we must add color members to the vertex data structure. Here, the color of the D3DCOLORVALUE structure is not used because Direct 3D wants to use the 32-bit integer representation of the color. In addition, when using a vertex shader, a four-dimensional vector is used to describe the vertex color, which is a 128-bit color. Details when discussing the vertex shader. Struct ColorvertEx {float _x, _y, _z; d3dcolor _color; static const dword fvf;} const dword colortex :: fvf = d3dfvf_xyz | D3DFVF_DIFFUSE;
4.3. Coloring mode
Coloring occurs when rasterization and through vertex colors. There are currently two coloring modes: flat mode and Gaulode model.
In flat mode, the color of the pixel will take the color of the first vertex constituting the geometry. So, the triangle composed of three vertices below is red, because the color of the first vertex is red, and the color of the two vertices will be ignored.
ColorvertEX T [3]; T [0] ._ color = D3DCOLOR_XRGB (255, 0, 0); T [1] ._ color = D3DCOLOR_XRGB (0, 255, 0); T [2] ._ color = D3DCOLOR_XRGB (0, 0 , 255);
The flat mode is often a geometry looks clear, and the color is lacking in a smoothing transition. Another more natural coloring mode is Gaulode mode, also called smooth mode, in which the color of the vertex renders the surface in a line-shaped interpolated manner.
You can use the following method to set the coloring mode in Direct3D:
// set flat shading device-> setRenderstate (D3DRS_SHADEMODE, D3DSHADE_FLAT); // set Gouraud Shading Device-> SetRenderstate (D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
4.4. Application example: Color triangle
This example is used to explain how to use flat modes and Gaulode mode rendering colored triangles. First, declare the following global variables:
D3DXMAMATRIX World; IDIRECT3DVERTEXBUFFER9 * TRIANGLE = 0;
Here, World is a triangular world coordinate system conversion matrix, Triangle is a vertex buffer pointer for storing triangular vertex data. Only one triangular vertex information is stored here, we will use the WORLD matrix to render the triangle multiple times in different locations in the coordinate system.
The function setup creates a vertex buffer and populates the vertex data of the triangle, and finally disables light. In the example, use the vertex structure of the above declaration ColorTex, the code is as follows:
bool Setup () {// create vertex buffer Device-> CreateVertexBuffer (3 * sizeof (ColorVertex), D3DUSAGE_WRITEONLY, ColorVertex :: FVF, D3DPOOL_MANAGED, & Triangle, 0); // fill the buffers with the triangle data ColorVertex * v; Triangle -> LOCK (0, 0, (void **) & v, 0); v [0] = Colorvertex (-1.0F, 0.0F, 2.0F, D3DCOLOR_XRGB (255, 0)); V [1] = Colorvertex (0.0F, 1.0F, 2.0F, D3DCOLOR_XRGB (0, 255, 0)); V [2] = Colorvertex (1.0F, 0.0F, 2.0F, D3DCOLOR_XRGB (0, 0, 255); triangle-> Unlock (); // set projection matrix D3DXMATRIX proj; D3DXMatrixPerspectiveFovLH (& proj, D3DX_PI * 0.5f, // 90 - degree (float) Width / (float) Height, 1.0f, 1000.0f); Device-> SetTransform (D3DTS_PROJECTION, & proj); // set the render stats Device-> Setrenderstate (D3DRS_Light, false); Return True;} DISPLAY uses different colorime modes to render this triangle twice in different locations, its location is controlled by the World matrix:
Bool Display (Float Timedelta) {if (device) {device-> Clear (0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xFFFFFFFF, 1.0F, 0); device-> beginscene (); device-> setfvf (colorvertex :: fvf) ; Device-> SetStreamSource (0, Triangle, 0, sizeof (ColorVertex)); // draw the triangle to the left with flat shading D3DXMatrixTranslation (& World, -1.25f, 0.0f, 0.0f); Device-> SetTransform (D3DTS_WORLD , & World); Device-> SetRenderState (D3DRS_SHADEMODE, D3DSHADE_FLAT); Device-> DrawPrimitive (D3DPT_TRIANGLELIST, 0, 1); // draw the triangle to the right with gouraud shading D3DXMatrixTranslation (& World, 1.25f, 0.0f, 0.0f) ; Device-> SetTransform (D3DTS_WORLD, & World); Device-> SetRenderState (D3DRS_SHADEMODE, D3DSHADE_GOURAUD); Device-> DrawPrimitive (D3DPT_TRIANGLELIST, 0, 1); Device-> EndScene (); Device-> Present (0, 0, 0 , 0);} Return True;} 4.5. Summary
l Color uses red, green, blue three original intensity description. D3DCOLOR, D3DCOLORVALUE, D3DXCOLOR structure are described in Direct3D.
l Sometimes the color is viewed as a quadruple vector (R, G, B, A). Color vector can be added, minus, enlarged like normal vector. In addition, the points and the spending between the color vectors have no sense, but the components are multiplied by the components.
l You can specify a color for the vertex, then Direct3D determines how to convert the colors of the vertex to pixels according to the current coloring mode.
l Flat coloring mode takes the color of the first vertex as the color of the geometric pixel; Gaulode mode calculates the color of the pixel through the line interpolation method.