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: 
D0009: 3DXVECTOR3 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:     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:     inline const D3DXMATRIX *GetViewInverse() const {return &m_mView_Inv;}
0039:     inline const D3DXMATRIX *GetViewProjInverse() const {return &m_mVP_Inv;}
0040: };
0041: 
0042: // ---------------------------------------------------------------------------
0043: // オブジェクト
0044: // ---------------------------------------------------------------------------
0045: char s_data[4*RENDER_WIDTH*RENDER_HEIGHT];// 仮想フレームバッファ
0046: CCamera camera;
0047: 
0048: // ---------------------------------------------------------------------------
0049: // 関数宣言
0050: // ---------------------------------------------------------------------------
0051: D3DXVECTOR3 *GetColor(D3DXVECTOR3 *dest, float x, float y);
0052: 
0053: 
0054: // ---------------------------------------------------------------------------
0055: // カメラクラス
0056: // ---------------------------------------------------------------------------
0057: void CCamera::Update()
0058: {
0059:     D3DXMatrixLookAtLH( &m_mView, &m_vFrom, &m_vLookat, &m_vUp );
0060:     D3DXMatrixPerspectiveFovLH( &m_mProj, m_fFovy, m_fAspect, m_fNear, m_fFar );
0061:     m_mVP = m_mView * m_mProj;
0062:     D3DXMatrixInverse( &m_mView_Inv, NULL, &m_mView);
0063:     D3DXMatrixInverse( &m_mVP_Inv, NULL, &m_mVP);
0064: }
0065: // ---------------------------------------------------------------------------
0066: char *GetDataPointer()
0067: {
0068:     return s_data;
0069: }
0070: // ---------------------------------------------------------------------------
0071: void Init()
0072: {
0073:     // フレームバッファの初期化
0074:     for(int j=0;j<RENDER_HEIGHT;j++){
0075:     for(int i=0;i<RENDER_WIDTH ;i++){
0076:         s_data[4*(j*RENDER_WIDTH+i)+0]=(char)255;// R
0077:         s_data[4*(j*RENDER_WIDTH+i)+1]=(char)(i*256/RENDER_WIDTH );// G
0078:         s_data[4*(j*RENDER_WIDTH+i)+2]=(char)(j*256/RENDER_HEIGHT);// B
0079:     }
0080:     }
0081:     
0082:     camera.SetFrom  (&D3DXVECTOR3(0,1,5));
0083:     camera.SetLookAt(&D3DXVECTOR3(0,1,0));
0084:     camera.SetUp    (&D3DXVECTOR3(0,1,0));
0085:     camera.SetFovY  (D3DX_PI/3);
0086:     camera.SetAspect(1.0f);
0087:     camera.SetNear  (0.01f);
0088:     camera.SetFar   (100.0f);
0089:     camera.Update();
0090: }
0091: // ---------------------------------------------------------------------------
0092: void Delete()
0093: {
0094: }
0095: // ---------------------------------------------------------------------------
0096: void Render()
0097: {
0098:     for(int j=0;j<RENDER_HEIGHT;j++){
0099:     for(int i=0;i<RENDER_WIDTH ;i++){
0100:         D3DXVECTOR3 col;
0101:         GetColor(&col, ((float)i+0.5f)/(float)RENDER_WIDTH
0102:                      , ((float)j+0.5f)/(float)RENDER_HEIGHT);
0103:         // 0~1の範囲の色を0~255に変換
0104:         s_data[4*(j*RENDER_WIDTH+i)+0]=(char)(255.9*col.x);// R
0105:         s_data[4*(j*RENDER_WIDTH+i)+1]=(char)(255.9*col.y);// G
0106:         s_data[4*(j*RENDER_WIDTH+i)+2]=(char)(255.9*col.z);// B
0107:     }
0108:     }
0109: }
0110: 
0111: // ---------------------------------------------------------------------------
0112: D3DXVECTOR3 *GetColor(D3DXVECTOR3 *dest, D3DXVECTOR4 *x, D3DXVECTOR4 *v)
0113: {
0114:     // 線分と球の判定
0115:     D3DXVECTOR4 center = D3DXVECTOR4(0,1,0,1);          // 中心位置
0116:     FLOAT radius_sq = 1.0f*1.0f;
0117: 
0118:     D3DXVECTOR4 xc = (*x)-center;// 中心からの相対位置
0119:     FLOAT xc2 = D3DXVec3Dot((D3DXVECTOR3 *)&xc, (D3DXVECTOR3 *)&xc);
0120:     FLOAT vxc = D3DXVec3Dot((D3DXVECTOR3 *)v, (D3DXVECTOR3 *)&xc);
0121:     FLOAT D = vxc*vxc-xc2+radius_sq;// 判別式
0122:     
0123:     *dest = D3DXVECTOR3(1,0.9,0.5); // 当たったときの色
0124: 
0125:     if(D<0) {*dest = BG_COLOR; return dest;} // 交点が存在しない外れた
0126:     
0127:     float tn = -vxc-sqrtf(D);
0128:     float tp = -vxc+sqrtf(D);
0129: 
0130:     if(tn<0 && tp<0) {*dest = BG_COLOR; return dest;}
0131: 
0132:     return dest;
0133: }
0134: // ---------------------------------------------------------------------------
0135: D3DXVECTOR3 *GetColor(D3DXVECTOR3 *dest, float x, float y)
0136: {
0137:     D3DXVECTOR4 ray_start_proj = D3DXVECTOR4(-2*x+1, -2*y+1, 0, 1);// 前方クリップ面
0138:     D3DXVECTOR4 ray_eye        = D3DXVECTOR4(0, 0, 0, 1);// ビュー空間でのカメラの位置
0139:     D3DXVECTOR4 ray_start;
0140:     D3DXVECTOR4 ray_to;
0141:     D3DXVECTOR4 ray_dir;
0142:     D3DXMATRIX mInv;
0143:     
0144:     // 視点を射影空間からワールド座標に変換する
0145:     D3DXVec4Transform( &ray_start, &ray_eye,        camera.GetViewInverse() );
0146:     D3DXVec4Transform( &ray_to,    &ray_start_proj, camera.GetViewProjInverse() );
0147:     D3DXVec4Scale( &ray_to,    &ray_to,    1.0f/ray_to.w   );// w=1 の射影空間に落とす
0148:     // 向きの計算
0149:     ray_dir = ray_to - ray_start;
0150:     D3DXVec4Normalize(&ray_dir, &ray_dir);
0151:     
0152:     // 色計算
0153:     return GetColor(dest, &ray_start, &ray_dir);
0154: }
0155: 
0156: };// namespace Render
0157: