Advanced 3D Game Programming with DirectX - phần 9 pot

71 400 0
Advanced 3D Game Programming with DirectX - phần 9 pot

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

569 D3DTA_SPECULAR—The argument value is the texture color. It is recommended that this argument be used only in stage 1. D3DTA_ALPHAREPLICATE—Additional flag, used in conjunction with one of the above. Causes the alpha component of the color to be copied to the other three color values. D3DTA_COMPLEMENT—Additional flag, used in conjunction with one of the above. Causes all components to be inverted, such that (x = 1.0 − x). (Default = D3DTOP_TEXTURE) ALPHAOP Defines the operation done to combine ALPHAARG1 and ALPHAARG2. One of the members of the D3DTEXTUREOP enumeration, discussed below. (Default = D3DTOP_DISABLE for all stages except stage 0, which is D3DTOP_MODULATE). ALPHAARG1, ALPHAARG2 Describes the source for the arguments in the texture alpha operation. The color argument can be any of the texture argument flags, which are supplied in the description of COLORARG1 and COLORARG2. (Default = D3DTOP_TEXTURE) BUMPENVMAT00, BUMPENVMAT01, BUMPENVMAT10, BUMPENVMAT11 Coefficients for the bump-mapping matrix. The valid range for these values is [–8,8]. This is the mathematical way of saying that the number must be equal or greater than –8 and less than (but not equal to) 8. (Default = 0) TEXCOORDINDEX An integer describing which set of texture coordinates to use for a particular stage (a vertex can be defined with up to eight vertices). You'll remember that back in Chapter 8 I described some vertex formats that had multiple sets of texture coordinates; this is where you can use them. If a requested index doesn't occur in the vertex, the behavior is to default to the texture coordinate (0,0). The value can also be one of the following additional flags: D3DTSS_TCI_PASSTHRU—Texture coordinates should be taken from the input index into the array of texture coordinates. This flag resolves to zero. 570 D3DTSS_TCI_CAMERASPACENORMAL—The texture coordinates for this stage are the normal for the vertex, transformed into camera space. This is mostly useful when texture transforms are enabled. D3DTSS_TCI_CAMERASPACEPOSITION—The texture coordinates for this stage are the position for the vertex, transformed into camera space. This is mostly useful when texture transforms are enabled. D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR—The texture coordinates for this stage are the reflection vector for the vertex, transformed into camera space. This is mostly useful when texture transforms are enabled. The reflection vector is a ray that is sent from the eye point and bounced off the vertex. (Default (for all stages) = 0) BUMPENVLSCALE, BUMPENVLOFFSET Bump mapping texture stage states. TEXTURE TRANSFORMFLAGS Stage flags for texture transformations, discussed later in the chapter. D3DTTFF_DISABLE—Disables texture transforms for the current stage. D3DTTFF_COUNT1—Instructs the rasterizer to expect one-dimensional texture coordinates. This is in place because it can be the case where an application takes 3D coordinates, like the camera space position, and applies a texture transformation matrix that only cares about one of the entries. D3DTTFF_COUNT2—Instructs the rasterizer to expect two-dimensional texture coordinates. This is in place because it is possible that an application could take 3D coordinates, like the camera space position, and apply a texture transformation matrix that only cares about two of the entries. D3DTTFF_COUNT3—Instructs the rasterizer to expect three- dimensional texture coordinates. D3DTTFF_COUNT4—Instructs the rasterizer to expect four-dimensional texture coordinates. D3DTTFF_PROJECTED—All of the texture coordinates, save the last, are divided by the last element, and the last element is thrown away. For example, if we supply the flags (D3DTTFF_COUNT3|D3DTTFF_PROJECTED), the first two texture coordinates are divided by the third, the third is thrown away, and the result is passed to the rasterizer. 571 (Default = D3DTTFF_DISABLE) One of the most often changed texture stage states is to change the color/alpha operation performed at each stage. The set of color/alpha operations sits inside the D3DTEXTUREOP enumeration, which is presented in Table 10.3 : Table 10.3: Members of the D3DTEXTUREOP enumeration (D3DTOP_ prefix omitted) DISABLE Disables a stage. Once Direct3D encounters a disabled stage, the stage cascade stops and the current result is passed to the next phase of the pipeline. SELECTARG1 Result of the stage's texture operation is the color of the first argument. Res=Arg1 SELECTARG2 Result of the stage's texture operation is the color of the second argument. Res=Arg2 MODULATE Result of the stage's texture operation is the result of the multiplication of the arguments. Res=Arg1 Arg2 MODULATE2X Result of the stage's texture operation is the result of the multiplication of the arguments, multiplied by 2. Res=2 (Arg1 Arg2) MODULATE4X Result of the stage's texture operation is the result of the multiplication of the arguments, multiplied by 4. Res=4 (Arg1 Arg2) 572 ADD Result of the stage's texture operation is the result of the addition of the arguments. Res=Arg1+Arg2 ADDSIGNED Result of the stage's texture operation is the result of the addition of the arguments biased by −0.5. This makes the range of one of the operations effectively a signed number [ −0.5, 0.5]. Res=Arg1+Arg2 −0.5 ADDSIGNED2X Result of the stage's texture operation is the result of the addition of the arguments biased by −0.5 and multiplied by 2. The bias makes the range of one of the operations effectively a signed number [ −0.5, 0.5]. Res=2 (Arg1+Arg2–0.5) SUBTRACT Result of the stage's texture operation is the result of the subtraction of the second argument from the first. Res=Arg1–Arg2 ADDSMOOTH Result of the stage's texture operation is the result of the addition of the arguments subtracted by the product of the arguments. Res=Arg1–Arg2 −Arg1 Arg2=Arg1+Arg2(1–Arg1) BLENDDIFFUSEALPHA, BLENDTEXTUREALPHA, Result of the stage's texture operation is the result of the linear blending of both color operations with 573 BLENDFACTORALPHA, BLENDTEXTUREALPHAPM, BLENDCURRENTALPHA the iterated diffuse alpha, the current iterated texture alpha, a scalar alpha factor (set with the D3DRS_TFACTOR render state), or the alpha that resulted from the previous stage. Res=Arg1 alpha+Arg2 (1–alpha) PREMODULATE For use with premodulated textures. MODULATEALPHA_ADDCOLOR Result of the stage's texture operation is the addition of the second color modulated with the first color's alpha component to the first color. This operation is only valid for color operations (not alpha operations). Res RGB =Arg1 RGB +Arg1A Arg2 RGB MODULATECOLOR_ADDALPHA Result of the stage's texture operation is the addition of the first argument's alpha component to the modulated first and second colors. This operation is only valid for color operations (not alpha operations). Res RGB =Arg1 RGB Arg2 RGB +Arg1 A MODULATEINVALPHA_ADDCOLOR Result of the stage's texture operation is the addition of the second color modulated with the inverse of the first color's alpha component to the first color. This operation is only valid for color operations (not alpha operations). Res RGB =Arg1 RGB +(1–Arg1 A ) Arg2 RGB MODULATEINVCOLOR_ADDALPHA Result of the stage's texture operation is the addition of the first argument's alpha component to the modulation of the second color and the inverse of the first color. This operation is only valid for color operations (not alpha operations). Res RGB =(1–Arg1 RGB ) Arg2 RGB +Arg1 A 574 BUMPENVMAP Performs per-pixel bump mapping, using the next stage as an environment map. This operation is only valid for color operations (not alpha operations). BUMPENVMAPLUMINANCE Performs per-pixel bump mapping, using the next stage as an environment map. The next stage must be a luminance map. This operation is only valid for color operations (not alpha operations). DOTPRODUCT3 Performs a dot product with the two arguments, replicating the result to all four color components. Res RGBA =Arg1 R Arg2 R + Arg1 G Arg2 G + Arg1 B Arg2 B Texture Transforms DirectX 9.0 has a feature for texture mapping called texture transforms. They allow an application to specify modifiers, such as projection or matrices that get applied to texture coordinates before being used. Each texture stage has a 4x4 texture transformation matrix associated with it. A lot of neat texture effects can be done automatically simply by fiddling with the matrix you set up. The texture coordinates that go into the matrix don't need to be four-dimensional; they can be two- or even one-dimensional. For example, let's say you want to perform a simple translation (suppose you had a texture that showed running water and you were displaying it on the clear section of a pipe). Instead of having to move the texture coordinates for the clear section of the pipe each frame, you can keep them stationary and use texture transformations. The end effect here is each frame you want to translate the coordinates horizontally to simulate movement over many frames. You would have a translation amount, which is called du. Just to be safe, whenever it is incremented past 1.0, it would be wrapped around back to 0.0 to prevent overflow. Strange things can happen if the magnitude of the texture coordinates are too large. Setting up the matrix to do this would yield: 575 Before the vertex texture coordinates are used to fetch texels from the image, the texture matrix first multiplies them for their stage. Of course, if the texture coordinate is only two-dimensional (u,v coordinates), it's padded with 1s to make the multiplication valid. To set the texture transform matrix for a particular stage, you call IDirect3DDevice9::SetTransform using the constants D3DTS_ TEXTURE0 (for the first stage) through D3DTS_TEXTURE7 (for the last stage) in the first state type parameter. To actually enable texture transforms, only one more step of work needs to be done. You set the texture stage state D3DTSS_TEXTURETRANSFORMFLAGS to inform it of how many of the resultant texture coordinates should be passed to the rasterizer. To disable the texture transformation, set this to D3DTTFF_DISABLE. For two-dimensional texture coordinates, set it to D3DTTFF_COUNT2. If you're doing something like projected textures, you would like to perform a perspective division on the texture coordinates we receive. To do this, set this to D3DTTFF_COUNT3|D3DTTFF_ PROJECTED. This instructs the texture transform engine to take the three texture coordinates resulting from the texture transform and divide the first two by the third. If you set up the matrix correctly this will perform your perspective divide. The cool thing is you can use things besides the specified texture coordinates with the texture transforms. You can change the D3DTSS_TEXCOORDINDEX texture stage state to use the view space position, view space normal, or view space reflection vector (all 3D values) as texture coordinates. I'll use this fact later to do spherical environment mapping. Effects Using Multiple Textures Most modern games now use multiple textures per primitive for a variety of effects. While there are many more possible kinds of effects than can be described here, I'm going to run through the most common ones and show how to implement them using both multiple textures per pass and multiple passes. The way you combine textures and the way you make the textures defines the kind of effect you end up with. Using multitexturing is preferred. Since you only draw the primitive once, it ends up being faster than multipass. Multipass involves drawing each of the separate phases of the effect one at a time. Generally you change the texture, change the alpha blending effects, and redraw the primitive. The new pass will be combined with the previous pass pixel-by-pixel. Figure 10.15 may help explain the kinds of things I'm trying to do. Using multitexture, you would set the first stage to texture A, the second stage to texture B, and then set the operation in texture B to either add, multiply, or subtract the pixels. Using multipass, you would draw texture A first, then change the alpha blending steps to add or multiply the pixels together (you can't subtract), and then draw the polygon again using texture B. 576 Figure 10.15: Combining textures Light Maps (a.k.a. Dark Maps) Light mapping is practically a standard feature for first-person shooters these days. It allows the diffuse color of a polygon to change non-linearly across the face of a polygon. This is used to create effects like colored lights and shadows. Using a light-map creation system (usually something like a radiosity calculator, which I created in Chapter 9 ), texture maps that contain just lighting information are calculated for all of the surfaces in the scene. Since usually the light map doesn't change per-pixel nearly as much as the texture map, a lower- resolution texture is used for the light map. Quake-style games use about 16 2 texels of light map for each texel of texture map. The base map is just the picture that would appear on the wall if everything were fully and evenly lit, like wallpaper. The light map is modulated with the base map. That way areas that get a lot of light (which appear white in the light map) appear as they would in the fully lit world (since the base map pixel times white(1) resolves to the base map). As the light map gets darker, the result appears darker. Since a light map can only darken the base map, not lighten it, sometimes the effect is referred to as "dark mapping." When you go to draw the polygon, you can do it in several ways. First I'll discuss the multitexture way. Using light maps with multitexture is done with two texture stages. The first texture stage can be either the base map or the light map, and the second is the other texture. You only need to worry about the color stages, too; the alpha stages aren't needed. Listing 10.4 shows sample code for setting this up. Listing 10.4: Sample code for setting up light mapping using multitexture //pDevice is a valid LPDIRECT3DDEVICE9 object 577 //pBase is the base texture //pLightMap is the light map pDevice->SetTextureStageState( 0, COLORARG1, D3DTA_TEXTURE ); pDevice->SetTextureStageState( 0, COLOROP, D3DTOP_SELECTARG1 ); pDevice->SetTexture( 0, pBase ); pDevice->SetTextureStageState( 1, COLORARG1, D3DTA_TEXTURE ); pDevice->SetTextureStageState( 1, COLORARG2, D3DTA_CURRENT ); pDevice->SetTextureStageState( 1, COLOROP, D3DTOP_MODULATE ); pDevice->SetTexture( 1, pLightMap ); // draw polygon Note that the texture is put into argument 1. Some cards depend on this being the case so you should make a habit of it. The effect using multipass rendering is similar to the above. You render the polygon twice, the first with no alpha blending and the base map, the second with the light map texture. The alpha blending done on the second stage should mimic the modulate color operation used in the multitexture rendering. Code to do it appears in Listing 10.5 . Listing 10.5: Sample code for setting up light mapping using multipass //pDevice is a valid LPDIRECT3DDEVICE9 object //pBase is the base texture //pLightMap is the light map pDevice->SetTextureStageState( 0, COLORARG1, D3DTA_TEXTURE ); pDevice->SetTextureStageState( 0, COLOROP, D3DTOP_SELECTARG1 ); pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE ); pDevice->SetTexture( 0, pBase ); 578 // draw polygon pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO ); pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR ); pDevice->SetTexture( 0, pLightMap ); // draw polygon The visual flair that you get from light mapping is amazing. Following is a prime example from Quake III: Arena. The first, Figure 10.16 , is rendered without light maps. The image looks bland and uninteresting. Figure 10.17 shows the same scene with light mapping enabled. The difference, I'm sure you'll agree, is amazing. Figure 10.16: Quake III: Arena, sans light maps [...]... LPDIRECT3DDEVICE9 object //pBase is the base texture 5 89 //pDetailMap is the detail map pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); // use the low-frequency texture coordinates pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); pDevice->SetTexture( 0, pBase ); pDevice->SetTextureStageState( 1, D3DTSS_COLORARG1,... LPDIRECT3DDEVICE9 object //pBase is the base texture //pDetailMap is the detail map pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); // use the low-frequency texture coordinates pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); pDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE ); pDevice->SetTexture(... modulated with diffuse color pDevice->SetTextureStageState( 0, COLORARG1, D3DTA_TEXTURE ); pDevice->SetTextureStageState( 0, COLOROP, D3DTOP_SELECTARG1 ); pDevice->SetTextureStageState( 1, COLORARG1, D3DTA_DIFFUSE ); pDevice->SetTextureStageState( 1, COLORARG2, D3DTA_CURRENT ); pDevice->SetTextureStageState( 1, COLOROP, D3DTOP_MODULATE ); pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE ); pDevice->SetTexture(... LPDIRECT3DDEVICE9 object //pBase is the base texture //pGlowMap is the glow map pDevice->SetTextureStageState( 0, COLORARG1, D3DTA_TEXTURE ); pDevice->SetTextureStageState( 0, COLOROP, D3DTOP_SELECTARG1 ); pDevice->SetTexture( 0, pBase ); pDevice->SetTextureStageState( 1, COLORARG1, D3DTA_TEXTURE ); pDevice->SetTextureStageState( 1, COLORARG2, D3DTA_CURRENT ); pDevice->SetTextureStageState( 1, COLOROP, D3DTOP_ADD... LPDIRECT3DDEVICE9 object // pBase is the base texture // pDetailMap is the glowmap pDevice->SetTextureStageState( 0, COLORARG1, D3DTA_TEXTURE ); pDevice->SetTextureStageState( 0, COLOROP, D3DTOP_SELECTARG1 ); pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE ); pDevice->SetTexture( 0, pBase ); // draw polygon pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); pDevice->SetRenderState( D3DRS_SRCBLEND,... pDevice->SetTexture( 0, pBase ); // draw polygon pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR ); pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR ); // use the high-frequency texture coordinates pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 1 ); 591 pDevice->SetTexture( 0, pDetailMap ); // draw polygon Application:... map modulated with gloss map // not included: code to set up spec-mapped texture coordinates pDevice->SetTextureStageState( 0, COLORARG1, D3DTA_TEXTURE ); pDevice->SetTextureStageState( 0, COLOROP, D3DTOP_SELECTARG1 ); pDevice->SetTextureStageState( 1, COLORARG1, D3DTA_TEXTURE ); pDevice->SetTextureStageState( 1, COLORARG2, D3DTA_CURRENT ); 597 pDevice->SetTextureStageState( 1, COLOROP, D3DTOP_MODULATE... pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR ); pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR ); /** * first stage is the detail map */ pDevice->SetTexture( 0, m_pTextures[2 ]-> GetTexture() ); 601 SetColorStage( 0, D3DTA_TEXTURE, D3DTA_CURRENT, D3DTOP_SELECTARG1 ); /** * The detail map needs the second pair of coordinates */ pDevice->SetTextureStageState(0,... color */ pDevice->SetTexture( 0, m_pTextures[0 ]-> GetTexture() ); SetColorStage( 0, D3DTA_TEXTURE, D3DTA_CURRENT, D3DTOP_MODULATE ); 599 /** * first pass doesn't use alpha blending */ pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE ); sMaterial mat( 0.f, color3(0.8f,0.8f,0.8f), color3(0.0f,0.0f,0.0f), color3(0.0f,0.0f,0.0f) ); pDevice->SetMaterial(&mat); pDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP,... pDevice->SetTexture( 0, pBase ); pDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); pDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_ADDSIGNED ); // use the high-frequency texture coordinates pDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 ); pDevice->SetTexture( 1, pDetailMap ); // draw polygon If the ADDSIGNED blending . D3DRS_ALPHABLENDENABLE, TRUE ); pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO ); pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR ); pDevice->SetTexture( 0, pLightMap. COLOROP, D3DTOP_SELECTARG1 ); pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE ); pDevice->SetTexture( 0, pBase ); 578 // draw polygon pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE,. COLOROP, D3DTOP_SELECTARG1 ); pDevice->SetTexture( 0, pBase ); pDevice->SetTextureStageState( 1, COLORARG1, D3DTA_TEXTURE ); pDevice->SetTextureStageState( 1, COLORARG2, D3DTA_CURRENT

Ngày đăng: 08/08/2014, 23:20

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan