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: #include "main.h"
0012: #include "d3dx8.h"
0013: #include "Cg/cgD3D.h"
0014: 
0015: extern cgProgramContainer *pVertexProgramContainer;
0016: extern cgProgramContainer  *pPixelProgramContainer;
0017: extern cgBindIter * vertex_mat_iter;
0018: extern cgBindIter * tex0_iter;
0019: 
0020: // 空
0021: #define NUM_Y       1   // 縦方向に何ポリゴン使うか
0022: #define NUM_CIRCLE  32  // 一回り何ポリゴンか
0023: #define NUM_VERTICES            ((NUM_Y+1)*(NUM_CIRCLE+1))
0024: #define NUM_INDICES_PERFACE     (3*2)
0025: #define NUM_FACES               (NUM_Y*NUM_CIRCLE)
0026: #define NUM_VERTICES_PERFACE    4
0027: 
0028: // 床
0029: #define FLOOR_SIZE  (10.0f)
0030: #define FLOOR_UV    (10.0f)     // テクスチャーの繰り返し回数
0031: 
0032: // ----------------------------------------------------------------------------
0033: typedef struct{
0034:     float x,y,z,w;
0035:     float tu,tv;
0036: } MyVertex;
0037: 
0038: // ----------------------------------------------------------------------------
0039: // 空
0040: LPDIRECT3DVERTEXBUFFER8     pCylinderVB;
0041: LPDIRECT3DINDEXBUFFER8      pCylinderIB;
0042: LPDIRECT3DTEXTURE8          pCylinderTex;
0043: // 床
0044: LPDIRECT3DVERTEXBUFFER8     pFloorVB;
0045: LPDIRECT3DINDEXBUFFER8      pFloorIB;
0046: LPDIRECT3DTEXTURE8          pFloorTex;
0047: 
0048: // 地球
0049: LPDIRECT3DVERTEXBUFFER8     pEarthVB;
0050: LPDIRECT3DINDEXBUFFER8      pEarthIB;
0051: LPDIRECT3DTEXTURE8          pEarthTex;
0052: #define EARTH_R             (1.0f)
0053: #define NUM_EARTH_X         32  // 縦に分割
0054: #define NUM_EARTH_Y         16  // 横に分割
0055: #define NUM_EARTH_VERTICES  ((NUM_EARTH_X+1)*(NUM_EARTH_Y+1))
0056: #define NUM_EARTH_POLYGONE  (2*NUM_EARTH_X*NUM_EARTH_Y)
0057: #define NUM_EARTH_INDEX     (6*NUM_EARTH_X*NUM_EARTH_Y)
0058: 
0059: static void InitEarth(LPDIRECT3DDEVICE8 lpD3DDev)
0060: {
0061:     WORD i, j;
0062:     
0063:     // 頂点バッファの作成 
0064:     MyVertex *pEarthDest;
0065:     lpD3DDev->CreateVertexBuffer( NUM_EARTH_VERTICES * sizeof(MyVertex),
0066:                                 0, 0, D3DPOOL_MANAGED,
0067:                                 &pEarthVB );
0068:     // 頂点をセットアップ
0069:     pEarthVB->Lock ( 0, 0, (BYTE**)&pEarthDest, 0 );
0070:     for ( j = 0; j <= NUM_EARTH_Y; j++) {
0071:     for ( i = 0; i <= NUM_EARTH_X; i++) {
0072:         float theta = ((float)i)*2*D3DX_PI/NUM_EARTH_X;
0073:         float phi   = ((float)j)*  D3DX_PI/NUM_EARTH_Y-D3DX_PI/2;
0074:         pEarthDest->x   = EARTH_R * (float)cos(phi) * (float)cos(theta);
0075:         pEarthDest->z   = EARTH_R * (float)cos(phi) * (float)sin(theta);
0076:         pEarthDest->y   = EARTH_R * (float)sin(phi);
0077:         pEarthDest->w   = 1.0f;
0078:         pEarthDest->tu = (float)i/NUM_EARTH_X;
0079:         pEarthDest->tv = 1.0f-(float)j/NUM_EARTH_Y;
0080:         pEarthDest++;
0081:     }
0082:     }
0083:     pEarthVB->Unlock ();
0084: 
0085: 
0086:     // インデックスをセットアップ
0087:     WORD *pIndex;
0088:     lpD3DDev->CreateIndexBuffer( NUM_EARTH_INDEX * sizeof(WORD),
0089:                                0,
0090:                                D3DFMT_INDEX16, D3DPOOL_MANAGED,
0091:                                &pEarthIB );
0092:     pEarthIB->Lock ( 0, 0, (BYTE**)&pIndex, 0 );
0093:     for ( j = 0; j < NUM_EARTH_Y; j++) {
0094:     for ( i = 0; i < NUM_EARTH_X; i++) {
0095:         *pIndex++ = (j+0)*(NUM_EARTH_X+1)+i+0;
0096:         *pIndex++ = (j+1)*(NUM_EARTH_X+1)+i+0;
0097:         *pIndex++ = (j+0)*(NUM_EARTH_X+1)+i+1;
0098:         *pIndex++ = (j+0)*(NUM_EARTH_X+1)+i+1;
0099:         *pIndex++ = (j+1)*(NUM_EARTH_X+1)+i+0;
0100:         *pIndex++ = (j+1)*(NUM_EARTH_X+1)+i+1;
0101:     }
0102:     }
0103:     pEarthIB->Unlock ();
0104: 
0105:     D3DXCreateTextureFromFileEx(lpD3DDev, "earth.bmp", 0,0,0,0,D3DFMT_A8R8G8B8,
0106:                                 D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,
0107:                                 0, NULL, NULL, &pEarthTex);
0108: 
0109: }
0110: 
0111: // ----------------------------------------------------------------------------
0112: void InitBg(LPDIRECT3DDEVICE8 lpD3DDev)
0113: {
0114:     //
0115:     // 円柱
0116:     //
0117:     // 頂点バッファの作成 
0118:     MyVertex *pDest;
0119:     lpD3DDev->CreateVertexBuffer( NUM_VERTICES * sizeof(MyVertex),
0120:                                 0, 0, D3DPOOL_MANAGED, &pCylinderVB );
0121: 
0122:     // 頂点をセットアップ
0123:     WORD k=0;
0124:     pCylinderVB->Lock ( 0, 0, (BYTE**)&pDest, 0 );
0125:     float r = 10.0f;
0126:     float h = 10.0f;
0127:     for (DWORD i = 0; i <= NUM_CIRCLE; i++) {
0128:         float theta = (2*PI*(float)i)/(float)NUM_CIRCLE;
0129:         for (DWORD j = 0; j <= NUM_Y; j++) {
0130:             pDest->x = r * (float)cos(theta);
0131:             pDest->z = r * (float)sin(theta);
0132:             pDest->y = h*((float)j/(float)NUM_Y-0.0f);
0133:             pDest->w   = 1.0f;
0134:             pDest->tu = (float)i / (float)NUM_CIRCLE;
0135:             pDest->tv = 1.0f-(float)j / (float)NUM_Y;
0136:             pDest += 1;
0137:         }
0138:     }       
0139:     pCylinderVB->Unlock ();
0140: 
0141: 
0142:     // インデックスをセットアップ
0143:     WORD *pIndex;
0144:     lpD3DDev->CreateIndexBuffer( NUM_INDICES_PERFACE  * NUM_FACES * sizeof(WORD),
0145:                                      0 ,
0146:                                      D3DFMT_INDEX16, D3DPOOL_DEFAULT,
0147:                                      &pCylinderIB );
0148:     pCylinderIB->Lock ( 0, 0, (BYTE**)&pIndex, 0 );
0149:     {
0150:     for (WORD i = 0; i < NUM_CIRCLE; i++) {
0151:         for (WORD j = 0; j < NUM_Y; j++) {
0152:             *pIndex++ = j + 0 + (i+0) * (NUM_Y+1);
0153:             *pIndex++ = j + 0 + (i+1) * (NUM_Y+1);
0154:             *pIndex++ = j + 1 + (i+0) * (NUM_Y+1);
0155: 
0156:             *pIndex++ = j + 1 + (i+0) * (NUM_Y+1);
0157:             *pIndex++ = j + 0 + (i+1) * (NUM_Y+1);
0158:             *pIndex++ = j + 1 + (i+1) * (NUM_Y+1);
0159:         }
0160:     }
0161:     }
0162:     pCylinderIB->Unlock ();
0163: 
0164:     D3DXCreateTextureFromFileEx(lpD3DDev, "sky.bmp", 0,0,0,0,D3DFMT_A8R8G8B8,
0165:                                 D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,
0166:                                 0, NULL, NULL, &pCylinderTex);
0167: 
0168:     //
0169:     // 床
0170:     //
0171:     // 頂点バッファの作成 
0172:     MyVertex *pFloorDest;
0173:     lpD3DDev->CreateVertexBuffer( 4 * sizeof(MyVertex),
0174:                                 0, 0, D3DPOOL_MANAGED, &pFloorVB );
0175:     // 頂点をセットアップ
0176:     {
0177:     pFloorVB->Lock ( 0, 0, (BYTE**)&pFloorDest, 0 );
0178:     for (DWORD i = 0; i < 4; i++) {
0179:         pFloorDest->x   = (i == 0 || i == 1)?(-FLOOR_SIZE):(+FLOOR_SIZE);
0180:         pFloorDest->z   = (i == 0 || i == 2)?(-FLOOR_SIZE):(+FLOOR_SIZE);
0181:         pFloorDest->y   = 0.0f;
0182:         pFloorDest->w   = 1.0f;
0183:         pFloorDest->tu = (i == 0 || i == 1)?0:FLOOR_UV;
0184:         pFloorDest->tv = (i == 0 || i == 2)?0:FLOOR_UV;
0185:         pFloorDest += 1;
0186:     }       
0187:     pFloorVB->Unlock ();
0188:     }
0189: 
0190: 
0191:     // インデックスをセットアップ
0192:     lpD3DDev->CreateIndexBuffer( 6 * sizeof(WORD),
0193:                                0,
0194:                                D3DFMT_INDEX16, D3DPOOL_MANAGED,
0195:                                &pFloorIB );
0196:     pFloorIB->Lock ( 0, 0, (BYTE**)&pIndex, 0 );
0197:     pIndex[0] = 0;  pIndex[1] = 1;  pIndex[2] = 2;
0198:     pIndex[3] = 1;  pIndex[4] = 3;  pIndex[5] = 2;
0199:     pFloorIB->Unlock ();
0200: 
0201:     D3DXCreateTextureFromFileEx(lpD3DDev, "tile.bmp", 0,0,0,0,D3DFMT_A8R8G8B8,
0202:                                 D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,
0203:                                 0, NULL, NULL, &pFloorTex);
0204:     
0205:     //
0206:     // 地球
0207:     //
0208:     InitEarth(lpD3DDev);
0209: }
0210: // ----------------------------------------------------------------------------
0211: void DrawBg(LPDIRECT3DDEVICE8 lpD3DDev, D3DXMATRIX &mVP)
0212: {
0213:     D3DXMATRIX mWorld, m;
0214: 
0215:     D3DXMatrixTranspose( &m, &mVP );
0216:     pVertexProgramContainer->SetShaderConstant( vertex_mat_iter, &m  );
0217: 
0218:     lpD3DDev->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_MODULATE);
0219:     lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0220:     lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG2,  D3DTA_DIFFUSE);
0221:     lpD3DDev->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0222:     
0223:     //
0224:     // 空
0225:     //
0226:     lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSU,   D3DTADDRESS_WRAP);
0227:     lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSV,   D3DTADDRESS_CLAMP);
0228: 
0229:     pPixelProgramContainer->SetTexture(tex0_iter, pCylinderTex);
0230:     lpD3DDev->SetStreamSource(0, pCylinderVB, sizeof(MyVertex));
0231:     lpD3DDev->SetIndices(pCylinderIB,0);
0232:     lpD3DDev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, NUM_VERTICES, 0 , NUM_FACES*2 );
0233:     
0234:     //
0235:     // 床
0236:     //
0237:     lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSU,   D3DTADDRESS_WRAP);
0238:     lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSV,   D3DTADDRESS_WRAP);
0239:     pPixelProgramContainer->SetTexture(tex0_iter, pFloorTex);
0240:     lpD3DDev->SetStreamSource(0, pFloorVB, sizeof(MyVertex));
0241:     lpD3DDev->SetIndices(pFloorIB,0);
0242:     lpD3DDev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 4, 0, 2 );
0243: 
0244:     //
0245:     // 地球
0246:     //
0247:     D3DXMATRIX m1, m2;
0248:     D3DXMatrixRotationY( &m1, ~0-timeGetTime()/1000.0f );
0249:     D3DXMatrixTranslation(&m2, 0,EARTH_R,0);
0250:     m = m1*m2*mVP;
0251:     D3DXMatrixTranspose( &m, &m );
0252:     pVertexProgramContainer->SetShaderConstant( vertex_mat_iter, &m  );
0253:     pPixelProgramContainer->SetTexture(tex0_iter, pEarthTex);
0254:     lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSU,   D3DTADDRESS_WRAP);
0255: 
0256:     lpD3DDev->SetStreamSource(0, pEarthVB, sizeof(MyVertex));
0257:     lpD3DDev->SetIndices(pEarthIB,0);
0258:     lpD3DDev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, NUM_EARTH_VERTICES, 0 , NUM_EARTH_POLYGONE );
0259:     
0260: }
0261: // ----------------------------------------------------------------------------
0262: void CleanBg(LPDIRECT3DDEVICE8 lpD3DDev)
0263: {
0264:     RELEASE(pEarthTex);
0265:     RELEASE(pEarthIB);
0266:     RELEASE(pEarthVB);
0267: 
0268:     RELEASE(pFloorTex);
0269:     RELEASE(pFloorIB);
0270:     RELEASE(pFloorVB);
0271:     
0272:     RELEASE(pCylinderTex);
0273:     RELEASE(pCylinderIB);
0274:     RELEASE(pCylinderVB);
0275: }