0001:
0002:
0003:
0004:
0005:
0006:
0007:
0008:
0009: #define STRICT
0010:
0011: #include "Cg/cgD3D.h"
0012: #include "main.h"
0013: #include "d3dx8.h"
0014:
0015:
0016: static cgProgramContainer *pVs = 0;
0017: static cgBindIter * vertex_mat_iter = 0;
0018:
0019: static cgProgramContainer *pPs = 0;
0020: static cgBindIter * tex0_iter = 0;
0021:
0022:
0023:
0024:
0025: typedef struct{
0026: float x,y,z,w;
0027: float tu,tv;
0028: } MyVertex;
0029:
0030:
0031: static cgVertexDefinition vertex_attributes[] = {
0032: {D3DVSDT_FLOAT4, "position", 0},
0033: {D3DVSDT_FLOAT2, "texcoord0", 0},
0034: CGVERTEXDEFINITIONEND
0035: };
0036:
0037:
0038:
0039: #define NUM_Y 1
0040: #define NUM_CIRCLE 32
0041: #define NUM_VERTICES ((NUM_Y+1)*(NUM_CIRCLE+1))
0042: #define NUM_INDICES_PERFACE (3*2)
0043: #define NUM_FACES (NUM_Y*NUM_CIRCLE)
0044: #define NUM_VERTICES_PERFACE 4
0045:
0046: LPDIRECT3DVERTEXBUFFER8 pCylinderVB;
0047: LPDIRECT3DINDEXBUFFER8 pCylinderIB;
0048: LPDIRECT3DTEXTURE8 pCylinderTex;
0049:
0050:
0051:
0052: static void InitSky(LPDIRECT3DDEVICE8 lpD3DDev)
0053: {
0054:
0055: MyVertex *pDest;
0056: lpD3DDev->CreateVertexBuffer( NUM_VERTICES * sizeof(MyVertex),
0057: 0, 0, D3DPOOL_MANAGED, &pCylinderVB );
0058:
0059:
0060: WORD k=0;
0061: pCylinderVB->Lock ( 0, 0, (BYTE**)&pDest, 0 );
0062: float r = 10.0f;
0063: float h = 10.0f;
0064: for (DWORD i = 0; i <= NUM_CIRCLE; i++) {
0065: float theta = (2*PI*(float)i)/(float)NUM_CIRCLE;
0066: for (DWORD j = 0; j <= NUM_Y; j++) {
0067: pDest->x = r * (float)cos(theta);
0068: pDest->z = r * (float)sin(theta);
0069: pDest->y = h*((float)j/(float)NUM_Y-0.0f);
0070: pDest->w = 1.0f;
0071: pDest->tu = (float)i / (float)NUM_CIRCLE;
0072: pDest->tv = 1.0f-(float)j / (float)NUM_Y;
0073: pDest += 1;
0074: }
0075: }
0076: pCylinderVB->Unlock ();
0077:
0078:
0079:
0080: WORD *pIndex;
0081: lpD3DDev->CreateIndexBuffer( NUM_INDICES_PERFACE * NUM_FACES * sizeof(WORD),
0082: 0 ,
0083: D3DFMT_INDEX16, D3DPOOL_DEFAULT,
0084: &pCylinderIB );
0085: pCylinderIB->Lock ( 0, 0, (BYTE**)&pIndex, 0 );
0086: {
0087: for (WORD i = 0; i < NUM_CIRCLE; i++) {
0088: for (WORD j = 0; j < NUM_Y; j++) {
0089: *pIndex++ = j + 0 + (i+0) * (NUM_Y+1);
0090: *pIndex++ = j + 0 + (i+1) * (NUM_Y+1);
0091: *pIndex++ = j + 1 + (i+0) * (NUM_Y+1);
0092:
0093: *pIndex++ = j + 1 + (i+0) * (NUM_Y+1);
0094: *pIndex++ = j + 0 + (i+1) * (NUM_Y+1);
0095: *pIndex++ = j + 1 + (i+1) * (NUM_Y+1);
0096: }
0097: }
0098: }
0099: pCylinderIB->Unlock ();
0100:
0101: D3DXCreateTextureFromFileEx(lpD3DDev, "sky.bmp", 0,0,0,0,D3DFMT_A8R8G8B8,
0102: D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,
0103: 0, NULL, NULL, &pCylinderTex);
0104: }
0105:
0106:
0107:
0108:
0109:
0110:
0111:
0112: #define FLOOR_SIZE (10.0f)
0113: #define FLOOR_UV (10.0f)
0114: LPDIRECT3DVERTEXBUFFER8 pFloorVB;
0115: LPDIRECT3DINDEXBUFFER8 pFloorIB;
0116: LPDIRECT3DTEXTURE8 pFloorTex;
0117:
0118:
0119:
0120: static void InitFloor(LPDIRECT3DDEVICE8 lpD3DDev)
0121: {
0122: WORD *pIndex;
0123:
0124:
0125: MyVertex *pFloorDest;
0126: lpD3DDev->CreateVertexBuffer( 4 * sizeof(MyVertex),
0127: 0, 0, D3DPOOL_MANAGED, &pFloorVB );
0128:
0129: {
0130: pFloorVB->Lock ( 0, 0, (BYTE**)&pFloorDest, 0 );
0131: for (DWORD i = 0; i < 4; i++) {
0132: pFloorDest->x = (i == 0 || i == 1)?(-FLOOR_SIZE):(+FLOOR_SIZE);
0133: pFloorDest->z = (i == 0 || i == 2)?(-FLOOR_SIZE):(+FLOOR_SIZE);
0134: pFloorDest->y = 0.0f;
0135: pFloorDest->w = 1.0f;
0136: pFloorDest->tu = (i == 0 || i == 1)?0:FLOOR_UV;
0137: pFloorDest->tv = (i == 0 || i == 2)?0:FLOOR_UV;
0138: pFloorDest += 1;
0139: }
0140: pFloorVB->Unlock ();
0141: }
0142:
0143:
0144:
0145: lpD3DDev->CreateIndexBuffer( 6 * sizeof(WORD),
0146: 0,
0147: D3DFMT_INDEX16, D3DPOOL_MANAGED,
0148: &pFloorIB );
0149: pFloorIB->Lock ( 0, 0, (BYTE**)&pIndex, 0 );
0150: pIndex[0] = 0; pIndex[1] = 1; pIndex[2] = 2;
0151: pIndex[3] = 1; pIndex[4] = 3; pIndex[5] = 2;
0152: pFloorIB->Unlock ();
0153:
0154: D3DXCreateTextureFromFileEx(lpD3DDev, "tile.bmp", 0,0,0,0,D3DFMT_A8R8G8B8,
0155: D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,
0156: 0, NULL, NULL, &pFloorTex);
0157:
0158: }
0159:
0160:
0161:
0162:
0163: LPDIRECT3DVERTEXBUFFER8 pEarthVB;
0164: LPDIRECT3DINDEXBUFFER8 pEarthIB;
0165: LPDIRECT3DTEXTURE8 pEarthTex;
0166: #define EARTH_R (0.7f)
0167: #define NUM_EARTH_X 32
0168: #define NUM_EARTH_Y 16
0169: #define NUM_EARTH_VERTICES ((NUM_EARTH_X+1)*(NUM_EARTH_Y+1))
0170: #define NUM_EARTH_POLYGONE (2*NUM_EARTH_X*NUM_EARTH_Y)
0171: #define NUM_EARTH_INDEX (6*NUM_EARTH_X*NUM_EARTH_Y)
0172:
0173:
0174:
0175: static void InitEarth(LPDIRECT3DDEVICE8 lpD3DDev)
0176: {
0177: WORD i, j;
0178:
0179:
0180: MyVertex *pEarthDest;
0181: lpD3DDev->CreateVertexBuffer( NUM_EARTH_VERTICES * sizeof(MyVertex),
0182: 0, 0, D3DPOOL_MANAGED,
0183: &pEarthVB );
0184:
0185: pEarthVB->Lock ( 0, 0, (BYTE**)&pEarthDest, 0 );
0186: for ( j = 0; j <= NUM_EARTH_Y; j++) {
0187: for ( i = 0; i <= NUM_EARTH_X; i++) {
0188: float theta = ((float)i)*2*D3DX_PI/NUM_EARTH_X;
0189: float phi = ((float)j)* D3DX_PI/NUM_EARTH_Y-D3DX_PI/2;
0190: pEarthDest->x = EARTH_R * (float)cos(phi) * (float)cos(theta);
0191: pEarthDest->z = EARTH_R * (float)cos(phi) * (float)sin(theta);
0192: pEarthDest->y = EARTH_R * (float)sin(phi);
0193: pEarthDest->w = 1.0f;
0194: pEarthDest->tu = (float)i/NUM_EARTH_X;
0195: pEarthDest->tv = 1.0f-(float)j/NUM_EARTH_Y;
0196: pEarthDest++;
0197: }
0198: }
0199: pEarthVB->Unlock ();
0200:
0201:
0202:
0203: WORD *pIndex;
0204: lpD3DDev->CreateIndexBuffer( NUM_EARTH_INDEX * sizeof(WORD),
0205: 0,
0206: D3DFMT_INDEX16, D3DPOOL_MANAGED,
0207: &pEarthIB );
0208: pEarthIB->Lock ( 0, 0, (BYTE**)&pIndex, 0 );
0209: for ( j = 0; j < NUM_EARTH_Y; j++) {
0210: for ( i = 0; i < NUM_EARTH_X; i++) {
0211: *pIndex++ = (j+0)*(NUM_EARTH_X+1)+i+0;
0212: *pIndex++ = (j+1)*(NUM_EARTH_X+1)+i+0;
0213: *pIndex++ = (j+0)*(NUM_EARTH_X+1)+i+1;
0214: *pIndex++ = (j+0)*(NUM_EARTH_X+1)+i+1;
0215: *pIndex++ = (j+1)*(NUM_EARTH_X+1)+i+0;
0216: *pIndex++ = (j+1)*(NUM_EARTH_X+1)+i+1;
0217: }
0218: }
0219: pEarthIB->Unlock ();
0220:
0221: D3DXCreateTextureFromFileEx(lpD3DDev, "earth.bmp", 0,0,0,0,D3DFMT_A8R8G8B8,
0222: D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,
0223: 0, NULL, NULL, &pEarthTex);
0224:
0225: }
0226:
0227:
0228:
0229: void InitShader(LPDIRECT3DDEVICE8 lpD3DDev, cgContextContainer *pCg)
0230: {
0231:
0232:
0233:
0234: pVs = pCg->LoadCGProgramFromFile(
0235: "bgvs.cg", "Vertex Shader", cgDX8VertexProfile, vertex_attributes);
0236: extern cgDirect3D cg;
0237: if (pVs == NULL) {
0238:
0239: const char * listing = pCg->GetLastListing();
0240: if (listing == 0) listing = "Could not find cgc.exe.";
0241: cg.NotePad("頂点シェーダープログラムの生成に失敗しました\n\n", listing);
0242:
0243: exit(1);
0244: }
0245:
0246:
0247: vertex_mat_iter = pVs->GetParameterBindByName("worldviewproj_matrix");
0248:
0249:
0250:
0251:
0252: pPs = pCg->LoadCGProgramFromFile(
0253: "bgps.cg", "test", cgDX8PixelProfile);
0254:
0255: if (pPs == NULL) {
0256:
0257: const char * listing = pCg->GetLastListing();
0258: if (listing == 0) listing = "Could not find cgc.exe.";
0259: cg.NotePad("ピクセルシェーダープログラムの生成に失敗しました\n\n", listing);
0260:
0261: exit(1);
0262: }
0263:
0264: tex0_iter = pPs->GetTextureBindByName("tex0");
0265: int t0 = pPs->GetTexturePosition(tex0_iter);
0266: }
0267:
0268: void InitBg(LPDIRECT3DDEVICE8 lpD3DDev, cgContextContainer *pCg)
0269: {
0270: InitShader(lpD3DDev, pCg);
0271:
0272: InitSky(lpD3DDev);
0273: InitFloor(lpD3DDev);
0274: InitEarth(lpD3DDev);
0275: }
0276:
0277: void DrawBg(LPDIRECT3DDEVICE8 lpD3DDev, D3DXMATRIX &mVP)
0278: {
0279: D3DXMATRIX mWorld, m;
0280:
0281:
0282: pVs->SetShaderActive();
0283: pPs->SetShaderActive();
0284:
0285: D3DXMatrixTranspose( &m, &mVP );
0286: pVs->SetShaderConstant( vertex_mat_iter, &m );
0287:
0288: lpD3DDev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_MODULATE);
0289: lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
0290: lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG2, D3DTA_DIFFUSE);
0291: lpD3DDev->SetTextureStageState(1,D3DTSS_COLOROP, D3DTOP_DISABLE);
0292:
0293:
0294:
0295:
0296: lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
0297: lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
0298: pPs->SetTexture(tex0_iter, pCylinderTex);
0299: lpD3DDev->SetStreamSource(0, pCylinderVB, sizeof(MyVertex));
0300: lpD3DDev->SetIndices(pCylinderIB,0);
0301: lpD3DDev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, NUM_VERTICES, 0 , NUM_FACES*2 );
0302:
0303:
0304:
0305:
0306: lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
0307: lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
0308: pPs->SetTexture(tex0_iter, pFloorTex);
0309: lpD3DDev->SetStreamSource(0, pFloorVB, sizeof(MyVertex));
0310: lpD3DDev->SetIndices(pFloorIB,0);
0311: lpD3DDev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 4, 0, 2 );
0312:
0313:
0314:
0315:
0316: lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
0317: D3DXMATRIX m1, m2;
0318: float t = 2.0f*D3DX_PI*(1.0f-(float)(timeGetTime()%0x1fff)/(32.0f*256.0f));
0319: while(t<0)t+=2.0f*D3DX_PI;
0320: D3DXMatrixRotationY( &m1, t );
0321: D3DXMatrixTranslation(&m2, 3.0f,3.0f,-10.0f);
0322: m = m1*m2*mVP;
0323: D3DXMatrixTranspose( &m, &m );
0324: pVs->SetShaderConstant( vertex_mat_iter, &m );
0325: pPs->SetTexture(tex0_iter, pEarthTex);
0326: lpD3DDev->SetStreamSource(0, pEarthVB, sizeof(MyVertex));
0327: lpD3DDev->SetIndices(pEarthIB,0);
0328: lpD3DDev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, NUM_EARTH_VERTICES, 0 , NUM_EARTH_POLYGONE );
0329:
0330: }
0331:
0332: void CleanBg(LPDIRECT3DDEVICE8 lpD3DDev)
0333: {
0334: RELEASE(pEarthTex);
0335: RELEASE(pEarthIB);
0336: RELEASE(pEarthVB);
0337:
0338: RELEASE(pFloorTex);
0339: RELEASE(pFloorIB);
0340: RELEASE(pFloorVB);
0341:
0342: RELEASE(pCylinderTex);
0343: RELEASE(pCylinderIB);
0344: RELEASE(pCylinderVB);
0345: }