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];
0031: float m_fFocalLength;
0032: float m_fFNumber;
0033: float m_fFocusDistance;
0034:
0035: float m_fLensRadius;
0036: float m_fFilmDistance;
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;
0072: static int s_y = 0;
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:
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:
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: },{
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: },{
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: },{
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: },{
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: },{
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: },{
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: },{
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: },{
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: },{
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: },{
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: },{
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: },{
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: },{
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:
0486: m_fLensRadius = 0.5f * m_fFocalLength / m_fFNumber;
0487:
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;
0569: s_data [4*(j*RENDER_WIDTH+i)+1]=(char)(i*256/RENDER_WIDTH );
0570: s_data [4*(j*RENDER_WIDTH+i)+2]=(char)(j*256/RENDER_HEIGHT);
0571: s_total[4*(j*RENDER_WIDTH+i)+0]=0;
0572: s_total[4*(j*RENDER_WIDTH+i)+1]=0;
0573: s_total[4*(j*RENDER_WIDTH+i)+2]=0;
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;
0607: s_total[no+1]+=col.y;
0608: s_total[no+2]+=col.z;
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));
0685: s_data [no+1]=(unsigned char)(255.9*min(1,s_total[no+1]/render_cnt));
0686: s_data [no+2]=(unsigned char)(255.9*min(1,s_total[no+2]/render_cnt));
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:
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: };
0899: