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