0001: #include "stdafx.h"
0002: #include <d3d9.h>
0003: #include <d3dx9.h>
0004: #include "math.h"
0005: #include "render.h"
0006: 
0007: namespace Render {
0008: 
0009: D3DXVECTOR3 BG_COLOR = D3DXVECTOR3(0.25f, 0.4f, 0.5f);// 背景色
0010: 
0011: class CCamera
0012: {
0013: private:
0014:     D3DXMATRIX  m_mView;
0015:     D3DXMATRIX  m_mProj;
0016:     D3DXMATRIX  m_mVP;
0017:     D3DXMATRIX  m_mVP_Inv;
0018:     D3DXMATRIX  m_mView_Inv;
0019: 
0020:     D3DXVECTOR3 m_vFrom;
0021:     D3DXVECTOR3 m_vLookat;
0022:     D3DXVECTOR3 m_vUp;
0023: 
0024:     float   m_fFovy;
0025:     float   m_fAspect;
0026:     float   m_fNear;
0027:     float   m_fFar;
0028: 
0029: public:
0030: 
0031:     void Update();
0032:     void SetFrom  (const D3DXVECTOR3 *p){m_vFrom  =*p;}
0033:     void SetLookAt(const D3DXVECTOR3 *p){m_vLookat=*p;}
0034:     void SetUp    (const D3DXVECTOR3 *p){m_vUp    =*p;}
0035:     void SetFovY  (float val){m_fFovy   = val;}
0036:     void SetAspect(float val){m_fAspect = val;}
0037:     void SetNear  (float val){m_fNear   = val;}
0038:     void SetFar   (float val){m_fFar    = val;}
0039: 
0040:     inline const D3DXMATRIX *GetViewInverse() const {return &m_mView_Inv;}
0041:     inline const D3DXMATRIX *GetViewProjInverse() const {return &m_mVP_Inv;}
0042: };
0043: 
0044: // ---------------------------------------------------------------------------
0045: // オブジェクト
0046: // ---------------------------------------------------------------------------
0047: char s_data[4*RENDER_WIDTH*RENDER_HEIGHT];// 仮想フレームバッファ
0048: CCamera camera;
0049: 
0050: // ---------------------------------------------------------------------------
0051: // 関数宣言
0052: // ---------------------------------------------------------------------------
0053: D3DXVECTOR3 *GetColor(D3DXVECTOR3 *dest, float x, float y);
0054: 
0055: 
0056: // ---------------------------------------------------------------------------
0057: // カメラクラス
0058: // ---------------------------------------------------------------------------
0059: void CCamera::Update()
0060: {
0061:     D3DXMatrixLookAtLH( &m_mView, &m_vFrom, &m_vLookat, &m_vUp );
0062:     D3DXMatrixPerspectiveFovLH( &m_mProj, m_fFovy, m_fAspect, m_fNear, m_fFar );
0063:     m_mVP = m_mView * m_mProj;
0064: 
0065:     D3DXMatrixInverse( &m_mView_Inv, NULL, &m_mView);
0066:     D3DXMatrixInverse( &m_mVP_Inv, NULL, &m_mVP);
0067: }
0068: // ---------------------------------------------------------------------------
0069: char *GetDataPointer()
0070: {
0071:     return s_data;
0072: }
0073: // ---------------------------------------------------------------------------
0074: void Init()
0075: {
0076:     // フレームバッファの初期化
0077:     for(int j=0;j<RENDER_HEIGHT;j++){
0078:     for(int i=0;i<RENDER_WIDTH ;i++){
0079:         s_data[4*(j*RENDER_WIDTH+i)+0]=(char)255;// R
0080:         s_data[4*(j*RENDER_WIDTH+i)+1]=(char)(i*256/RENDER_WIDTH );// G
0081:         s_data[4*(j*RENDER_WIDTH+i)+2]=(char)(j*256/RENDER_HEIGHT);// B
0082:     }
0083:     }
0084:     
0085:     camera.SetFrom  (&D3DXVECTOR3(0,0,3));
0086:     camera.SetLookAt(&D3DXVECTOR3(0,0,0));
0087:     camera.SetUp    (&D3DXVECTOR3(0,1,0));
0088:     camera.SetFovY  (D3DX_PI/3);
0089:     camera.SetAspect(1.0f);
0090:     camera.SetNear  (0.01f);
0091:     camera.SetFar   (100.0f);
0092:     camera.Update();
0093: }
0094: // ---------------------------------------------------------------------------
0095: void Delete()
0096: {
0097: }
0098: // ---------------------------------------------------------------------------
0099: void Render()
0100: {
0101:     for(int j=0;j<RENDER_HEIGHT;j++){
0102:     for(int i=0;i<RENDER_WIDTH ;i++){
0103:         D3DXVECTOR3 col;
0104:         GetColor(&col, ((float)i+0.5f)/(float)RENDER_WIDTH
0105:                      , ((float)j+0.5f)/(float)RENDER_HEIGHT);
0106:         // 0~1の範囲の色を0~255に変換
0107:         s_data[4*(j*RENDER_WIDTH+i)+0]=(char)(255.9*col.x);// R
0108:         s_data[4*(j*RENDER_WIDTH+i)+1]=(char)(255.9*col.y);// G
0109:         s_data[4*(j*RENDER_WIDTH+i)+2]=(char)(255.9*col.z);// B
0110:     }
0111:     }
0112: }
0113: 
0114: // ---------------------------------------------------------------------------
0115: D3DXVECTOR3 *GetColor(D3DXVECTOR3 *dest, D3DXVECTOR4 *x, D3DXVECTOR4 *v)
0116: {
0117:     D3DXVECTOR4 d0, d1;
0118:     D3DXVECTOR3 c;
0119:     D3DXVECTOR4 normal;
0120: 
0121:     // 3角形の各頂点
0122:     D3DXVECTOR4 pos[3] = {
0123:         D3DXVECTOR4( 0.000f, 0.866f, 0.0f, 1),
0124:         D3DXVECTOR4( 0.866f,-0.500f, 0.0f, 1),
0125:         D3DXVECTOR4(-0.866f,-0.500f, 0.0f, 1),
0126:     };
0127: 
0128:     *dest = BG_COLOR;   // 外れたときの色
0129: 
0130:     // 法線ベクトルの計算
0131:     D3DXVECTOR4 t0 = pos[1]-pos[0];
0132:     D3DXVECTOR4 t1 = pos[2]-pos[0];
0133:     D3DXVec3Cross((D3DXVECTOR3*)&normal, (D3DXVECTOR3*)&t1, (D3DXVECTOR3*)&t0);
0134:     D3DXVec3Normalize((D3DXVECTOR3*)&normal, (D3DXVECTOR3*)&normal);
0135: 
0136: 
0137:     // 線分との判定
0138:     D3DXVECTOR4 xp = pos[0]-(*x);
0139:     FLOAT xpn = D3DXVec3Dot((D3DXVECTOR3 *)&xp, (D3DXVECTOR3 *)&normal);
0140:     FLOAT vn  = D3DXVec3Dot((D3DXVECTOR3 *)v,   (D3DXVECTOR3 *)&normal);
0141:     
0142:     if(-0.00001f<=vn) return dest;// カリングと発散を外す
0143: 
0144:     float t = xpn/vn;
0145:     
0146:     if(t<0) return dest;// 後ろ向きのレイは無効
0147: 
0148:     D3DXVECTOR4 p = (*x)+t*(*v);// 3角形の平面への射影
0149: 
0150:     // 射影した点が3角形の内側にあるかテスト
0151:     d0 = p-pos[0];
0152:     d1 = pos[1]-pos[0];
0153:     D3DXVec3Cross(&c, (D3DXVECTOR3*)&d0, (D3DXVECTOR3*)&d1);
0154:     if(D3DXVec3Dot(&c, (D3DXVECTOR3 *)&normal)<0) return dest;
0155:     d0 = p-pos[1];
0156:     d1 = pos[2]-pos[1];
0157:     D3DXVec3Cross(&c, (D3DXVECTOR3*)&d0, (D3DXVECTOR3*)&d1);
0158:     if(D3DXVec3Dot(&c, (D3DXVECTOR3 *)&normal)<0) return dest;
0159:     d0 = p-pos[2];
0160:     d1 = pos[0]-pos[2];
0161:     D3DXVec3Cross(&c, (D3DXVECTOR3*)&d0, (D3DXVECTOR3*)&d1);
0162:     if(D3DXVec3Dot(&c, (D3DXVECTOR3 *)&normal)<0) return dest;
0163:     
0164:     // 当たったときの色
0165:     *dest = D3DXVECTOR3( 1.0f, 0.9f, 0.5f );
0166:     
0167:     return dest;
0168: }
0169: // ---------------------------------------------------------------------------
0170: D3DXVECTOR3 *GetColor(D3DXVECTOR3 *dest, float x, float y)
0171: {
0172:     D3DXVECTOR4 ray_start_proj = D3DXVECTOR4(-2*x+1, -2*y+1, 0, 1);// 前方クリップ面
0173:     D3DXVECTOR4 ray_eye        = D3DXVECTOR4(0, 0, 0, 1);// ビュー空間でのカメラの位置
0174:     D3DXVECTOR4 ray_start;
0175:     D3DXVECTOR4 ray_to;
0176:     D3DXVECTOR4 ray_dir;
0177:     D3DXMATRIX mInv;
0178:     
0179:     // 視点を射影空間からワールド座標に変換する
0180:     D3DXVec4Transform( &ray_start, &ray_eye,        camera.GetViewInverse() );
0181:     D3DXVec4Transform( &ray_to,    &ray_start_proj, camera.GetViewProjInverse() );
0182:     D3DXVec4Scale( &ray_to,    &ray_to,    1.0f/ray_to.w   );// w=1 の射影空間に落とす
0183:     // 向きの計算
0184:     ray_dir = ray_to - ray_start;
0185:     D3DXVec4Normalize(&ray_dir, &ray_dir);
0186:     
0187:     // 色計算
0188:     return GetColor(dest, &ray_start, &ray_dir);
0189: }
0190: 
0191: };// namespace Render
0192: