0001: // ----------------------------------------------------------------------------
0002: //
0003: // draw.cpp - 背景
0004: // 
0005: // Copyright (c) 2001 if (if@edokko.com)
0006: // All Rights Reserved.
0007: //
0008: // ----------------------------------------------------------------------------
0009: #define STRICT
0010: 
0011: 
0012: #include "main.h"
0013: #include "load.h"
0014: 
0015: // 空
0016: #define NUM_Y       1   // 縦方向に何ポリゴン使うか
0017: #define NUM_CIRCLE  32  // 一回り何ポリゴンか
0018: #define NUM_VERTICES            ((NUM_Y+1)*(NUM_CIRCLE+1))
0019: #define NUM_INDICES_PERFACE     (3*2)
0020: #define NUM_FACES               (NUM_Y*NUM_CIRCLE)
0021: #define NUM_VERTICES_PERFACE    4
0022: 
0023: // 床
0024: #define FLOOR_SIZE  (10.0f)
0025: #define FLOOR_UV    (30.0f)     // テクスチャーの繰り返し回数
0026: 
0027: // ----------------------------------------------------------------------------
0028: typedef struct{
0029:     float x,y,z;
0030:     float tu0,tv0;
0031: } CylinderVertex;
0032: #define CYLINDER_VERTEX (D3DFVF_XYZ | D3DFVF_TEX1)
0033: 
0034: typedef struct {
0035:     float  x,  y,  z;
0036:     float tu, tv;
0037:     float xx, xy, xz;
0038:     float sx, sy, sz;
0039:     float tx, ty, tz;
0040: }FloorVertex;
0041: 
0042: static DWORD dwDeclFloor[] = {
0043:     D3DVSD_STREAM(0),
0044:     D3DVSD_REG(D3DVSDE_POSITION,    D3DVSDT_FLOAT3 ),           // D3DVSDE_POSITION,  0
0045:     D3DVSD_REG(D3DVSDE_TEXCOORD0,   D3DVSDT_FLOAT2 ),           // D3DVSDE_TEXCOORD0, 7  
0046:     D3DVSD_REG(3,                   D3DVSDT_FLOAT3 ),           // SxT  
0047:     D3DVSD_REG(4,                   D3DVSDT_FLOAT3 ),           // S
0048:     D3DVSD_REG(5,                   D3DVSDT_FLOAT3 ),           // T  
0049:     D3DVSD_END()
0050: };
0051: 
0052: 
0053: // ----------------------------------------------------------------------------
0054: // 空
0055: LPDIRECT3DVERTEXBUFFER8     pCylinderVB;
0056: LPDIRECT3DINDEXBUFFER8      pCylinderIB;
0057: LPDIRECT3DTEXTURE8          pCylinderTex;
0058: // 床
0059: LPDIRECT3DVERTEXBUFFER8     pFloorVB;
0060: LPDIRECT3DINDEXBUFFER8      pFloorIB;
0061: LPDIRECT3DTEXTURE8          pFloorTex;
0062: LPDIRECT3DTEXTURE8          pNormalTex;
0063: DWORD                       hVertexShader=~0;
0064: DWORD                       hDiffuseShader=~0;
0065: BOOL                        gBgBump = true;
0066: // ----------------------------------------------------------------------------
0067: void InitBg(LPDIRECT3DDEVICE8 lpD3DDev)
0068: {
0069:     //
0070:     // 円柱
0071:     //
0072:     // 頂点バッファの作成 
0073:     CylinderVertex *pDest;
0074:     lpD3DDev->CreateVertexBuffer( NUM_VERTICES * sizeof(CylinderVertex),
0075:                                 D3DUSAGE_WRITEONLY, 
0076:                                 CYLINDER_VERTEX, D3DPOOL_MANAGED,
0077:                                 &pCylinderVB );
0078: 
0079:     // 頂点をセットアップ
0080:     WORD k=0;
0081:     pCylinderVB->Lock ( 0, 0, (BYTE**)&pDest, 0 );
0082:     float r = 10.0f;
0083:     float h = 10.0f;
0084:     for (DWORD i = 0; i <= NUM_CIRCLE; i++) {
0085:         float theta = (2*PI*(float)i)/(float)NUM_CIRCLE;
0086:         for (DWORD j = 0; j <= NUM_Y; j++) {
0087:             pDest->x = r * (float)cos(theta);
0088:             pDest->z = r * (float)sin(theta);
0089:             pDest->y = h*((float)j/(float)NUM_Y-0.0f);
0090:             pDest->tu0 = (float)i / (float)NUM_CIRCLE;
0091:             pDest->tv0 = 1.0f-(float)j / (float)NUM_Y;
0092:             pDest += 1;
0093:         }
0094:     }       
0095:     pCylinderVB->Unlock ();
0096: 
0097: 
0098:     // インデックスをセットアップ
0099:     WORD *pIndex;
0100:     lpD3DDev->CreateIndexBuffer( NUM_INDICES_PERFACE  * NUM_FACES * sizeof(WORD),
0101:                                      0 ,
0102:                                      D3DFMT_INDEX16, D3DPOOL_DEFAULT,
0103:                                      &pCylinderIB );
0104:     pCylinderIB->Lock ( 0, 0, (BYTE**)&pIndex, 0 );
0105:     {
0106:     for (WORD i = 0; i < NUM_CIRCLE; i++) {
0107:         for (WORD j = 0; j < NUM_Y; j++) {
0108:             *pIndex++ = j + 0 + (i+0) * (NUM_Y+1);
0109:             *pIndex++ = j + 0 + (i+1) * (NUM_Y+1);
0110:             *pIndex++ = j + 1 + (i+0) * (NUM_Y+1);
0111: 
0112:             *pIndex++ = j + 1 + (i+0) * (NUM_Y+1);
0113:             *pIndex++ = j + 0 + (i+1) * (NUM_Y+1);
0114:             *pIndex++ = j + 1 + (i+1) * (NUM_Y+1);
0115:         }
0116:     }
0117:     }
0118:     pCylinderIB->Unlock ();
0119: 
0120:     CTextureMgr::Load(lpD3DDev, "sky.bmp", &pCylinderTex);
0121:     
0122:     //
0123:     // 床
0124:     //
0125:     // 頂点バッファの作成 
0126:     FloorVertex *pFloorDest;
0127:     lpD3DDev->CreateVertexBuffer( 4 * sizeof(FloorVertex),
0128:                                 D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED,
0129:                                 &pFloorVB );
0130:     // 頂点をセットアップ
0131:     {
0132:     pFloorVB->Lock ( 0, 0, (BYTE**)&pFloorDest, 0 );
0133:     for (DWORD i = 0; i < 4; i++) {
0134:         pFloorDest->x   = (i == 0 || i == 1)?(-FLOOR_SIZE):(+FLOOR_SIZE);
0135:         pFloorDest->z   = (i == 0 || i == 2)?(-FLOOR_SIZE):(+FLOOR_SIZE);
0136:         pFloorDest->y   = 0.0f;
0137:         pFloorDest->tu = (i == 0 || i == 1)?0:FLOOR_UV;
0138:         pFloorDest->tv = (i == 0 || i == 2)?0:FLOOR_UV;
0139:         pFloorDest->sx = 1.0f;pFloorDest->sy = 0.0f;pFloorDest->sz = 0.0f;
0140:         pFloorDest->tx = 0.0f;pFloorDest->ty = 0.0f;pFloorDest->tz = 1.0f;
0141:         pFloorDest->xx = 0.0f;pFloorDest->xy = 1.0f;pFloorDest->xz = 0.0f;
0142:         pFloorDest += 1;
0143:     }       
0144:     pFloorVB->Unlock ();
0145:     }
0146: 
0147: 
0148:     // インデックスをセットアップ
0149:     lpD3DDev->CreateIndexBuffer( 6 * sizeof(WORD),
0150:                                0,
0151:                                D3DFMT_INDEX16, D3DPOOL_MANAGED,
0152:                                &pFloorIB );
0153:     pFloorIB->Lock ( 0, 0, (BYTE**)&pIndex, 0 );
0154:     pIndex[0] = 0;  pIndex[1] = 1;  pIndex[2] = 2;
0155:     pIndex[3] = 1;  pIndex[4] = 3;  pIndex[5] = 2;
0156:     pFloorIB->Unlock ();
0157: 
0158:     CTextureMgr::Load(lpD3DDev, "tile.bmp", &pFloorTex);
0159:     CTextureMgr::Load(lpD3DDev, "normal.bmp", &pNormalTex);
0160:     CVertexShaderMgr::Load(lpD3DDev, "bg.vsh", &hVertexShader, dwDeclFloor);
0161:     CVertexShaderMgr::Load(lpD3DDev, "diffuse.vsh", &hDiffuseShader, dwDeclFloor);
0162: }
0163: // ----------------------------------------------------------------------------
0164: void DrawBg(LPDIRECT3DDEVICE8 lpD3DDev, D3DXMATRIX mWorld, D3DXMATRIX mView, D3DXMATRIX mProj)
0165: {
0166:     // 空
0167:     lpD3DDev->SetTransform( D3DTS_WORLD, &mWorld );
0168:     lpD3DDev->SetTransform( D3DTS_VIEW, &mView );
0169:     lpD3DDev->SetTransform( D3DTS_PROJECTION, &mProj );
0170:     lpD3DDev->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_MODULATE);
0171:     lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0172:     lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG2,  D3DTA_DIFFUSE);
0173:     lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSU,   D3DTADDRESS_WRAP);
0174:     lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSV,   D3DTADDRESS_CLAMP);
0175:     lpD3DDev->SetRenderState( D3DRS_WRAP0, D3DWRAP_U);
0176:     lpD3DDev->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0177:     lpD3DDev->SetVertexShader(CYLINDER_VERTEX);
0178:     lpD3DDev->SetTexture(0,pCylinderTex);
0179:     lpD3DDev->SetStreamSource(0, pCylinderVB, sizeof(CylinderVertex));
0180:     lpD3DDev->SetIndices(pCylinderIB,0);
0181:     lpD3DDev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, NUM_VERTICES, 0 , NUM_FACES*2 );
0182:     
0183:     // 床
0184:     D3DXMATRIX m = mWorld * mView * mProj;
0185:     D3DXMatrixTranspose( &m ,  &m);
0186:     lpD3DDev->SetVertexShaderConstant(0,&m, 4);
0187:     D3DXMatrixTranspose( &m ,  &mWorld);
0188:     lpD3DDev->SetVertexShaderConstant(4, &m, 4);
0189:     extern D3DXVECTOR4 lpos;
0190:     D3DXVECTOR4 lightDir;
0191:     D3DXMatrixInverse( &m,  NULL, &mWorld);
0192:     D3DXVec4Transform(&lightDir, &lpos, &m);
0193:     D3DXVec4Normalize(&lightDir, &lightDir);
0194:     lpD3DDev->SetVertexShaderConstant(13, &lightDir, 1);
0195:     
0196:     if(gBgBump){
0197:         lpD3DDev->SetTexture(0,pNormalTex);
0198:         lpD3DDev->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_DOTPRODUCT3);
0199:         lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0200:         lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG2,  D3DTA_DIFFUSE);
0201:         lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSU,   D3DTADDRESS_WRAP);
0202:         lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSV,   D3DTADDRESS_WRAP);
0203:         lpD3DDev->SetRenderState( D3DRS_WRAP0, D3DWRAP_U | D3DWRAP_V);
0204:         lpD3DDev->SetTexture(1,pFloorTex);
0205:         lpD3DDev->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_MODULATE);
0206:         lpD3DDev->SetTextureStageState(1,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0207:         lpD3DDev->SetTextureStageState(1,D3DTSS_COLORARG2,  D3DTA_CURRENT);
0208:         lpD3DDev->SetTextureStageState(1,D3DTSS_ADDRESSU,   D3DTADDRESS_WRAP);
0209:         lpD3DDev->SetTextureStageState(1,D3DTSS_ADDRESSV,   D3DTADDRESS_WRAP);
0210:         lpD3DDev->SetRenderState( D3DRS_WRAP1, D3DWRAP_U | D3DWRAP_V);
0211: 
0212:         lpD3DDev->SetVertexShader(hVertexShader);
0213:     }else{
0214:         lpD3DDev->SetTexture(0,pFloorTex);
0215:         lpD3DDev->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_MODULATE);
0216:         lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0217:         lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG2,  D3DTA_DIFFUSE);
0218:         lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSU,   D3DTADDRESS_WRAP);
0219:         lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSV,   D3DTADDRESS_WRAP);
0220:         lpD3DDev->SetRenderState( D3DRS_WRAP0, D3DWRAP_U | D3DWRAP_V);
0221:         lpD3DDev->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0222:         
0223:         lpD3DDev->SetVertexShaderConstant(15, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 0.0f), 1);// 下半球の色
0224: 
0225:         lpD3DDev->SetVertexShader(hDiffuseShader);
0226:     }
0227:     lpD3DDev->SetStreamSource(0, pFloorVB, sizeof(FloorVertex));
0228:     lpD3DDev->SetIndices(pFloorIB,0);
0229:     lpD3DDev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 4, 0, 2 );
0230: }
0231: // ----------------------------------------------------------------------------
0232: void CleanBg(LPDIRECT3DDEVICE8 lpD3DDev)
0233: {
0234:     CVertexShaderMgr::Release(lpD3DDev, &hVertexShader);
0235:     CVertexShaderMgr::Release(lpD3DDev, &hDiffuseShader);
0236:     CTextureMgr::Release(pNormalTex);
0237:     CTextureMgr::Release(pFloorTex);
0238:     CTextureMgr::Release(pCylinderTex);
0239: }