0001: #include "stdafx.h"
0002: #include <process.h>
0003: #include "math.h"
0004: #include "prim.h"
0005: #include "render.h"
0006: #include "math\CRand.h"
0007: #include "CBitmap.h"
0008: 
0009: 
0010: namespace Render {
0011: 
0012: D3DXVECTOR3 BG_COLOR = D3DXVECTOR3(0.25f, 0.4f, 0.5f);
0013: 
0014: typedef struct
0015: {
0016:     s32 left;
0017:     s32 right;
0018:     s32 top;
0019:     s32 bottom;
0020: } rect;
0021: 
0022: 
0023: class CCamera
0024: {
0025: private:
0026:     D3DXVECTOR3 m_vFrom;
0027:     D3DXVECTOR3 m_vLookat;
0028:     D3DXVECTOR3 m_vUp;
0029: 
0030:     float   m_fFilmSize[2];  // フィルムの実寸0.036*0.024[m*m]0.025*0.025(Cornell Box)
0031:     float   m_fFocalLength;  // 焦点距離 0.035(Cornell Box )
0032:     float   m_fFNumber;      // F値
0033:     float   m_fFocusDistance;// ピントが合う位置までの距離
0034: 
0035:     float   m_fLensRadius;   // レンズの半径(f/2F)
0036:     float   m_fFilmDistance; // フィルムまでの距離 Lf/(L-f)
0037: 
0038:     D3DXVECTOR3 u, v, w;
0039: 
0040: public:
0041: 
0042:     void Update();
0043:     void SetFrom  (const D3DXVECTOR3 *p){m_vFrom  =*p;}
0044:     void SetLookAt(const D3DXVECTOR3 *p){m_vLookat=*p;}
0045:     void SetUp    (const D3DXVECTOR3 *p){m_vUp    =*p;}
0046:     void SetFilmSize      (float w, float h){m_fFilmSize[0] = w; m_fFilmSize[1] = h;}
0047:     void SetFocalLength   (float v){m_fFocalLength   = v;}
0048:     void SetFNumber       (float v){m_fFNumber       = v;}
0049:     void SetFocusDistance (float v){m_fFocusDistance = v;}
0050:     
0051:     void GetRay( D3DXVECTOR3 *o, D3DXVECTOR3 *v, float x, float y);
0052: };
0053: 
0054: // ---------------------------------------------------------------------------
0055: // オブジェクト
0056: // ---------------------------------------------------------------------------
0057: char  s_data [4*RENDER_WIDTH*RENDER_HEIGHT];// 仮想フレームバッファ
0058: float s_total[4*RENDER_WIDTH*RENDER_HEIGHT];// 累積フレームバッファ
0059: 
0060: CCamera camera;
0061: 
0062: CRand   *g_pRand = NULL;
0063: #define frand() ((float)g_pRand->GetF32())
0064: 
0065: CMesh *pRoom       = NULL;
0066: CMesh *pBlockSmall = NULL;
0067: CMesh *pBlockTall  = NULL;
0068: CMesh *pShpereS    = NULL;
0069: CMesh *pShpereT    = NULL;
0070: 
0071: static int s_x = 0;         // レンダリングピクセルのx座標
0072: static int s_y = 0;         // レンダリングピクセルのy座標
0073: static float render_cnt = 0;// 描画回数
0074: enum{
0075:     STATE_IDLE=0,           // 処理待ち
0076:     STATE_RENDER_BEGIN,     // 初期化
0077:     STATE_RENDER,           // 描画
0078:     STATE_RENDER_END,       // 後片付け
0079: };
0080: 
0081: OBJ_DATA sphere_data[] = {
0082: {// 小さいのに乗ってるほう
0083:     OBJ_TYPE_SPHERE,
0084:     {
0085:         {0.10f, 0.100f, 0.10f},
0086:         0.2f, 0.8f, 0.0f, 0.0f,
0087:     },{{0,0,0},{0,0,0},{0,0,0},},{
0088:         {125.5, 0+100,169},
0089: //      {185.5, 165+100,169},
0090:         100.0f,
0091:     }
0092: },{// 大きいのに乗ってるほう
0093:     OBJ_TYPE_SPHERE,
0094:     {
0095:         {0.05f, 0.050f, 0.05f},
0096:         0.80f, 0.00f, 0.20f, 0.0f,
0097:     },{{0,0,0},{0,0,0},{0,0,0},},{
0098:         {368.5, 330+100,351},
0099:         100.0f,
0100:     }
0101: }};
0102: OBJ_DATA room_data[14] = {
0103: {
0104: // ライト1
0105:     OBJ_TYPE_TRIANGLE,
0106:     {
0107:         {100.0f*1.00f, 100.0f*0.90f, 100.0f*0.50f},
0108:         0.0f, 0.0f, 0.0f, 1.0f,
0109:     },{
0110:         {213.0, 548.799f, 227.0},
0111:         {213.0, 548.799f, 332.0},
0112:         {343.0, 548.799f, 227.0},
0113:     }
0114: },{// ライト2
0115:     OBJ_TYPE_TRIANGLE,
0116:     {
0117:         {100.0f*1.00f, 100.0f*0.90f, 100.0f*0.50f},
0118:         0.0f, 0.0f, 0.0f, 1.0f,
0119:     },{
0120:         {343.0, 548.799f, 227.0},
0121:         {213.0, 548.799f, 332.0},
0122:         {343.0, 548.799f, 332.0},
0123:     }
0124: },{ // 左1
0125:     OBJ_TYPE_TRIANGLE,
0126:     {
0127:         {0.70f, 0.15f, 0.15f},
0128:         0.0f, 0.0f, 1.0f, 0.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.70f, 0.15f, 0.15f},
0139:         0.0f, 0.0f, 1.0f, 0.0f,
0140:     },{
0141:         {549.6f,   0.0f, 559.2f},
0142:         {556.0f, 548.8f,   0.0f},
0143:         {556.0f, 548.8f, 559.2f},
0144:     }
0145: 
0146: },{// 右1
0147:     OBJ_TYPE_TRIANGLE,
0148:     {
0149:         {0.15f, 0.15f, 0.70f},
0150:         0.0f, 0.0f, 1.0f, 0.0f,
0151:     },{
0152:         {0.0f,   0.0f,   0.0f},
0153:         {0.0f,   0.0f, 559.2f},
0154:         {0.0f, 548.8f,   0.0f},
0155:     }
0156: 
0157: },{// 右2
0158:     OBJ_TYPE_TRIANGLE,
0159:     {
0160:         {0.15f, 0.15f, 0.70f},
0161:         0.0f, 0.0f, 1.0f, 0.0f,
0162:     },{
0163:         {0.0f, 548.8f,   0.0f},
0164:         {0.0f,   0.0f, 559.2f},
0165:         {0.0f, 548.8f, 559.2f},
0166:     }
0167: 
0168: },{// 奥1
0169:     OBJ_TYPE_TRIANGLE,
0170:     {
0171:         {0.70f, 0.70f, 0.70f},
0172:         0.0f, 0.0f, 1.0f, 0.0f,
0173:     },{
0174:         {  0.0f,   0.0f, 559.2f},
0175:         {549.6f,   0.0f, 559.2f},
0176:         {  0.0f, 548.8f, 559.2f},
0177:     }
0178: 
0179: },{// 奥2
0180:     OBJ_TYPE_TRIANGLE,
0181:     {
0182:         {0.70f, 0.70f, 0.70f},
0183:         0.0f, 0.0f, 1.0f, 0.0f,
0184:     },{
0185:         {  0.0f, 548.8f, 559.2f},
0186:         {549.6f,   0.0f, 559.2f},
0187:         {556.0f, 548.8f, 559.2f},
0188:     }
0189: 
0190: },{// 天井1
0191:     OBJ_TYPE_TRIANGLE,
0192:     {
0193:         {0.70f, 0.70f, 0.70f},
0194:         0.0f, 0.0f, 1.0f, 0.0f,
0195:     },{
0196:         {  0.0f, 548.8f,   0.0f},
0197:         {  0.0f, 548.8f, 559.2f},
0198:         {556.0f, 548.8f,   0.0f},
0199:     }
0200: 
0201: },{// 天井2
0202:     OBJ_TYPE_TRIANGLE,
0203:     {
0204:         {0.70f, 0.70f, 0.70f},
0205:         0.0f, 0.0f, 1.0f, 0.0f,
0206:     },{
0207:         {  0.0f, 548.8f, 559.2f},
0208:         {556.0f, 548.8f, 559.2f},
0209:         {556.0f, 548.8f,   0.0f},
0210:     }
0211: 
0212: },{// 床1
0213:     OBJ_TYPE_TRIANGLE,
0214:     {
0215:         {0.70f, 0.70f, 0.70f},
0216:         0.0f, 0.0f, 1.0f, 0.0f,
0217:     },{
0218:         {  0.0f, 0.0f,   0.0f},
0219:         {552.8f, 0.0f,   0.0f},
0220:         {  0.0f, 0.0f, 559.2f},
0221:     }
0222: },{// 床1
0223:     OBJ_TYPE_TRIANGLE,
0224:     {
0225:         {0.70f, 0.70f, 0.70f},
0226:         0.0f, 0.0f, 1.0f, 0.0f,
0227:     },{
0228:         {  0.0f, 0.0f, 559.2f},
0229:         {552.8f, 0.0f,   0.0f},
0230:         {549.6f, 0.0f, 559.2f},
0231:     }
0232: },{// 手前1
0233:     OBJ_TYPE_TRIANGLE,
0234:     {
0235:         {0.70f, 0.70f, 0.70f},
0236:         0.0f, 0.0f, 1.0f, 0.0f,
0237:     },{
0238:         {  0.0f,   0.0f, 0.0f},
0239:         {  0.0f, 548.8f, 0.0f},
0240:         {549.6f,   0.0f, 0.0f},
0241:     }
0242: 
0243: },{// 手前2
0244:     OBJ_TYPE_TRIANGLE,
0245:     {
0246:         {0.70f, 0.70f, 0.70f},
0247:         0.0f, 0.0f, 1.0f, 0.0f,
0248:     },{
0249:         {  0.0f, 548.8f, 0.0f},
0250:         {556.0f, 548.8f, 0.0f},
0251:         {549.6f,   0.0f, 0.0f},
0252:     }
0253: 
0254: 
0255: }};
0256: 
0257: 
0258: OBJ_DATA Short_block[] = {
0259: {
0260:     // 床
0261:     OBJ_TYPE_TRIANGLE,
0262:     {
0263:         {0.70f, 0.70f, 0.70f},
0264:         0.0f, 0.0f, 1.0f, 0.0f,
0265:     },{
0266:         { 82.0f, 165.0f, 225.0f},
0267:         {130.0f, 165.0f,  65.0f},
0268:         {240.0f, 165.0f, 272.0f},
0269:     }
0270: },{
0271:     OBJ_TYPE_TRIANGLE,
0272:     {
0273:         {0.70f, 0.70f, 0.70f},
0274:         0.0f, 0.0f, 1.0f, 0.0f,
0275:     },{
0276:         {290.0, 165.0, 114.0},
0277:         {240.0, 165.0, 272.0},
0278:         {130.0, 165.0,  65.0},
0279:     }
0280: },{//側面
0281:     OBJ_TYPE_TRIANGLE,
0282:     {
0283:         {0.70f, 0.70f, 0.70f},
0284:         0.0f, 0.0f, 1.0f, 0.0f,
0285:     },{
0286:         {290.0, 165.0, 114.0},
0287:         {290.0,   0.0, 114.0},
0288:         {240.0, 165.0, 272.0},
0289:     }
0290: },{
0291:     OBJ_TYPE_TRIANGLE,
0292:     {
0293:         {0.70f, 0.70f, 0.70f},
0294:         0.0f, 0.0f, 1.0f, 0.0f,
0295:     },{
0296:         {240.0, 165.0, 272.0},
0297:         {290.0,   0.0, 114.0},
0298:         {240.0,   0.0, 272.0},
0299:     }
0300: },{//前面
0301:     OBJ_TYPE_TRIANGLE,
0302:     {
0303:         {0.70f, 0.70f, 0.70f},
0304:         0.0f, 0.0f, 1.0f, 0.0f,
0305:     },{
0306:         {290.0,   0.0, 114.0},
0307:         {290.0, 165.0, 114.0},
0308:         {130.0,   0.0,  65.0},
0309:     }
0310: },{
0311:     OBJ_TYPE_TRIANGLE,
0312:     {
0313:         {0.70f, 0.70f, 0.70f},
0314:         0.0f, 0.0f, 1.0f, 0.0f,
0315:     },{
0316:         {130.0,   0.0,  65.0},
0317:         {290.0, 165.0, 114.0},
0318:         {130.0, 165.0,  65.0},
0319:     }
0320: },{//側面
0321:     OBJ_TYPE_TRIANGLE,
0322:     {
0323:         {0.70f, 0.70f, 0.70f},
0324:         0.0f, 0.0f, 1.0f, 0.0f,
0325:     },{
0326:         { 82.0,   0.0, 225.0},
0327:         {130.0, 165.0,  65.0},
0328:         { 82.0, 165.0, 225.0},
0329:     }
0330: },{
0331:     OBJ_TYPE_TRIANGLE,
0332:     {
0333:         {0.70f, 0.70f, 0.70f},
0334:         0.0f, 0.0f, 1.0f, 0.0f,
0335:     },{
0336:         { 82.0,   0.0, 225.0},
0337:         {130.0,   0.0,  65.0},
0338:         {130.0, 165.0,  65.0},
0339:     }
0340: },{//背面
0341:     OBJ_TYPE_TRIANGLE,
0342:     {
0343:         {0.70f, 0.70f, 0.70f},
0344:         0.0f, 0.0f, 1.0f, 0.0f,
0345:     },{
0346:         {240.0,   0.0, 272.0},
0347:         { 82.0, 165.0, 225.0},
0348:         {240.0, 165.0, 272.0},
0349:     }
0350: },{
0351:     OBJ_TYPE_TRIANGLE,
0352:     {
0353:         {0.70f, 0.70f, 0.70f},
0354:         0.0f, 0.0f, 1.0f, 0.0f,
0355:     },{
0356:         {240.0,   0.0, 272.0},
0357:         { 82.0,   0.0, 225.0},
0358:         { 82.0, 165.0, 225.0},
0359:     }
0360: }};
0361: 
0362: OBJ_DATA Tall_block[] = {
0363: {
0364:     // 床
0365:     OBJ_TYPE_TRIANGLE,
0366:     {
0367:         {0.70f, 0.70f, 0.70f},
0368:         0.0f, 0.0f, 1.0f, 0.0f,
0369:     },{
0370:         {423.0f, 330.0f, 247.0f},
0371:         {314.0f, 330.0f, 456.0f},
0372:         {265.0f, 330.0f, 296.0f},
0373:     }
0374: },{
0375:     OBJ_TYPE_TRIANGLE,
0376:     {
0377:         {0.70f, 0.70f, 0.70f},
0378:         0.0f, 0.0f, 1.0f, 0.0f,
0379:     },{
0380:         {423.0f, 330.0f, 247.0f},
0381:         {472.0f, 330.0f, 406.0f},
0382:         {314.0f, 330.0f, 456.0f},
0383:     }
0384: },{//側面
0385:     OBJ_TYPE_TRIANGLE,
0386:     {
0387:         {0.70f, 0.70f, 0.70f},
0388:         0.0f, 0.0f, 1.0f, 0.0f,
0389:     },{
0390:         {423.0f,   0.0f, 247.0f},
0391:         {472.0f,   0.0f, 406.0f},
0392:         {423.0f, 330.0f, 247.0f},
0393:     }
0394: },{
0395:     OBJ_TYPE_TRIANGLE,
0396:     {
0397:         {0.70f, 0.70f, 0.70f},
0398:         0.0f, 0.0f, 1.0f, 0.0f,
0399:     },{
0400:         {423.0f, 330.0f, 247.0f},
0401:         {472.0f,   0.0f, 406.0f},
0402:         {472.0f, 330.0f, 406.0f},
0403:     }
0404: },{//背面
0405:     OBJ_TYPE_TRIANGLE,
0406:     {
0407:         {0.70f, 0.70f, 0.70f},
0408:         0.0f, 0.0f, 1.0f, 0.0f,
0409:     },{
0410:         {314.0f,   0.0f, 456.0f},
0411:         {314.0f, 330.0f, 456.0f},
0412:         {472.0f,   0.0f, 406.0f},
0413:     }
0414: },{
0415:     OBJ_TYPE_TRIANGLE,
0416:     {
0417:         {0.70f, 0.70f, 0.70f},
0418:         0.0f, 0.0f, 1.0f, 0.0f,
0419:     },{
0420:         {314.0f, 330.0f, 456.0f},
0421:         {472.0f, 330.0f, 406.0f},
0422:         {472.0f,   0.0f, 406.0f},
0423:     }
0424: },{//側面
0425:     OBJ_TYPE_TRIANGLE,
0426:     {
0427:         {0.70f, 0.70f, 0.70f},
0428:         0.0f, 0.0f, 1.0f, 0.0f,
0429:     },{
0430:         {314.0f,   0.0f, 456.0f},
0431:         {265.0f,   0.0f, 296.0f},
0432:         {265.0f, 330.0f, 296.0f},
0433:     }
0434: },{
0435:     OBJ_TYPE_TRIANGLE,
0436:     {
0437:         {0.70f, 0.70f, 0.70f},
0438:         0.0f, 0.0f, 1.0f, 0.0f,
0439:     },{
0440:         {314.0f,   0.0f, 456.0f},
0441:         {265.0f, 330.0f, 296.0f},
0442:         {314.0f, 330.0f, 456.0f},
0443:     }
0444: },{//前面
0445:     OBJ_TYPE_TRIANGLE,
0446:     {
0447:         {0.70f, 0.70f, 0.70f},
0448:         0.0f, 0.0f, 1.0f, 0.0f,
0449:     },{
0450:         {265.0f,   0.0f, 296.0f},
0451:         {423.0f,   0.0f, 247.0f},
0452:         {265.0f, 330.0f, 296.0f},
0453:     }
0454: },{
0455:     OBJ_TYPE_TRIANGLE,
0456:     {
0457:         {0.70f, 0.70f, 0.70f},
0458:         0.0f, 0.0f, 1.0f, 0.0f,
0459:     },{
0460:         {265.0f, 330.0f, 296.0f},
0461:         {423.0f,   0.0f, 247.0f},
0462:         {423.0f, 330.0f, 247.0f},
0463:     }
0464: }};
0465: 
0466: // ---------------------------------------------------------------------------
0467: // 関数宣言
0468: // ---------------------------------------------------------------------------
0469: D3DXVECTOR3 *GetColor(D3DXVECTOR3 *dest, float x, float y);
0470: 
0471: 
0472: // ---------------------------------------------------------------------------
0473: // カメラクラス
0474: // ---------------------------------------------------------------------------
0475: void CCamera::Update()
0476: {
0477:     // 正規直行基底の計算
0478:     D3DXVec3Subtract( &w, &m_vLookat, &m_vFrom );
0479:     D3DXVec3Cross( &v, &w, &m_vUp );
0480:     D3DXVec3Cross( &u, &v, &w );
0481:     D3DXVec3Normalize( &u, &u );
0482:     D3DXVec3Normalize( &v, &v );
0483:     D3DXVec3Normalize( &w, &w );
0484: 
0485:     // レンズの半径(f/2F)
0486:     m_fLensRadius = 0.5f * m_fFocalLength / m_fFNumber;
0487:     // フィルムまでの距離 Lf/(L-f)
0488:     m_fFilmDistance = m_fFocusDistance*m_fFocalLength/(m_fFocusDistance-m_fFocalLength);
0489: }
0490: // ---------------------------------------------------------------------------
0491: void CCamera::GetRay( D3DXVECTOR3 *o, D3DXVECTOR3 *dir, float x, float y)
0492: {
0493:     D3DXVECTOR3 ds, e;
0494:     D3DXVECTOR3 tmp, tmp1;
0495:     float z1 = frand();
0496:     float z2 = frand();
0497: 
0498:     float r = m_fLensRadius * sqrtf(z1);
0499:     float theta = 2.0f * D3DX_PI * z2;
0500:     
0501:     // レイを飛ばす位置
0502:     D3DXVec3Scale( &tmp, &v, cosf(theta) );
0503:     D3DXVec3Scale( &ds,  &u, cosf(theta) );
0504:     D3DXVec3Add( &ds, &ds, &tmp );
0505:     D3DXVec3Scale( &ds, &ds, r );
0506:     D3DXVec3Add( o, &ds, &m_vFrom );
0507: 
0508:     // レンズの中心からピントの当たる位置へのベクトル
0509:     D3DXVec3Scale( &e,    &w,   m_fFilmDistance );
0510:     D3DXVec3Scale( &tmp,  &v,   m_fFilmSize[0] * (x-0.5f) );
0511:     D3DXVec3Scale( &tmp1, &u, - m_fFilmSize[1] * (y-0.5f) );
0512:     D3DXVec3Add( &e, &e, &tmp );
0513:     D3DXVec3Add( &e, &e, &tmp1 );
0514:     D3DXVec3Normalize( &e, &e );
0515: 
0516:     D3DXVec3Scale( dir, &e, m_fFocusDistance / D3DXVec3Dot( &e, &w ) );
0517:     D3DXVec3Subtract( dir, dir, &ds );
0518:     D3DXVec3Normalize( dir, dir );
0519: }
0520: 
0521: 
0522: 
0523: // ---------------------------------------------------------------------------
0524: char *GetDataPointer()
0525: {
0526:     return s_data;
0527: }
0528: // ---------------------------------------------------------------------------
0529: int GetRenderCount()
0530: {
0531:     return (int)(render_cnt+0.5f);
0532: }
0533: // ---------------------------------------------------------------------------
0534: void Init()
0535: {
0536:     int i, j;
0537: 
0538:     camera.SetFrom  (&D3DXVECTOR3(278,273,-800));
0539:     camera.SetLookAt(&D3DXVECTOR3(278,273,0));
0540:     camera.SetUp    (&D3DXVECTOR3(0,1,0));
0541:     camera.SetFilmSize      ( ASPECT*25, 25 );
0542:     camera.SetFocalLength   ( 35 );
0543:     camera.SetFNumber       ( 0.14f  );
0544:     camera.SetFocusDistance ( 1200.0 );
0545:     camera.Update();
0546:     
0547:     g_pRand = new CRand();
0548: 
0549:     pRoom = new CMesh();
0550:     pRoom->Init( room_data, 14 );
0551:     
0552:     pBlockSmall = new CMesh();
0553:     pBlockSmall->Init( Short_block, 10);
0554: 
0555:     pBlockTall = new CMesh();
0556:     pBlockTall->Init( Tall_block, 10);
0557:     
0558:     pShpereS = new CMesh();
0559:     pShpereS->Init( sphere_data, 1);
0560:     
0561:     pShpereT = new CMesh();
0562:     pShpereT->Init( sphere_data+1,1);
0563: 
0564:     render_cnt = 0; // レンダリング回数
0565:     // フレームバッファの初期化
0566:     for(j=0; j<RENDER_HEIGHT; j++){
0567:     for(i=0; i<RENDER_WIDTH ; i++){
0568:         s_data [4*(j*RENDER_WIDTH+i)+0]=(char)255;// R
0569:         s_data [4*(j*RENDER_WIDTH+i)+1]=(char)(i*256/RENDER_WIDTH );// G
0570:         s_data [4*(j*RENDER_WIDTH+i)+2]=(char)(j*256/RENDER_HEIGHT);// B
0571:         s_total[4*(j*RENDER_WIDTH+i)+0]=0;// R
0572:         s_total[4*(j*RENDER_WIDTH+i)+1]=0;// G
0573:         s_total[4*(j*RENDER_WIDTH+i)+2]=0;// B
0574:     }
0575:     }
0576: }
0577: // ---------------------------------------------------------------------------
0578: void Delete()
0579: {
0580:     if(pShpereT){delete pShpereT;pShpereT=NULL;}
0581:     if(pShpereS){delete pShpereS;pShpereS=NULL;}
0582:     if(pBlockTall){delete pBlockTall;pBlockTall=NULL;}
0583:     if(pBlockSmall){delete pBlockSmall;pBlockSmall=NULL;}
0584:     if(pRoom){delete pRoom; pRoom=NULL;}
0585:     if(g_pRand){delete g_pRand; g_pRand=NULL;}
0586: }
0587: // ---------------------------------------------------------------------------
0588: 
0589: #define BLOCK_X 2
0590: #define BLOCK_Y 2
0591: 
0592: // ---------------------------------------------------------------------------
0593: unsigned int WINAPI RayTrace ( LPVOID pParam )
0594: {
0595:     rect *pRect = (rect *)pParam;
0596:     D3DXVECTOR3 col;
0597:     
0598: for(int i=0;i<10;i++)
0599:     for( s32 y = pRect->top; y < pRect->bottom; y++ )
0600:     {
0601:         for( s32 x = pRect->left; x < pRect->right; x++ )
0602:         {
0603:             GetColor(&col, ((float)x+0.5f)/(float)RENDER_WIDTH
0604:                          , ((float)y+0.5f)/(float)RENDER_HEIGHT);
0605:             int no = 4*(y*RENDER_WIDTH+x);
0606:             s_total[no+0]+=col.x;// R
0607:             s_total[no+1]+=col.y;// G
0608:             s_total[no+2]+=col.z;// B
0609:         }
0610:     }
0611: 
0612:     return 0;
0613: }
0614: 
0615: 
0616: // ---------------------------------------------------------------------------
0617: int Render()
0618: {
0619:     int k,no;
0620:     static unsigned int save_bit = 0;
0621: 
0622:     render_cnt+=10.0f;
0623: 
0624:     static rect r[BLOCK_Y][BLOCK_X];
0625:     HANDLE  hThread[BLOCK_Y][BLOCK_X];
0626:     unsigned int  dummy;
0627:     
0628:     for( s32 i = 0; i < BLOCK_Y; i++ )
0629:     {
0630:         for( s32 j = 0; j < BLOCK_X; j++ )
0631:         {
0632:             r[i][j].left   = (j+0)*RENDER_WIDTH /BLOCK_X;
0633:             r[i][j].right  = (j+1)*RENDER_WIDTH /BLOCK_X;
0634:             r[i][j].top    = (i+0)*RENDER_HEIGHT/BLOCK_Y;
0635:             r[i][j].bottom = (i+1)*RENDER_HEIGHT/BLOCK_Y;
0636:         }
0637:     }
0638:     
0639:     bool bFinished[BLOCK_Y][BLOCK_X]; // 終わった?
0640:     
0641:     // 終了フラグ
0642:     for( s32 i = 0; i < BLOCK_Y; i++ )
0643:         for( s32 j = 0; j < BLOCK_X; j++ )
0644:             bFinished[i][j] = false;
0645:     
0646:     for( u32 n = BLOCK_X * BLOCK_Y; 0 < n; )
0647:     {
0648:         // スレッドを生成する
0649:         for( s32 i = 0; i < BLOCK_Y; i++ )
0650:         {
0651:             for( s32 j = 0; j < BLOCK_X; j++ )
0652:             {
0653:                 if( !bFinished[i][j] )
0654:                 {
0655:                     hThread[i][j] = (HANDLE)_beginthreadex( NULL, 0, &RayTrace, (LPVOID)&r[i][j], 0, &dummy );
0656:                 }
0657:                 if(0==hThread[i][j])
0658:                 {
0659:                     hThread[i][j]=0;
0660:                 }
0661:             }
0662:         }
0663:         
0664:         // スレッドを待つ
0665:         for( s32 i = 0; i < BLOCK_Y; i++ )
0666:         {
0667:             for( s32 j = 0; j < BLOCK_X; j++ )
0668:             {
0669:                 if( !bFinished[i][j] && 0 != hThread[i][j] )
0670:                 {
0671:                     WaitForSingleObject( hThread[i][j], INFINITE );  // 受信スレッド終了待ち
0672:                     CloseHandle( hThread[i][j] );                    // ハンドルを閉じる
0673:                     bFinished[i][j] = true;
0674:                     n--;
0675:                 }
0676:             }
0677:         }
0678:     }
0679: 
0680:     // 画面の反映
0681:     no = 0;
0682:     for(s32 j=0; j<RENDER_HEIGHT; j++){
0683:     for(s32 i=0; i<RENDER_WIDTH ; i++){
0684:         s_data [no+0]=(unsigned char)(255.9*min(1,s_total[no+0]/render_cnt));// R
0685:         s_data [no+1]=(unsigned char)(255.9*min(1,s_total[no+1]/render_cnt));// G
0686:         s_data [no+2]=(unsigned char)(255.9*min(1,s_total[no+2]/render_cnt));// B
0687:         no += 4;
0688:     }
0689:     }
0690: 
0691:     // 適当なときに画像を保存する
0692:     if( (1<<save_bit) <= GetRenderCount() )
0693:     {
0694:         // ファイル名を決める
0695:         _TCHAR buf[256];
0696:         _stprintf( buf, _T("%d.bmp"), GetRenderCount());
0697:         
0698:         // ビットマップイメージを作る
0699:         BYTE *pImage = new BYTE[3 * RENDER_WIDTH * RENDER_HEIGHT];
0700:         k = 0;
0701:         for(s32 j=0; j<RENDER_HEIGHT; j++)
0702:         {
0703:             no = 4*RENDER_WIDTH*(RENDER_HEIGHT-j-1);
0704:             for(s32 i=0; i<RENDER_WIDTH ; i++)
0705:             {
0706:                 pImage[k+0] = s_data [no+2];
0707:                 pImage[k+1] = s_data [no+1];
0708:                 pImage[k+2] = s_data [no+0];
0709:                 no += 4;
0710:                 k += 3;
0711:             }
0712:         }
0713: 
0714:         // ビットマップに必要な情報を格納する
0715:         SAVE_BITMAP tBitmap_Info;
0716:         tBitmap_Info.pFileName = buf;
0717:         tBitmap_Info.iWidth  = RENDER_WIDTH;
0718:         tBitmap_Info.iHeight = RENDER_HEIGHT;
0719:         tBitmap_Info.iBitCount = 24;
0720:         tBitmap_Info.pData = (BYTE*)pImage;
0721: 
0722:         SaveBitMap( tBitmap_Info );
0723: 
0724:         delete[] pImage;
0725: 
0726:         save_bit++;
0727:     }
0728: 
0729:     return 0;
0730: }
0731: 
0732: // ---------------------------------------------------------------------------
0733: bool GetColor(D3DXVECTOR3 *dest, const D3DXVECTOR4 *x, const D3DXVECTOR4 *v, int depth)
0734: {
0735:     D3DXVECTOR3 diffuse_color=D3DXVECTOR3(0,0,0);
0736: 
0737:     // -----------------------------------------------------------------------
0738:     // 初期化:光が屈折、反射しかしないで延々と跳ね返ったときは、光が届かない黒色
0739:     // -----------------------------------------------------------------------
0740:     if(0==depth) *dest = D3DXVECTOR3(0,0,0);
0741: 
0742:     // -----------------------------------------------------------------------
0743:     // 再帰しすぎた場合は光が届いていないものと考える
0744:     // -----------------------------------------------------------------------
0745:     const int DEPTH_MAX = 3;
0746:     if(DEPTH_MAX <= depth) { *dest=D3DXVECTOR3(0,0,0); return FALSE;}
0747: 
0748:     // -----------------------------------------------------------------------
0749:     // 視線から交点を求める
0750:     // -----------------------------------------------------------------------
0751:     float t = CPrimitive::INFINTY_DIST;
0752:     CPrimitive *pObj = NULL;
0753:     D3DXVECTOR4 p, n;// 交点の位置と法線
0754: 
0755:     t = pShpereS   ->IsAcross(t, &n, &p, &pObj, x, v);
0756:     t = pShpereT   ->IsAcross(t, &n, &p, &pObj, x, v);
0757:     t = pRoom      ->IsAcross(t, &n, &p, &pObj, x, v);
0758: //  t = pBlockSmall->IsAcross(t, &n, &p, &pObj, x, v);
0759:     t = pBlockTall ->IsAcross(t, &n, &p, &pObj, x, v);
0760: 
0761:     if( NULL == pObj ){
0762:         // 視線はオブジェクトから外れた!
0763:         *dest = BG_COLOR;
0764:         return TRUE;
0765:     }
0766: 
0767:     // -----------------------------------------------------------------------
0768:     // 反射方向をロシアンルーレットで決める
0769:     // -----------------------------------------------------------------------
0770:     float cd = pObj->m_material.diffuse;    // 拡散率
0771:     float cr = pObj->m_material.reflection; // 反射率
0772:     float cn = pObj->m_material.refraction; // 屈折率
0773:     float ce = pObj->m_material.emmisive;   // 放射率
0774:     float total = cd+cr+cn+ce;
0775:     float prob = total * (float)frand();
0776: 
0777:     int type = 0;// 拡散
0778:     if(prob < cr      ) type = 1; else// 反射
0779:     if(prob < cr+cn   ) type = 2; else// 屈折
0780:     if(prob < cr+cn+ce) type = 3;     // 放射
0781: 
0782:     // -----------------------------------------------------------------------
0783:     // 交点が、影に隠れているかどうか調べて、拡散光を算出する
0784:     // -----------------------------------------------------------------------
0785:     if(0==type){
0786:         if(++depth<DEPTH_MAX){
0787:             // さらに奥を検索
0788:             D3DXVECTOR4 dir, pos;
0789:             
0790:             // 等方的にレイを飛ばす
0791:             float theta =      D3DX_PI * (float)frand();
0792:             float phi   = 2.0f*D3DX_PI * (float)frand();
0793:             dir.x = sinf(theta) * cosf(phi);
0794:             dir.y = sinf(theta) * sinf(phi);
0795:             dir.z = cosf(theta);
0796:             float dn = D3DXVec3Dot((D3DXVECTOR3 *)&dir, (D3DXVECTOR3 *)&n);
0797:             if(dn<0){
0798:                 // 法線と反対向きに飛ぶつもりなら、方向を反対にする
0799:                 dn = -dn;
0800:                 dir.x *= -1;
0801:                 dir.y *= -1;
0802:                 dir.z *= -1;
0803:             }
0804: 
0805:             pos = p + 0.01f*(dir);
0806:             GetColor(&diffuse_color, &pos, &dir, depth);
0807:             // プリミティブの色や拡散光の余弦側を適用
0808:             diffuse_color.x *= pObj->m_material.COLOR_DIF[0] * dn * 0.5f*D3DX_PI;
0809:             diffuse_color.y *= pObj->m_material.COLOR_DIF[1] * dn * 0.5f*D3DX_PI;
0810:             diffuse_color.z *= pObj->m_material.COLOR_DIF[2] * dn * 0.5f*D3DX_PI;
0811:         }
0812:     }
0813: 
0814:     // -----------------------------------------------------------------------
0815:     // 再帰的に光線を飛ばして、より高次の反射を考慮に入れる
0816:     // -----------------------------------------------------------------------
0817:     // 反射
0818:     D3DXVECTOR3 reflect_color=D3DXVECTOR3(0,0,0);
0819:     if(1==type){
0820:         // 反射ベクトル
0821:         D3DXVECTOR4 r = *v - 2.0f*D3DXVec3Dot((D3DXVECTOR3 *)&n, (D3DXVECTOR3 *)v) * n;
0822:         D3DXVECTOR4 pos = p + 0.01f*n;// ちょっと浮かす
0823:         if(!GetColor( &reflect_color, &pos, &r, depth)){
0824:             cr = 0;// 結局、光が届かなかった
0825:         }
0826:     }
0827: 
0828:     // -----------------------------------------------------------------------
0829:     // 屈折
0830:     // -----------------------------------------------------------------------
0831:     D3DXVECTOR3 refract_color=D3DXVECTOR3(0,0,0);
0832:     if(2==type){
0833:         // 屈折ベクトル
0834:         D3DXVECTOR4 t, pos;
0835:         float VN = D3DXVec3Dot((D3DXVECTOR3 *)v, (D3DXVECTOR3 *)&n);
0836:         float eta = 1.5f;
0837:         if(VN<0){
0838:             // 入射
0839:             float D = 1-(1+VN)*(1+VN)/(eta*eta);
0840:             if(D<0){cn=0;goto no_refract;}// 全反射
0841:             t = (-VN/eta-sqrtf(D))*n+(1/eta)*(*v);
0842:             pos = p - 0.01f*n;// ちょっと浮かす
0843:         }else{
0844:             // 出て行く
0845:             float D = 1-(1-VN)*(1-VN)*(eta*eta);
0846:             if(D<0){cn=0;goto no_refract;}// 全反射
0847:             t = -(VN*eta-sqrtf(D))*n+eta*(*v);
0848:             pos = p + 0.01f*n;// ちょっと浮かす
0849:         }
0850:         D3DXVec3Normalize( (D3DXVECTOR3 *)&t, (D3DXVECTOR3 *)&t );
0851:         if(!GetColor( &refract_color, &pos, &t, depth)){
0852:             cn = 0;// 結局、光が届かなかった
0853:         }
0854:     }
0855: no_refract:
0856: 
0857:     // -----------------------------------------------------------------------
0858:     // 放射
0859:     // -----------------------------------------------------------------------
0860:     D3DXVECTOR3 emmisive_color = *(D3DXVECTOR3*)&pObj->m_material.COLOR_DIF;
0861: 
0862:     // -----------------------------------------------------------------------
0863:     // 色を出力する
0864:     // -----------------------------------------------------------------------
0865:     switch(type){
0866:     case 0:// 拡散
0867:         *dest = (cd+cr+cn) * diffuse_color;
0868:         break;
0869:     case 1:// 反射
0870:         *dest = (cd+cr+cn) * reflect_color;     
0871:         break;
0872:     case 2:// 屈折
0873:         *dest = (cd+cr+cn) * refract_color;
0874:         break;
0875:     case 3:// 放射
0876:         *dest = ce * emmisive_color;
0877:         break;
0878:     }
0879: 
0880:     return TRUE;
0881: }
0882: // ---------------------------------------------------------------------------
0883: D3DXVECTOR3 *GetColor(D3DXVECTOR3 *dest, float x, float y)
0884: {
0885:     D3DXVECTOR4 ray_start;
0886:     D3DXVECTOR4 ray_dir;
0887:     
0888:     ray_start.w = 1.0f;
0889:     ray_dir.w   = 0.0f;
0890: 
0891:     camera.GetRay( (D3DXVECTOR3*)&ray_start, (D3DXVECTOR3*)&ray_dir, x, y);
0892:     
0893:     GetColor(dest, &ray_start, &ray_dir, 0);
0894: 
0895:     return dest;
0896: }
0897: 
0898: };// namespace Render
0899: