0001: #include "stdafx.h"
0002: #include <mmsystem.h>
0003: #include "math.h"
0004: #include "prim.h"
0005: #include "render.h"
0006: 
0007: #define frand() ((float)rand()/(float)RAND_MAX)
0008: 
0009: namespace Render {
0010: 
0011: D3DXVECTOR3 BG_COLOR = D3DXVECTOR3(0.25f, 0.4f, 0.5f);
0012: 
0013: class CCamera
0014: {
0015: private:
0016:     D3DXMATRIX  m_mView;
0017:     D3DXMATRIX  m_mProj;
0018:     D3DXMATRIX  m_mVP;
0019:     D3DXMATRIX  m_mVP_Inv;
0020:     D3DXMATRIX  m_mView_Inv;
0021: 
0022:     D3DXVECTOR3 m_vFrom;
0023:     D3DXVECTOR3 m_vLookat;
0024:     D3DXVECTOR3 m_vUp;
0025: 
0026:     float   m_fFovy;
0027:     float   m_fAspect;
0028:     float   m_fNear;
0029:     float   m_fFar;
0030: 
0031: public:
0032: 
0033:     void Update();
0034:     void SetFrom  (const D3DXVECTOR3 *p){m_vFrom  =*p;}
0035:     void SetLookAt(const D3DXVECTOR3 *p){m_vLookat=*p;}
0036:     void SetUp    (const D3DXVECTOR3 *p){m_vUp    =*p;}
0037:     void SetFovY  (float val){m_fFovy   = val;}
0038:     void SetAspect(float val){m_fAspect = val;}
0039:     void SetNear  (float val){m_fNear   = val;}
0040:     void SetFar   (float val){m_fFar    = val;}
0041: 
0042:     inline const D3DXMATRIX *GetViewInverse() const {return &m_mView_Inv;}
0043:     inline const D3DXMATRIX *GetViewProjInverse() const {return &m_mVP_Inv;}
0044:     inline void GetFrom (D3DXVECTOR3 *dest) const {*dest = m_vFrom;}
0045: };
0046: 
0047: // ---------------------------------------------------------------------------
0048: // オブジェクト
0049: // ---------------------------------------------------------------------------
0050: char  s_data [4*RENDER_WIDTH*RENDER_HEIGHT];// 仮想フレームバッファ
0051: float s_total[4*RENDER_WIDTH*RENDER_HEIGHT];// 累積フレームバッファ
0052: 
0053: CCamera camera;
0054: 
0055: CMesh *pRoom       = NULL;
0056: CMesh *pBlockSmall = NULL;
0057: CMesh *pBlockTall  = NULL;
0058: CMesh *pShpereS    = NULL;
0059: CMesh *pShpereT    = NULL;
0060: 
0061: static int s_x = 0;         // レンダリングピクセルのx座標
0062: static int s_y = 0;         // レンダリングピクセルのy座標
0063: static int s_state = 0;     // レンダリング関数の状態
0064: static float render_cnt = 0;// 描画回数
0065: enum{
0066:     STATE_IDLE=0,           // 処理待ち
0067:     STATE_RENDER_BEGIN,     // 初期化
0068:     STATE_RENDER,           // 描画
0069:     STATE_RENDER_END,       // 後片付け
0070: };
0071: 
0072: OBJ_DATA sphere_data[] = {
0073: {// 小さいのに乗ってるほう
0074:     OBJ_TYPE_SPHERE,
0075:     {
0076:         {0.10f, 0.100f, 0.10f},
0077:         0.2f, 0.8f, 0.0f, 0.0f,
0078:     },{{0,0,0},{0,0,0},{0,0,0},},{
0079:         {125.5, 0+100,169},
0080: //      {185.5, 165+100,169},
0081:         100.0f,
0082:     }
0083: },{// 大きいのに乗ってるほう
0084:     OBJ_TYPE_SPHERE,
0085:     {
0086:         {0.05f, 0.050f, 0.05f},
0087:         0.80f, 0.00f, 0.20f, 0.0f,
0088:     },{{0,0,0},{0,0,0},{0,0,0},},{
0089:         {368.5, 330+100,351},
0090:         100.0f,
0091:     }
0092: }};
0093: OBJ_DATA room_data[14] = {
0094: {
0095: // ライト1
0096:     OBJ_TYPE_TRIANGLE,
0097:     {
0098:         {100.0f*1.00f, 100.0f*0.90f, 100.0f*0.50f},
0099:         0.0f, 0.0f, 0.0f, 1.0f,
0100:     },{
0101:         {213.0, 548.799f, 227.0},
0102:         {213.0, 548.799f, 332.0},
0103:         {343.0, 548.799f, 227.0},
0104:     }
0105: },{// ライト2
0106:     OBJ_TYPE_TRIANGLE,
0107:     {
0108:         {100.0f*1.00f, 100.0f*0.90f, 100.0f*0.50f},
0109:         0.0f, 0.0f, 0.0f, 1.0f,
0110:     },{
0111:         {343.0, 548.799f, 227.0},
0112:         {213.0, 548.799f, 332.0},
0113:         {343.0, 548.799f, 332.0},
0114:     }
0115: },{ // 左1
0116:     OBJ_TYPE_TRIANGLE,
0117:     {
0118:         {0.70f, 0.15f, 0.15f},
0119:         0.0f, 0.0f, 1.0f, 0.0f,
0120:     },{
0121:         {552.8f,   0.0f,   0.0f},
0122:         {556.0f, 548.8f,   0.0f},
0123:         {549.6f,   0.0f, 559.2f},
0124:     }
0125: 
0126: },{// 左2
0127:     OBJ_TYPE_TRIANGLE,
0128:     {
0129:         {0.70f, 0.15f, 0.15f},
0130:         0.0f, 0.0f, 1.0f, 0.0f,
0131:     },{
0132:         {549.6f,   0.0f, 559.2f},
0133:         {556.0f, 548.8f,   0.0f},
0134:         {556.0f, 548.8f, 559.2f},
0135:     }
0136: 
0137: },{// 右1
0138:     OBJ_TYPE_TRIANGLE,
0139:     {
0140:         {0.15f, 0.15f, 0.70f},
0141:         0.0f, 0.0f, 1.0f, 0.0f,
0142:     },{
0143:         {0.0f,   0.0f,   0.0f},
0144:         {0.0f,   0.0f, 559.2f},
0145:         {0.0f, 548.8f,   0.0f},
0146:     }
0147: 
0148: },{// 右2
0149:     OBJ_TYPE_TRIANGLE,
0150:     {
0151:         {0.15f, 0.15f, 0.70f},
0152:         0.0f, 0.0f, 1.0f, 0.0f,
0153:     },{
0154:         {0.0f, 548.8f,   0.0f},
0155:         {0.0f,   0.0f, 559.2f},
0156:         {0.0f, 548.8f, 559.2f},
0157:     }
0158: 
0159: },{// 奥1
0160:     OBJ_TYPE_TRIANGLE,
0161:     {
0162:         {0.70f, 0.70f, 0.70f},
0163:         0.0f, 0.0f, 1.0f, 0.0f,
0164:     },{
0165:         {  0.0f,   0.0f, 559.2f},
0166:         {549.6f,   0.0f, 559.2f},
0167:         {  0.0f, 548.8f, 559.2f},
0168:     }
0169: 
0170: },{// 奥2
0171:     OBJ_TYPE_TRIANGLE,
0172:     {
0173:         {0.70f, 0.70f, 0.70f},
0174:         0.0f, 0.0f, 1.0f, 0.0f,
0175:     },{
0176:         {  0.0f, 548.8f, 559.2f},
0177:         {549.6f,   0.0f, 559.2f},
0178:         {556.0f, 548.8f, 559.2f},
0179:     }
0180: 
0181: },{// 天井1
0182:     OBJ_TYPE_TRIANGLE,
0183:     {
0184:         {0.70f, 0.70f, 0.70f},
0185:         0.0f, 0.0f, 1.0f, 0.0f,
0186:     },{
0187:         {  0.0f, 548.8f,   0.0f},
0188:         {  0.0f, 548.8f, 559.2f},
0189:         {556.0f, 548.8f,   0.0f},
0190:     }
0191: 
0192: },{// 天井2
0193:     OBJ_TYPE_TRIANGLE,
0194:     {
0195:         {0.70f, 0.70f, 0.70f},
0196:         0.0f, 0.0f, 1.0f, 0.0f,
0197:     },{
0198:         {  0.0f, 548.8f, 559.2f},
0199:         {556.0f, 548.8f, 559.2f},
0200:         {556.0f, 548.8f,   0.0f},
0201:     }
0202: 
0203: },{// 床1
0204:     OBJ_TYPE_TRIANGLE,
0205:     {
0206:         {0.70f, 0.70f, 0.70f},
0207:         0.0f, 0.0f, 1.0f, 0.0f,
0208:     },{
0209:         {  0.0f, 0.0f,   0.0f},
0210:         {552.8f, 0.0f,   0.0f},
0211:         {  0.0f, 0.0f, 559.2f},
0212:     }
0213: },{// 床1
0214:     OBJ_TYPE_TRIANGLE,
0215:     {
0216:         {0.70f, 0.70f, 0.70f},
0217:         0.0f, 0.0f, 1.0f, 0.0f,
0218:     },{
0219:         {  0.0f, 0.0f, 559.2f},
0220:         {552.8f, 0.0f,   0.0f},
0221:         {549.6f, 0.0f, 559.2f},
0222:     }
0223: },{// 手前1
0224:     OBJ_TYPE_TRIANGLE,
0225:     {
0226:         {0.70f, 0.70f, 0.70f},
0227:         0.0f, 0.0f, 1.0f, 0.0f,
0228:     },{
0229:         {  0.0f,   0.0f, 0.0f},
0230:         {  0.0f, 548.8f, 0.0f},
0231:         {549.6f,   0.0f, 0.0f},
0232:     }
0233: 
0234: },{// 手前2
0235:     OBJ_TYPE_TRIANGLE,
0236:     {
0237:         {0.70f, 0.70f, 0.70f},
0238:         0.0f, 0.0f, 1.0f, 0.0f,
0239:     },{
0240:         {  0.0f, 548.8f, 0.0f},
0241:         {556.0f, 548.8f, 0.0f},
0242:         {549.6f,   0.0f, 0.0f},
0243:     }
0244: 
0245: 
0246: }};
0247: 
0248: 
0249: OBJ_DATA Short_block[] = {
0250: {
0251:     // 床
0252:     OBJ_TYPE_TRIANGLE,
0253:     {
0254:         {0.70f, 0.70f, 0.70f},
0255:         0.0f, 0.0f, 1.0f, 0.0f,
0256:     },{
0257:         { 82.0f, 165.0f, 225.0f},
0258:         {130.0f, 165.0f,  65.0f},
0259:         {240.0f, 165.0f, 272.0f},
0260:     }
0261: },{
0262:     OBJ_TYPE_TRIANGLE,
0263:     {
0264:         {0.70f, 0.70f, 0.70f},
0265:         0.0f, 0.0f, 1.0f, 0.0f,
0266:     },{
0267:         {290.0, 165.0, 114.0},
0268:         {240.0, 165.0, 272.0},
0269:         {130.0, 165.0,  65.0},
0270:     }
0271: },{//側面
0272:     OBJ_TYPE_TRIANGLE,
0273:     {
0274:         {0.70f, 0.70f, 0.70f},
0275:         0.0f, 0.0f, 1.0f, 0.0f,
0276:     },{
0277:         {290.0, 165.0, 114.0},
0278:         {290.0,   0.0, 114.0},
0279:         {240.0, 165.0, 272.0},
0280:     }
0281: },{
0282:     OBJ_TYPE_TRIANGLE,
0283:     {
0284:         {0.70f, 0.70f, 0.70f},
0285:         0.0f, 0.0f, 1.0f, 0.0f,
0286:     },{
0287:         {240.0, 165.0, 272.0},
0288:         {290.0,   0.0, 114.0},
0289:         {240.0,   0.0, 272.0},
0290:     }
0291: },{//前面
0292:     OBJ_TYPE_TRIANGLE,
0293:     {
0294:         {0.70f, 0.70f, 0.70f},
0295:         0.0f, 0.0f, 1.0f, 0.0f,
0296:     },{
0297:         {290.0,   0.0, 114.0},
0298:         {290.0, 165.0, 114.0},
0299:         {130.0,   0.0,  65.0},
0300:     }
0301: },{
0302:     OBJ_TYPE_TRIANGLE,
0303:     {
0304:         {0.70f, 0.70f, 0.70f},
0305:         0.0f, 0.0f, 1.0f, 0.0f,
0306:     },{
0307:         {130.0,   0.0,  65.0},
0308:         {290.0, 165.0, 114.0},
0309:         {130.0, 165.0,  65.0},
0310:     }
0311: },{//側面
0312:     OBJ_TYPE_TRIANGLE,
0313:     {
0314:         {0.70f, 0.70f, 0.70f},
0315:         0.0f, 0.0f, 1.0f, 0.0f,
0316:     },{
0317:         { 82.0,   0.0, 225.0},
0318:         {130.0, 165.0,  65.0},
0319:         { 82.0, 165.0, 225.0},
0320:     }
0321: },{
0322:     OBJ_TYPE_TRIANGLE,
0323:     {
0324:         {0.70f, 0.70f, 0.70f},
0325:         0.0f, 0.0f, 1.0f, 0.0f,
0326:     },{
0327:         { 82.0,   0.0, 225.0},
0328:         {130.0,   0.0,  65.0},
0329:         {130.0, 165.0,  65.0},
0330:     }
0331: },{//背面
0332:     OBJ_TYPE_TRIANGLE,
0333:     {
0334:         {0.70f, 0.70f, 0.70f},
0335:         0.0f, 0.0f, 1.0f, 0.0f,
0336:     },{
0337:         {240.0,   0.0, 272.0},
0338:         { 82.0, 165.0, 225.0},
0339:         {240.0, 165.0, 272.0},
0340:     }
0341: },{
0342:     OBJ_TYPE_TRIANGLE,
0343:     {
0344:         {0.70f, 0.70f, 0.70f},
0345:         0.0f, 0.0f, 1.0f, 0.0f,
0346:     },{
0347:         {240.0,   0.0, 272.0},
0348:         { 82.0,   0.0, 225.0},
0349:         { 82.0, 165.0, 225.0},
0350:     }
0351: }};
0352: 
0353: OBJ_DATA Tall_block[] = {
0354: {
0355:     // 床
0356:     OBJ_TYPE_TRIANGLE,
0357:     {
0358:         {0.70f, 0.70f, 0.70f},
0359:         0.0f, 0.0f, 1.0f, 0.0f,
0360:     },{
0361:         {423.0f, 330.0f, 247.0f},
0362:         {314.0f, 330.0f, 456.0f},
0363:         {265.0f, 330.0f, 296.0f},
0364:     }
0365: },{
0366:     OBJ_TYPE_TRIANGLE,
0367:     {
0368:         {0.70f, 0.70f, 0.70f},
0369:         0.0f, 0.0f, 1.0f, 0.0f,
0370:     },{
0371:         {423.0f, 330.0f, 247.0f},
0372:         {472.0f, 330.0f, 406.0f},
0373:         {314.0f, 330.0f, 456.0f},
0374:     }
0375: },{//側面
0376:     OBJ_TYPE_TRIANGLE,
0377:     {
0378:         {0.70f, 0.70f, 0.70f},
0379:         0.0f, 0.0f, 1.0f, 0.0f,
0380:     },{
0381:         {423.0f,   0.0f, 247.0f},
0382:         {472.0f,   0.0f, 406.0f},
0383:         {423.0f, 330.0f, 247.0f},
0384:     }
0385: },{
0386:     OBJ_TYPE_TRIANGLE,
0387:     {
0388:         {0.70f, 0.70f, 0.70f},
0389:         0.0f, 0.0f, 1.0f, 0.0f,
0390:     },{
0391:         {423.0f, 330.0f, 247.0f},
0392:         {472.0f,   0.0f, 406.0f},
0393:         {472.0f, 330.0f, 406.0f},
0394:     }
0395: },{//背面
0396:     OBJ_TYPE_TRIANGLE,
0397:     {
0398:         {0.70f, 0.70f, 0.70f},
0399:         0.0f, 0.0f, 1.0f, 0.0f,
0400:     },{
0401:         {314.0f,   0.0f, 456.0f},
0402:         {314.0f, 330.0f, 456.0f},
0403:         {472.0f,   0.0f, 406.0f},
0404:     }
0405: },{
0406:     OBJ_TYPE_TRIANGLE,
0407:     {
0408:         {0.70f, 0.70f, 0.70f},
0409:         0.0f, 0.0f, 1.0f, 0.0f,
0410:     },{
0411:         {314.0f, 330.0f, 456.0f},
0412:         {472.0f, 330.0f, 406.0f},
0413:         {472.0f,   0.0f, 406.0f},
0414:     }
0415: },{//側面
0416:     OBJ_TYPE_TRIANGLE,
0417:     {
0418:         {0.70f, 0.70f, 0.70f},
0419:         0.0f, 0.0f, 1.0f, 0.0f,
0420:     },{
0421:         {314.0f,   0.0f, 456.0f},
0422:         {265.0f,   0.0f, 296.0f},
0423:         {265.0f, 330.0f, 296.0f},
0424:     }
0425: },{
0426:     OBJ_TYPE_TRIANGLE,
0427:     {
0428:         {0.70f, 0.70f, 0.70f},
0429:         0.0f, 0.0f, 1.0f, 0.0f,
0430:     },{
0431:         {314.0f,   0.0f, 456.0f},
0432:         {265.0f, 330.0f, 296.0f},
0433:         {314.0f, 330.0f, 456.0f},
0434:     }
0435: },{//前面
0436:     OBJ_TYPE_TRIANGLE,
0437:     {
0438:         {0.70f, 0.70f, 0.70f},
0439:         0.0f, 0.0f, 1.0f, 0.0f,
0440:     },{
0441:         {265.0f,   0.0f, 296.0f},
0442:         {423.0f,   0.0f, 247.0f},
0443:         {265.0f, 330.0f, 296.0f},
0444:     }
0445: },{
0446:     OBJ_TYPE_TRIANGLE,
0447:     {
0448:         {0.70f, 0.70f, 0.70f},
0449:         0.0f, 0.0f, 1.0f, 0.0f,
0450:     },{
0451:         {265.0f, 330.0f, 296.0f},
0452:         {423.0f,   0.0f, 247.0f},
0453:         {423.0f, 330.0f, 247.0f},
0454:     }
0455: }};
0456: 
0457: // ---------------------------------------------------------------------------
0458: // 関数宣言
0459: // ---------------------------------------------------------------------------
0460: D3DXVECTOR3 *GetColor(D3DXVECTOR3 *dest, float x, float y);
0461: 
0462: 
0463: // ---------------------------------------------------------------------------
0464: // カメラクラス
0465: // ---------------------------------------------------------------------------
0466: void CCamera::Update()
0467: {
0468:     D3DXMatrixLookAtLH( &m_mView, &m_vFrom, &m_vLookat, &m_vUp );
0469:     D3DXMatrixPerspectiveFovLH( &m_mProj, m_fFovy, m_fAspect, m_fNear, m_fFar );
0470:     m_mVP = m_mView * m_mProj;
0471: 
0472:     D3DXMatrixInverse( &m_mView_Inv, NULL, &m_mView);
0473:     D3DXMatrixInverse( &m_mVP_Inv, NULL, &m_mVP);
0474: }
0475: 
0476: 
0477: // ---------------------------------------------------------------------------
0478: char *GetDataPointer()
0479: {
0480:     return s_data;
0481: }
0482: // ---------------------------------------------------------------------------
0483: int GetRenderCount()
0484: {
0485:     return (int)(render_cnt+0.5f);
0486: }
0487: // ---------------------------------------------------------------------------
0488: void Init()
0489: {
0490:     int i, j;
0491: 
0492:     camera.SetFrom  (&D3DXVECTOR3(278,273,-800));
0493:     camera.SetLookAt(&D3DXVECTOR3(278,273,0));
0494:     camera.SetUp    (&D3DXVECTOR3(0,1,0));
0495:     camera.SetFovY  (D3DX_PI/4);
0496:     camera.SetAspect(1.0f);
0497:     camera.SetNear  (0.01f);
0498:     camera.SetFar   (100.0f);
0499:     camera.Update();
0500: 
0501:     pRoom = new CMesh();
0502:     pRoom->Init( room_data, 14 );
0503:     
0504:     pBlockSmall = new CMesh();
0505:     pBlockSmall->Init( Short_block, 10);
0506: 
0507:     pBlockTall = new CMesh();
0508:     pBlockTall->Init( Tall_block, 10);
0509:     
0510:     pShpereS = new CMesh();
0511:     pShpereS->Init( sphere_data, 1);
0512:     
0513:     pShpereT = new CMesh();
0514:     pShpereT->Init( sphere_data+1,1);
0515: 
0516:     render_cnt = 0; // レンダリング回数
0517:     // フレームバッファの初期化
0518:     for(j=0; j<RENDER_HEIGHT; j++){
0519:     for(i=0; i<RENDER_WIDTH ; i++){
0520:         s_data [4*(j*RENDER_WIDTH+i)+0]=(char)255;// R
0521:         s_data [4*(j*RENDER_WIDTH+i)+1]=(char)(i*256/RENDER_WIDTH );// G
0522:         s_data [4*(j*RENDER_WIDTH+i)+2]=(char)(j*256/RENDER_HEIGHT);// B
0523:         s_total[4*(j*RENDER_WIDTH+i)+0]=0;// R
0524:         s_total[4*(j*RENDER_WIDTH+i)+1]=0;// G
0525:         s_total[4*(j*RENDER_WIDTH+i)+2]=0;// B
0526:     }
0527:     }
0528: }
0529: // ---------------------------------------------------------------------------
0530: void Delete()
0531: {
0532:     if(pShpereT){delete pShpereT;pShpereT=NULL;}
0533:     if(pShpereS){delete pShpereS;pShpereS=NULL;}
0534:     if(pBlockTall){delete pBlockTall;pBlockTall=NULL;}
0535:     if(pBlockSmall){delete pBlockSmall;pBlockSmall=NULL;}
0536:     if(pRoom){delete pRoom; pRoom=NULL;}
0537: }
0538: // ---------------------------------------------------------------------------
0539: void Begin()
0540: {
0541:     s_state = STATE_RENDER_BEGIN;
0542: }
0543: // ---------------------------------------------------------------------------
0544: int Render()
0545: {
0546:     if(STATE_IDLE==s_state) return 0;
0547: 
0548:     int i,j,no;
0549:     D3DXVECTOR3 col;
0550:     int ret = -1;
0551: 
0552:     timeBeginPeriod( 500 );// タイマー精度の設定
0553: 
0554:     for(unsigned long t = timeGetTime()
0555:         ; timeGetTime()-t < 1000        // 1秒たったか
0556:         && STATE_IDLE!=s_state;){       // 終了したか
0557: 
0558:         switch(s_state){
0559:         case STATE_IDLE:        // 待機
0560:             break;
0561:         case STATE_RENDER_BEGIN:// 初期化
0562:             s_x = 0;
0563:             s_y = 0;
0564:             render_cnt+=1.0f;
0565:             s_state = STATE_RENDER;
0566:             break;
0567:         case STATE_RENDER:      // 画面の描画
0568:             GetColor(&col, ((float)s_x+frand())/(float)RENDER_WIDTH
0569:                          , ((float)s_y+frand())/(float)RENDER_HEIGHT);
0570:             s_total[4*(s_y*RENDER_WIDTH+s_x)+0]+=col.x;// R
0571:             s_total[4*(s_y*RENDER_WIDTH+s_x)+1]+=col.y;// G
0572:             s_total[4*(s_y*RENDER_WIDTH+s_x)+2]+=col.z;// B
0573: 
0574:             // 次のピクセルに移動
0575:             if(RENDER_WIDTH<=++s_x){
0576:                 // 行を変える
0577:                 s_x = 0;
0578:                 if(RENDER_HEIGHT<=++s_y){
0579:                     s_state = STATE_RENDER_END;
0580:                     break;
0581:                 }
0582:             }
0583:             break;
0584:         case STATE_RENDER_END:  // 描画の終了
0585:             // 画面の反映
0586:             no = 0;
0587:             for(j=0; j<RENDER_HEIGHT; j++){
0588:             for(i=0; i<RENDER_WIDTH ; i++){
0589:                 s_data [no+0]=(char)(255.9*min(1,s_total[no+0]/render_cnt));// R
0590:                 s_data [no+1]=(char)(255.9*min(1,s_total[no+1]/render_cnt));// G
0591:                 s_data [no+2]=(char)(255.9*min(1,s_total[no+2]/render_cnt));// B
0592:                 no += 4;
0593:             }
0594:             }
0595:             s_state = STATE_RENDER_BEGIN;// 無限ループ
0596:             break;
0597:         }
0598:     }
0599: 
0600:     timeEndPeriod( 500 );// タイマー精度を戻す
0601: 
0602:     return ret;
0603: }
0604: 
0605: // ---------------------------------------------------------------------------
0606: bool GetColor(D3DXVECTOR3 *dest, const D3DXVECTOR4 *x, const D3DXVECTOR4 *v, int depth)
0607: {
0608:     D3DXVECTOR3 diffuse_color=D3DXVECTOR3(0,0,0);
0609: 
0610:     // -----------------------------------------------------------------------
0611:     // 初期化:光が屈折、反射しかしないで延々と跳ね返ったときは、光が届かない黒色
0612:     // -----------------------------------------------------------------------
0613:     if(0==depth) *dest = D3DXVECTOR3(0,0,0);
0614: 
0615:     // -----------------------------------------------------------------------
0616:     // 再帰しすぎた場合は光が届いていないものと考える
0617:     // -----------------------------------------------------------------------
0618:     const int DEPTH_MAX = 3;
0619:     if(DEPTH_MAX <= depth) { *dest=D3DXVECTOR3(0,0,0); return FALSE;}
0620: 
0621:     // -----------------------------------------------------------------------
0622:     // 視線から交点を求める
0623:     // -----------------------------------------------------------------------
0624:     float t = CPrimitive::INFINTY_DIST;
0625:     CPrimitive *pObj = NULL;
0626:     D3DXVECTOR4 p, n;// 交点の位置と法線
0627: 
0628:     t = pShpereS   ->IsAcross(t, &n, &p, &pObj, x, v);
0629:     t = pShpereT   ->IsAcross(t, &n, &p, &pObj, x, v);
0630:     t = pRoom      ->IsAcross(t, &n, &p, &pObj, x, v);
0631: //  t = pBlockSmall->IsAcross(t, &n, &p, &pObj, x, v);
0632:     t = pBlockTall ->IsAcross(t, &n, &p, &pObj, x, v);
0633: 
0634:     if( NULL == pObj ){
0635:         // 視線はオブジェクトから外れた!
0636:         *dest = BG_COLOR;
0637:         return TRUE;
0638:     }
0639: 
0640:     // -----------------------------------------------------------------------
0641:     // 反射方向をロシアンルーレットで決める
0642:     // -----------------------------------------------------------------------
0643:     float cd = pObj->m_material.diffuse;    // 拡散率
0644:     float cr = pObj->m_material.reflection; // 反射率
0645:     float cn = pObj->m_material.refraction; // 屈折率
0646:     float ce = pObj->m_material.emmisive;   // 放射率
0647:     float total = cd+cr+cn+ce;
0648:     float prob = total * frand();
0649: 
0650:     int type = 0;// 拡散
0651:     if(prob < cr      ) type = 1; else// 反射
0652:     if(prob < cr+cn   ) type = 2; else// 屈折
0653:     if(prob < cr+cn+ce) type = 3;     // 放射
0654: 
0655:     // -----------------------------------------------------------------------
0656:     // 交点が、影に隠れているかどうか調べて、拡散光を算出する
0657:     // -----------------------------------------------------------------------
0658:     if(0==type){
0659:         if(++depth<DEPTH_MAX){
0660:             // さらに奥を検索
0661:             D3DXVECTOR4 dir, pos;
0662:             
0663:             // 等方的にレイを飛ばす
0664:             float theta =      D3DX_PI * frand();
0665:             float phi   = 2.0f*D3DX_PI * frand();
0666:             dir.x = sinf(theta) * cosf(phi);
0667:             dir.y = sinf(theta) * sinf(phi);
0668:             dir.z = cosf(theta);
0669:             float dn = D3DXVec3Dot((D3DXVECTOR3 *)&dir, (D3DXVECTOR3 *)&n);
0670:             if(dn<0){
0671:                 // 法線と反対向きに飛ぶつもりなら、方向を反対にする
0672:                 dn = -dn;
0673:                 dir.x *= -1;
0674:                 dir.y *= -1;
0675:                 dir.z *= -1;
0676:             }
0677: 
0678:             pos = p + 0.01f*(dir);
0679:             GetColor(&diffuse_color, &pos, &dir, depth);
0680:             // プリミティブの色や拡散光の余弦側を適用
0681:             diffuse_color.x *= pObj->m_material.COLOR_DIF[0] * dn;
0682:             diffuse_color.y *= pObj->m_material.COLOR_DIF[1] * dn;
0683:             diffuse_color.z *= pObj->m_material.COLOR_DIF[2] * dn;
0684:         }
0685:     }
0686: 
0687:     // -----------------------------------------------------------------------
0688:     // 再帰的に光線を飛ばして、より高次の反射を考慮に入れる
0689:     // -----------------------------------------------------------------------
0690:     // 反射
0691:     D3DXVECTOR3 reflect_color=D3DXVECTOR3(0,0,0);
0692:     if(1==type){
0693:         // 反射ベクトル
0694:         D3DXVECTOR4 r = *v - 2.0f*D3DXVec3Dot((D3DXVECTOR3 *)&n, (D3DXVECTOR3 *)v) * n;
0695:         D3DXVECTOR4 pos = p + 0.01f*n;// ちょっと浮かす
0696:         if(!GetColor( &reflect_color, &pos, &r, depth)){
0697:             cr = 0;// 結局、光が届かなかった
0698:         }
0699:     }
0700: 
0701:     // -----------------------------------------------------------------------
0702:     // 屈折
0703:     // -----------------------------------------------------------------------
0704:     D3DXVECTOR3 refract_color=D3DXVECTOR3(0,0,0);
0705:     if(2==type){
0706:         // 屈折ベクトル
0707:         D3DXVECTOR4 t, pos;
0708:         float VN = D3DXVec3Dot((D3DXVECTOR3 *)v, (D3DXVECTOR3 *)&n);
0709:         float eta = 1.5f;
0710:         if(VN<0){
0711:             // 入射
0712:             float D = 1-(1+VN)*(1+VN)/(eta*eta);
0713:             if(D<0){cn=0;goto no_refract;}// 全反射
0714:             t = (-VN/eta-sqrtf(D))*n+(1/eta)*(*v);
0715:             pos = p - 0.01f*n;// ちょっと浮かす
0716:         }else{
0717:             // 出て行く
0718:             float D = 1-(1-VN)*(1-VN)*(eta*eta);
0719:             if(D<0){cn=0;goto no_refract;}// 全反射
0720:             t = -(VN*eta-sqrtf(D))*n+eta*(*v);
0721:             pos = p + 0.01f*n;// ちょっと浮かす
0722:         }
0723:         D3DXVec3Normalize( (D3DXVECTOR3 *)&t, (D3DXVECTOR3 *)&t );
0724:         if(!GetColor( &refract_color, &pos, &t, depth)){
0725:             cn = 0;// 結局、光が届かなかった
0726:         }
0727:     }
0728: no_refract:
0729: 
0730:     // -----------------------------------------------------------------------
0731:     // 放射
0732:     // -----------------------------------------------------------------------
0733:     D3DXVECTOR3 emmisive_color = *(D3DXVECTOR3*)&pObj->m_material.COLOR_DIF;
0734: 
0735:     // -----------------------------------------------------------------------
0736:     // 色を出力する
0737:     // -----------------------------------------------------------------------
0738:     switch(type){
0739:     case 0:// 拡散
0740:         *dest = (cd+cr+cn) * diffuse_color;
0741:         break;
0742:     case 1:// 反射
0743:         *dest = (cd+cr+cn) * reflect_color;     
0744:         break;
0745:     case 2:// 屈折
0746:         *dest = (cd+cr+cn) * refract_color;
0747:         break;
0748:     case 3:// 放射
0749:         *dest = ce * emmisive_color;
0750:         break;
0751:     }
0752: 
0753:     return TRUE;
0754: }
0755: // ---------------------------------------------------------------------------
0756: D3DXVECTOR3 *GetColor(D3DXVECTOR3 *dest, float x, float y)
0757: {
0758:     D3DXVECTOR4 ray_start_proj = D3DXVECTOR4(-2*x+1, -2*y+1, 0, 1);// 前方クリップ面
0759:     D3DXVECTOR4 ray_eye        = D3DXVECTOR4(0, 0, 0, 1);// ビュー空間でのカメラの位置
0760:     D3DXVECTOR4 ray_start;
0761:     D3DXVECTOR4 ray_to;
0762:     D3DXVECTOR4 ray_dir;
0763:     D3DXMATRIX mInv;
0764:     
0765:     // 視点を射影空間からワールド座標に変換する
0766:     D3DXVec4Transform( &ray_start, &ray_eye,        camera.GetViewInverse() );
0767:     D3DXVec4Transform( &ray_to,    &ray_start_proj, camera.GetViewProjInverse() );
0768:     D3DXVec4Scale( &ray_to,    &ray_to,    1.0f/ray_to.w   );// w=1 の射影空間に落とす
0769:     // 向きの計算
0770:     ray_dir = ray_to - ray_start;
0771:     D3DXVec4Normalize(&ray_dir, &ray_dir);
0772:     
0773:     GetColor(dest, &ray_start, &ray_dir, 0);
0774: 
0775:     return dest;
0776: }
0777: 
0778: };// namespace Render
0779: