bool ReleaseResourceDX9(void) { g_Model_DX9.Release(); g_SpotLightModel_DX9.Release(); return true; }
bool InitResourceDX9(void) { // 取得Direct3D 9裝置 LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); // 設定視角轉換矩陣 g_projection_matrix = GutMatrixPerspectiveRH_DirectX(g_fFOV, 1.0f, 0.1f, 100.0f); InitStateDX9(); CGutModel::SetTexturePath("../../textures/"); g_Model_DX9.ConvertToDX9Model(&g_Model); g_SpotLightModel_DX9.ConvertToDX9Model(&g_SpotLightModel); g_material_stencilpass.m_bCullFace = false; g_material_spotlightpass.m_bBlend = true; g_material_spotlightpass.m_SrcBlend = D3DBLEND_ONE; g_material_spotlightpass.m_DestBlend = D3DBLEND_ONE; g_material_spotlightpass.m_Material.Diffuse.r = g_material_spotlightpass.m_Material.Diffuse.g = g_material_spotlightpass.m_Material.Diffuse.b = g_material_spotlightpass.m_Material.Diffuse.a = 0.3f; return true; }
bool ReleaseResourceDX9(void) { SAFE_RELEASE(g_pTexture); SAFE_RELEASE(g_pDepthStencil); SAFE_RELEASE(g_pBlurTextures[0]); SAFE_RELEASE(g_pBlurTextures[1]); g_Model_DX9.Release(); g_Terrain_DX9.Release(); return true; }
// 使用DirectX9來繪圖 void RenderFrameDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0); // `把隱藏面測試規則設為小於或等於` <= device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); // `設定轉換矩陣` Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix = g_Control.GetObjectMatrix(); device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &view_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &world_matrix); // `開始下繪圖指令` device->BeginScene(); // `前8盞光` if ( g_iSwitch & 0x01 ) { SetupLightingDX9(&g_Lights[0], 8); g_Model_DX9.Render(); } // `後8盞光` if ( g_iSwitch & 0x02 ) { SetupLightingDX9(&g_Lights[8], 8); if ( g_iSwitch & 0x01 ) { // 如果前8盞光有開, 要使用混色來把下8盞光疊加上去. device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); // ~SUBMIT_BLEND 會取消套用檔案中的混色設定. g_Model_DX9.Render(~SUBMIT_BLEND); } else { g_Model_DX9.Render(); } } // `宣告所有的繪圖指令都下完了` device->EndScene(); // `把背景backbuffer的畫面呈現出來` device->Present( NULL, NULL, NULL, NULL ); }
bool InitResourceDX9(void) { // 取得Direct3D 9裝置 LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); // 設定視角轉換矩陣 g_projection_matrix = GutMatrixPerspectiveRH_DirectX(g_fFOV, 1.0f, 0.1f, 100.0f); device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &g_projection_matrix); // 關閉打光 device->SetRenderState(D3DRS_LIGHTING, FALSE); // 改變三角形正面的面向 device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // 使用自動normalize功能 device->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE); // 配置動態貼圖 { device->CreateTexture(g_framebuffer_w, g_framebuffer_h, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pTexture, NULL); device->CreateDepthStencilSurface(g_framebuffer_w, g_framebuffer_h, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &g_pDepthStencil, NULL); device->CreateTexture(g_framebuffer_w, g_framebuffer_h, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pBlurTextures[0], NULL); device->CreateTexture(g_framebuffer_w, g_framebuffer_h, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pBlurTextures[1], NULL); } // 載入模型 { CGutModel::SetTexturePath("../../textures/"); g_Model_DX9.ConvertToDX9Model(&g_Model); g_Terrain_DX9.ConvertToDX9Model(&g_Terrain); } // 設定貼圖內插方法 { device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); device->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); device->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_NONE); device->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); device->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); } return true; }
bool InitResourceDX9(void) { g_orient_matrix.Identity(); LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); if ( !ReInitResourceDX9() ) return false; g_pPostEffect = GutLoadFXShaderDX9("../../shaders/Posteffect.fx"); if ( NULL==g_pPostEffect ) return false; g_pWaterEffect = GutLoadFXShaderDX9("../../shaders/Watereffect.fx"); if ( NULL==g_pWaterEffect ) return false; g_pWaterTexture = GutLoadTexture_DX9("../../textures/lena.tga"); if ( NULL==g_pWaterTexture ) return false; g_Model_DX9.ConvertToDX9Model(&g_Model); return true; }
// 使用DirectX 9來繪圖 void RenderFrameDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0); device->SetRenderState(D3DRS_LIGHTING, FALSE); // 設定轉換矩陣 Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix = g_Control.GetObjectMatrix(); device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &view_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &world_matrix); // 開始下繪圖指令 device->BeginScene(); SetupLightingDX9(); g_Model_DX9.Render(); // 宣告所有的繪圖指令都下完了 device->EndScene(); // 把背景backbuffer的畫面呈現出來 device->Present( NULL, NULL, NULL, NULL ); }
bool InitResourceDX9(void) { // 取得Direct3D 9裝置 LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); // 設定視角轉換矩陣 int w, h; GutGetWindowSize(w, h); float aspect = (float) h / (float) w; g_projection_matrix = GutMatrixPerspectiveRH_DirectX(g_fFovW, aspect, 0.1f, 100.0f); device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &g_projection_matrix); // 畫出正向跟反向的三角形 device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); CGutModel::SetTexturePath("../../textures/"); for ( int t=0; t<MAX_NUM_TEXTURES; t++ ) { // trilinear filter device->SetSamplerState(t, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); device->SetSamplerState(t, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState(t, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); } g_Model_DX9.ConvertToDX9Model(&g_Model); return true; }
// 使用DirectX 9來繪圖 void RenderFrameDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); // 消除畫面 device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0); // 開始下繪圖指令 device->BeginScene(); // 設定座標轉換矩陣 Matrix4x4 view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &view_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &g_world_matrix); // 套用貼圖 device->SetTexture(0, g_pTexture); // trilinear filter device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); // 自動產生貼圖座標 device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); //device->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3); // 使用自動normalize功能 device->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE); // 畫模型 // 傳入0代表不套用模型中的材質, 經由外部來設定. g_Model_DX9.Render(0); // 宣告所有的繪圖指令都下完了 device->EndScene(); // 把背景backbuffer的畫面呈現出來 device->Present( NULL, NULL, NULL, NULL ); }
void DrawObject(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 scale_matrix; scale_matrix.Scale_Replace(g_fRippleSize, g_fRippleSize, 1.0f); Matrix4x4 world_matrix = g_orient_matrix * scale_matrix; world_matrix[3] = g_vPosition; device->SetVertexShader(NULL); device->SetPixelShader(NULL); device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*) &g_proj_matrix); device->SetTransform(D3DTS_VIEW, (D3DMATRIX*) &view_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX*) &world_matrix); device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); device->SetRenderState(D3DRS_ZENABLE, TRUE); device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); g_Model_DX9.Render(); device->SetRenderState(D3DRS_LIGHTING, FALSE); }
static void RenderModelDX9(bool mirror, Vector4 *pPlane) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); Matrix4x4 view_matrix; Matrix4x4 world_matrix = g_Control.GetObjectMatrix(); if ( mirror ) { Vector4 vEye = g_Control.GetCameraPosition(); Vector4 vUp = g_Control.m_vUp; Vector4 vLookAt = g_Control.m_vLookAt; Vector4 mirror_eye = MirrorPoint(vEye, *pPlane); Vector4 mirror_lookat = MirrorPoint(vLookAt, *pPlane); Vector4 mirror_up = MirrorPoint(vUp, *pPlane); view_matrix = GutMatrixLookAtRH(mirror_eye, mirror_lookat, mirror_up); g_mirror_view_matrix = view_matrix; } else { view_matrix = g_Control.GetViewMatrix(); } device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &view_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &world_matrix); g_Model_DX9.Render(); }
void RenderFrameDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); device->BeginScene(); Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix = g_Control.GetObjectMatrix(); // normal pass if ( g_bPosteffect ) { device->SetRenderTarget(0, g_pFrameSurface[FULLSIZE]); device->SetDepthStencilSurface(NULL); } else { device->SetRenderTarget(0, g_pMainSurface); device->SetDepthStencilSurface(NULL); } device->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 1.0f, 0); device->SetVertexShader(NULL); device->SetPixelShader(NULL); device->SetRenderState(D3DRS_LIGHTING, FALSE); device->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&g_proj_matrix); device->SetTransform(D3DTS_VIEW, (D3DMATRIX*)&view_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *)&world_matrix); g_Model_DX9.Render(); if ( g_bPosteffect ) { ConverToLogLuminance(g_pFrameBuffer[FULLSIZE], &g_ImageInfo); // ExpLuminance(g_pFrameSurface[FULLSIZE], g_pFrameBuffer[DOWNSAMPLED_256x256], &g_Image256x256); AverageLuminance(g_pFrameBuffer[DOWNSAMPLED_256x256]); ExpLuminance(); AdaptiveLuminance(); device->SetRenderTarget(0, g_pMainSurface); device->SetDepthStencilSurface(NULL); //device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0x0, 1.0f, 0); AutoExposure(); if ( g_iMode & 0x01 ) { DrawImage(g_pFrameBuffer[LUMINANCE_TEMP], &g_Image1x1, -1.0f, -1.0f, 0.1f, 0.1f); DrawImage(g_pFrameBuffer[LUMINANCE_CURRENT], &g_Image1x1, -0.9f, -1.0f, 0.1f, 0.1f); } } device->EndScene(); device->Present( NULL, NULL, NULL, NULL ); }
static void AddImpulse(void) { static Vector4 vPosition(0.0f, 0.0f, 0.0f, 0.0f); //Vector4 vDiff = vPosition - g_vPosition; Vector4 vDiff = g_vPosition - vPosition; Vector4 vLength = vDiff.Length(); if ( vLength[0]<2.0f ) return; Vector4 vDir = vDiff / vLength; Vector4 vVec0(vDir[1],-vDir[0], 0.0f, 0.0f); Vector4 vVec1(vDir[0], vDir[1], 0.0f, 0.0f); vPosition = g_vPosition; Vector4 vVec0_old = g_orient_matrix[0]; Vector4 vVec1_old = g_orient_matrix[1]; Vector4 vVec0_new = VectorLerp(vVec0_old, vVec0, 0.2f); Vector4 vVec1_new = VectorLerp(vVec1_old, vVec1, 0.2f); vVec0_new.Normalize(); vVec1_new.Normalize(); Vector4 vVec2_new = Vector3CrossProduct(vVec0_new, vVec1_new); g_orient_matrix.Identity(); g_orient_matrix[0] = vVec0_new; g_orient_matrix[1] = vVec1_new; g_orient_matrix[2] = vVec2_new; LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); device->SetRenderTarget(0, g_pSurfaces[TEX_HEIGHT1]); device->SetDepthStencilSurface(NULL); Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix; world_matrix.Scale_Replace(g_fRippleSize, g_fRippleSize, 1.0f); world_matrix[3] = g_vPosition; Matrix4x4 wvp_matrix = g_orient_matrix * world_matrix * view_matrix * g_proj_matrix; D3DXHANDLE shader = g_pWaterEffect->GetTechniqueByName("AddImpulse"); D3DXHANDLE wvp_matrix_var = g_pWaterEffect->GetParameterByName(NULL, "wvp_matrix"); D3DXHANDLE force_var = g_pWaterEffect->GetParameterByName(NULL, "fForce"); g_pWaterEffect->SetTechnique(shader); g_pWaterEffect->SetMatrix(wvp_matrix_var, (D3DXMATRIX *)&wvp_matrix); g_pWaterEffect->SetFloat(force_var, 0.05f); g_pWaterEffect->Begin(NULL, 0); g_pWaterEffect->BeginPass(0); g_Model_DX9.Render(0); g_pWaterEffect->EndPass(); g_pWaterEffect->End(); vPosition = g_vPosition; }
bool ReleaseResourceDX9(void) { SAFE_RELEASE(g_pTexture); SAFE_RELEASE(g_pDepthStencil); g_Model_DX9.Release(); return true; }
bool InitResourceDX9(void) { // 取得Direct3D 9裝置 LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); // 設定視角轉換矩陣 g_projection_matrix = GutMatrixPerspectiveRH_DirectX(g_fFOV, 1.0f, 0.1f, 100.0f); InitStateDX9(); CGutModel::SetTexturePath("../../textures/"); g_Model_DX9.ConvertToDX9Model(&g_Model_textured); return true; }
static void RenderModelDX9(bool mirror, Vector4 *pPlane) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); Matrix4x4 view_matrix; if ( mirror ) { Vector4 vEye = g_Control.GetCameraPosition(); Vector4 vLookAt = g_Control.m_vLookAt; Vector4 vUp = g_Control.m_vUp; Vector4 mirror_eye = MirrorPoint(vEye, *pPlane); Vector4 mirror_lookat = MirrorPoint(vLookAt, *pPlane); Vector4 mirror_up = MirrorVector(vUp, *pPlane); Matrix4x4 temp_matrix = GutMatrixLookAtRH(mirror_eye, mirror_lookat, mirror_up); // 因為是鏡射, 在轉換到鏡頭座標系後要做個左右對調的動作. Matrix4x4 mirror_x; mirror_x.Identity(); mirror_x.Scale(-1.0f, 1.0f, 1.0f); view_matrix = temp_matrix * mirror_x; // 右左對調後, 3角形的頂點排列順序會被反過來. GutSetDX9BackFace(D3DCULL_CCW); } else { view_matrix = g_Control.GetViewMatrix(); device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); GutSetDX9BackFace(D3DCULL_CW); } Matrix4x4 world_matrix = g_Control.GetObjectMatrix(); device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &view_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &world_matrix); g_Model_DX9.Render(); GutSetDX9BackFace(D3DCULL_CW); }
bool InitResourceDX9(void) { // 取得Direct3D 9裝置 LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); // 設定視角轉換矩陣 g_projection_matrix = GutMatrixPerspectiveRH_DirectX(g_fFOV, 1.0f, 0.1f, 100.0f); device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &g_projection_matrix); // 關閉打光 device->SetRenderState(D3DRS_LIGHTING, FALSE); // 改變三角形正面的面向 device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // 使用自動normalize功能 device->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE); device->CreateTexture(512, 512, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pTexture, NULL); device->CreateDepthStencilSurface(512, 512, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &g_pDepthStencil, NULL); CGutModel::SetTexturePath("../../textures/"); g_Model_DX9.ConvertToDX9Model(&g_Model); return true; }
bool InitResourceDX9(void) { // 取得Direct3D 9裝置 LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); // 設定視角轉換矩陣 int w, h; GutGetWindowSize(w, h); float aspect = (float) h / (float) w; Matrix4x4 projection_matrix = GutMatrixPerspectiveRH_DirectX(g_fFovW, aspect, 0.1f, 100.0f); device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &projection_matrix); // 關閉打光 device->SetRenderState(D3DRS_LIGHTING, FALSE); // 畫出正向跟反向的三角形 device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // 載入貼圖 const char *texture_array[] = { "../../textures/uffizi_right.tga", "../../textures/uffizi_left.tga", "../../textures/uffizi_top.tga", "../../textures/uffizi_bottom.tga", "../../textures/uffizi_back.tga", // `右手座標系上 Z+ 為鏡頭後方.` "../../textures/uffizi_front.tga" // `右手座標系上 Z- 為鏡頭前方.` }; g_pTexture = GutLoadCubemapTexture_DX9(texture_array); if ( g_pTexture==NULL ) { // 有些舊硬體不支援 mipmapped cubemap , 改載入 dds 的版本. g_pTexture = GutLoadCubemapTexture_DX9("../../textures/uffizi_cubemap.dds"); if ( g_pTexture==NULL ) return false; } if ( !g_Model_DX9.ConvertToDX9Model(&g_Model) ) return false; return true; }
bool InitResourceDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); CGutModel::SetTexturePath("../../textures/"); g_pTexture = GutLoadTexture_DX9("../../textures/lena.tga", &g_ImageInfo); g_pEffect = GutLoadFXShaderDX9("../../shaders/Posteffect.fx"); if ( NULL==g_pEffect ) return false; g_pRefractionFX = GutLoadFXShaderDX9("../../shaders/Refraction.fx"); if ( NULL==g_pRefractionFX ) return false; g_Model_DX9.ConvertToDX9Model(&g_Model); if ( !ReInitResourceDX9() ) return false; return true; }
void RenderFrameDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); device->BeginScene(); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0x0, 1.0f, 0); Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix = g_Control.GetObjectMatrix(); Matrix4x4 wv_matrix = world_matrix * view_matrix; Matrix4x4 wvp_matrix = wv_matrix * g_proj_matrix; DrawImage(g_pTexture, &g_ImageInfo); D3DXHANDLE shader = g_pRefractionFX->GetTechniqueByName("Refraction"); D3DXHANDLE texture = g_pRefractionFX->GetParameterByName(NULL, "BackgroundImage"); D3DXHANDLE wv_matrix_h = g_pRefractionFX->GetParameterByName(NULL, "wv_matrix"); D3DXHANDLE wvp_matrix_h = g_pRefractionFX->GetParameterByName(NULL, "wvp_matrix"); D3DXHANDLE objectcolor_h = g_pRefractionFX->GetParameterByName(NULL, "object_color"); g_pRefractionFX->SetTechnique(shader); g_pRefractionFX->SetTexture(texture, g_pTexture); g_pRefractionFX->SetMatrix(wv_matrix_h, (D3DXMATRIX *)&wv_matrix); g_pRefractionFX->SetMatrix(wvp_matrix_h, (D3DXMATRIX *)&wvp_matrix); g_pRefractionFX->SetVector(objectcolor_h, (D3DXVECTOR4 *)&g_vObjectColor); g_pRefractionFX->Begin(NULL, 0); g_pRefractionFX->BeginPass(0); g_Model_DX9.Render(0); g_pRefractionFX->EndPass(); g_pRefractionFX->End(); device->EndScene(); device->Present( NULL, NULL, NULL, NULL ); }
bool InitResourceDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); for ( int i=0; i<NUM_FRAMEBUFFERS; i++ ) { g_pFrameBuffer[i] = NULL; g_pFrameSurface[i] = NULL; } CGutModel::SetTexturePath("../../textures/"); if ( !g_Model_DX9.ConvertToDX9Model(&g_Model) ) return false; g_pEffect = GutLoadFXShaderDX9("../../shaders/Posteffect.fx"); if ( NULL==g_pEffect ) return false; g_pAddImageShader = g_pEffect->GetTechniqueByName("DrawImage"); g_pBlurShader = g_pEffect->GetTechniqueByName("BlurImage"); g_pBrightnessShader = g_pEffect->GetTechniqueByName("Brightness"); if ( NULL==g_pAddImageShader || NULL==g_pBlurShader || NULL==g_pBrightnessShader ) return false; g_pExposureEffect = GutLoadFXShaderDX9("../../shaders/Exposure.fx"); if ( NULL==g_pExposureEffect ) return false; if ( !ReInitResourceDX9() ) return false; return true; }
bool InitResourceDX9(void) { // 取得Direct3D 9裝置 LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); // 設定視角轉換矩陣 int w, h; GutGetWindowSize(w, h); float aspect = (float) h / (float) w; g_projection_matrix = GutMatrixPerspectiveRH_DirectX(g_fFovW, aspect, g_fNear, g_fFar); device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &g_projection_matrix); for ( int t=0; t<MAX_NUM_TEXTURES; t++ ) { // trilinear filter device->SetSamplerState(t, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); device->SetSamplerState(t, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState(t, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); } g_Model_DX9.ConvertToDX9Model(&g_Model); //g_Model_DX9.SetCullMode(D3DCULL_NONE); device->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE); device->SetRenderState(D3DRS_SPECULARENABLE, TRUE); device->SetRenderState(D3DRS_COLORVERTEX, FALSE); device->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL); device->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL); device->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL); device->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL); device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); //device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); return true; }
// 使用DirectX 9來繪圖 void RenderFrameDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix = g_Control.GetObjectMatrix(); device->BeginScene(); // 消除畫面 device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, D3DCOLOR_RGBA(0, 0, 0, 255), 1.0f, 0); // 轉換矩陣 device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &g_projection_matrix); device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &view_matrix); // 畫出空間中的茶壼 { device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &world_matrix); g_Model_DX9.Render(); } device->SetRenderState(D3DRS_STENCILENABLE, TRUE); device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); device->SetRenderState(D3DRS_STENCILMASK, 0xff); device->SetRenderState(D3DRS_STENCILREF, 1); // 在Stencil Buffer中標示出光柱照射的區域 { Matrix4x4 ident_matrix = Matrix4x4::IdentityMatrix(); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &ident_matrix); // `啟動 Two sided stencil test 功能` device->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE); // `順時針方向的 Stencil Test 設定` device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); device->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR); // `逆時針方向的 Stencil Test 設定` device->SetRenderState(D3DRS_CCW_STENCILFUNC, D3DCMP_ALWAYS); device->SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR); // `關閉顏色跟 ZBuffer 的更新` device->SetRenderState(D3DRS_COLORWRITEENABLE, 0); CGutModel_DX9::SetMaterialOverwrite(&g_material_stencilpass); g_SpotLightModel_DX9.Render(); CGutModel_DX9::SetMaterialOverwrite(NULL); // `還原設定` device->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE); device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); device->SetRenderState(D3DRS_CCW_STENCILFUNC, D3DSTENCILOP_KEEP); device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA); } // 畫出光柱照射到的區域 { device->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL); device->SetRenderState(D3DRS_STENCILREF, 1); CGutModel_DX9::SetCullMode(D3DCULL_CCW); CGutModel_DX9::SetMaterialOverwrite(&g_material_spotlightpass); g_SpotLightModel_DX9.Render(); CGutModel_DX9::SetMaterialOverwrite(NULL); device->SetRenderState(D3DRS_ZENABLE, TRUE); } device->SetRenderState(D3DRS_STENCILENABLE, FALSE); // 畫出光柱 { CGutModel_DX9::SetCullMode(D3DCULL_CW); g_SpotLightModel_DX9.Render(); } device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); // 宣告所有的繪圖指令都下完了 device->EndScene(); // 把背景backbuffer的畫面呈現出來 device->Present( NULL, NULL, NULL, NULL ); }
// 使用DirectX 9來繪圖 void RenderFrameDX9(void) { DWORD FogColor = D3DCOLOR_RGBA(128, 128, 128, 255); LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); device->BeginScene(); // 消除畫面 device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, FogColor, 1.0f, 0); // 設定轉換矩陣 Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 object_matrix = g_Control.GetObjectMatrix(); device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &g_projection_matrix); device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &view_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &object_matrix); // 設定霧 device->SetRenderState(D3DRS_FOGENABLE, TRUE); device->SetRenderState(D3DRS_FOGCOLOR, FogColor); switch(g_iFogMode) { case 0: device->SetRenderState(D3DRS_FOGENABLE, FALSE); break; case 1: { // 隨距離線性變濃的霧 float fStart = 0.0f; float fEnd = 10.0f; device->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR); device->SetRenderState(D3DRS_FOGSTART, *(DWORD *)(&fStart)); device->SetRenderState(D3DRS_FOGEND, *(DWORD *)(&fEnd)); // 計算公式為 // (fog_end - distance_to_camera) / (fog_end - fog_start) break; } case 2: { // `套用指數函式來變化的霧 ` float fFogDensity = 0.5f; device->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_EXP); device->SetRenderState(D3DRS_FOGDENSITY, *(DWORD *)&fFogDensity); // 計算公式為 // power(e, -(fog_density * distance_to_camera)) break; } case 3: { // `套用指數函式來變化的霧 ` float fFogDensity = 0.5f; device->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_EXP2); device->SetRenderState(D3DRS_FOGDENSITY, *(DWORD *)&fFogDensity); // 計算公式為 // power(e, -(fog_density * distance_to_camera)^2) break; } } // 畫出模型 g_Model_DX9.Render(); // 宣告所有的繪圖指令都下完了 device->EndScene(); // 把背景backbuffer的畫面呈現出來 device->Present( NULL, NULL, NULL, NULL ); }
// `使用Direct3D9來繪圖` void RenderFrameDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); Matrix4x4 light_projection_matrix; Matrix4x4 light_view_matrix; Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix = g_Control.GetObjectMatrix(); // `開始下繪圖指令` device->BeginScene(); // `把剪影畫在動態貼圖中` if(1) { //! 设置临时framebuffer LPDIRECT3DSURFACE9 pFrameBufferBackup, pDepthBufferBackup; device->GetRenderTarget(0, &pFrameBufferBackup); pFrameBufferBackup->Release(); device->GetDepthStencilSurface(&pDepthBufferBackup); pDepthBufferBackup->Release(); LPDIRECT3DSURFACE9 pSurface; g_pTexture->GetSurfaceLevel(0, &pSurface); device->SetRenderTarget(0, pSurface); device->SetDepthStencilSurface(g_pDepthStencil); device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(255, 255, 255, 255), 1.0f, 0); Vector4 vLightPos = g_Light.m_Position; Vector4 vLightUp(0.0f, 1.0f, 0.0f); Vector4 vLightLookat(0.0f, 0.0f, 0.0f); // `把鏡頭放在光源的` light_projection_matrix = GutMatrixPerspectiveRH_DirectX(60.0f, 1.0f, 0.1f, 100.0f); light_view_matrix = GutMatrixLookAtRH(vLightPos, vLightLookat, vLightUp); // `設定轉換矩陣` device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *)&light_projection_matrix); device->SetTransform(D3DTS_VIEW, (D3DMATRIX *)&light_view_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *)&world_matrix); D3DCOLORVALUE zero = {0.0f, 0.0f, 0.0f, 1.0f}; sModelMaterial_DX9 material; material.m_Material.Ambient = zero; material.m_Material.Emissive = zero; material.m_Material.Diffuse = zero; material.m_Material.Specular = zero; material.m_bCullFace = false; material.Submit(); device->SetRenderState(D3DRS_LIGHTING, 0); g_Model_DX9.Render(0); pSurface->Release(); device->SetRenderTarget(0, pFrameBufferBackup); device->SetDepthStencilSurface(pDepthBufferBackup); } // `把上一個步驟的結果當成貼圖來使用` { // `消除畫面` device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0, 0, 150, 255), 1.0f, 0); // `設定轉換矩陣` device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &g_projection_matrix); device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &view_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &world_matrix); #define DRAW_TEAPORT_FIRST 1 //! 画茶壶 if (DRAW_TEAPORT_FIRST) { SetupLightingDX9(); g_Model_DX9.Render(); } //! 设置矩形的纹理 sModelMaterial_DX9 material; material.m_pTextures[0] = g_pTexture; material.Submit(); Matrix4x4 inv_view_matrix = view_matrix; inv_view_matrix.FastInvert(); Matrix4x4 uv_offset_matrix; uv_offset_matrix.Identity(); uv_offset_matrix.Scale(0.5f, -0.5f, 0.5f); uv_offset_matrix[3].Set(0.5f, 0.5f, 0.5f, 1.0f); Matrix4x4 texture_matrix = inv_view_matrix * light_view_matrix * light_projection_matrix * uv_offset_matrix; Matrix4x4 indent_matrix = Matrix4x4::IdentityMatrix(); device->SetTransform(D3DTS_TEXTURE0, (D3DMATRIX *) &texture_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &indent_matrix); device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); device->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED ); device->SetRenderState(D3DRS_LIGHTING, FALSE); // `畫出矩形` device->SetFVF(D3DFVF_XYZ); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_Quad, sizeof(Vertex_VT)); //! 关闭纹理矩阵 device->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); if (!DRAW_TEAPORT_FIRST) { //SetupLightingDX9(); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &world_matrix); g_Model_DX9.Render(); } } // `宣告所有的繪圖指令都下完了` device->EndScene(); // `把背景backbuffer的畫面呈現出來` device->Present( NULL, NULL, NULL, NULL ); }
// 使用DirectX 9來繪圖 void RenderFrameDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix = g_Control.GetObjectMatrix(); Matrix4x4 ident_matrix; ident_matrix.Identity(); device->BeginScene(); // 消除畫面 device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, D3DCOLOR_RGBA(30, 30, 30, 255), 1.0f, 0); // light position & orientation Vector4 light_pos(5.0f, 0.0f, 5.0f); Vector4 light_lookat(0.0f, 0.0f, 0.0f); Vector4 light_up(0.0f, 1.0f, 0.0f); // light matrix Matrix4x4 light_view = GutMatrixLookAtRH(light_pos, light_lookat, light_up); Matrix4x4 light_world_view = world_matrix * light_view; Matrix4x4 shadow_matrix; // 建立shadow volume if ( g_bDirectionalLight ) { g_ShadowVolume.BuildShadowVolume_DirectionalLight(light_world_view, 20.0f, true); shadow_matrix = light_view; shadow_matrix.FastInvert(); } else { g_ShadowVolume.BuildShadowVolume_PointLight(light_pos, world_matrix, 20.0f, true); shadow_matrix.Identity(); } // 畫出空間中的茶壼 { device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &g_projection_matrix); device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &view_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &world_matrix); g_Model_DX9.Render(); } // 畫出墻壁 { device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &ident_matrix); sModelMaterial_DX9 material; material.m_Material.Diffuse.r = 0.0f; material.m_Material.Diffuse.g = 0.0f; material.m_Material.Diffuse.b = 1.0f; material.m_Material.Diffuse.a = 1.0f; material.Submit(); device->SetFVF(D3DFVF_XYZ); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_Quad, sizeof(Vertex_VT)); } device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); device->SetRenderState(D3DRS_STENCILENABLE, TRUE); device->SetRenderState(D3DRS_STENCILREF, 0x01); device->SetRenderState(D3DRS_STENCILMASK, 0xff); // 在Stencil Buffer上標示出陰影區域 { sModelMaterial_DX9 material; material.m_bCullFace = false; material.Submit(); // 套用矩陣 device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &shadow_matrix); // 設定頂點資料格式 device->SetFVF(D3DFVF_XYZ); device->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE); // cw stencil setting device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); device->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR); // ccw stencil setting device->SetRenderState(D3DRS_CCW_STENCILFUNC, D3DCMP_ALWAYS); device->SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR); // disable color write device->SetRenderState(D3DRS_COLORWRITEENABLE, 0); // 畫出Shadow Volume device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, g_ShadowVolume.m_iNumShadowVolumeFaces, g_ShadowVolume.m_pShadowVolume, sizeof(Vector4)); // 恢復更新framebuffer device->SetRenderState(D3DRS_COLORWRITEENABLE, 0xff); device->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE); device->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); device->SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP); } // 畫出陰影 { sModelMaterial_DX9 material; material.m_bCullFace = false; material.Submit(); device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); // 套用矩陣 device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &ident_matrix); device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &ident_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &ident_matrix); // 只更新stencil buffer上值為1的像素 device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL); device->SetRenderState(D3DRS_STENCILREF, 0x01); // 使用黑色再畫一次墻壁 device->SetRenderState(D3DRS_TEXTUREFACTOR, D3DCOLOR_RGBA(0, 0, 0,255) ); device->SetFVF(D3DFVF_XYZ); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_FullScreenQuad, sizeof(Vertex_VT)); } device->SetRenderState(D3DRS_STENCILENABLE, FALSE); // 觀察shadow volume, 除錯用. if ( g_bDrawShadowVolume ) { device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &g_projection_matrix); device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &view_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &shadow_matrix); sModelMaterial_DX9 material; material.m_bCullFace = false; material.Submit(); device->SetRenderState(D3DRS_TEXTUREFACTOR, D3DCOLOR_RGBA(255, 255, 255, 255) ); device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, g_ShadowVolume.m_iNumShadowVolumeFaces, g_ShadowVolume.m_pShadowVolume, sizeof(Vector4)); device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); } // 恢復更新zbuffer device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); // 把顏色來源還原為 diffuse * texture device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); // 宣告所有的繪圖指令都下完了 device->EndScene(); // 把背景backbuffer的畫面呈現出來 device->Present( NULL, NULL, NULL, NULL ); }
// 使用DirectX 9來繪圖 void RenderFrameDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); LPDIRECT3DTEXTURE9 pBlurredTexture = NULL; Matrix4x4 light_projection_matrix; Matrix4x4 light_view_matrix; Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix = g_Control.GetObjectMatrix(); // 開始下繪圖指令 device->BeginScene(); { // 保存主framebuffer LPDIRECT3DSURFACE9 pFrameBufferBackup, pDepthBufferBackup; device->GetRenderTarget(0, &pFrameBufferBackup); pFrameBufferBackup->Release(); device->GetDepthStencilSurface(&pDepthBufferBackup); pDepthBufferBackup->Release(); // 取出動態貼圖中的surface LPDIRECT3DSURFACE9 pSurface; g_pTexture->GetSurfaceLevel(0, &pSurface); // 把繪圖結果輸出到動態貼圖中 device->SetRenderTarget(0, pSurface); device->SetDepthStencilSurface(g_pDepthStencil); // 清除畫面 device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(255, 255, 255, 255), 1.0f, 0); // 設定光源位置 Vector4 vLightPos = g_Light.m_Position; Vector4 vLightUp(0.0f, 1.0f, 0.0f); Vector4 vLightLookat(0.0f, 0.0f, 0.0f); light_projection_matrix = GutMatrixPerspectiveRH_DirectX(60.0f, 1.0f, 0.1f, 100.0f); light_view_matrix = GutMatrixLookAtRH(vLightPos, vLightLookat, vLightUp); // 把鏡頭放到光源位置來畫陰影 device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *)&light_projection_matrix); device->SetTransform(D3DTS_VIEW, (D3DMATRIX *)&light_view_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *)&world_matrix); // 把所有反射關閉,讓模型在畫面上呈現黑色。 D3DCOLORVALUE zero = {0.0f, 0.0f, 0.0f, 1.0f}; sModelMaterial_DX9 material; material.m_Material.Ambient = zero; material.m_Material.Emissive = zero; material.m_Material.Diffuse = zero; material.m_Material.Specular = zero; material.m_bCullFace = false; material.Submit(); SetupLightingDX9(); // 畫出模型 g_Model_DX9.Render(0); // 告知direct3d9裝置rendertarget使用完畢 pSurface->Release(); // 還原主framebuffer device->SetRenderTarget(0, pFrameBufferBackup); device->SetDepthStencilSurface(pDepthBufferBackup); } // 把影子柔化 { pBlurredTexture = BlurTexture(g_pTexture); } // 把上一個步驟的結果當成貼圖來使用 { // 消除畫面 device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0, 0, 150, 255), 1.0f, 0); // 設定轉換矩陣 device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &g_projection_matrix); device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &view_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &world_matrix); // 設定光源 SetupLightingDX9(); device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); device->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); device->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); // 畫出茶壼 g_Model_DX9.Render(); sModelMaterial_DX9 material; material.m_pTextures[0] = pBlurredTexture; material.Submit(); // 計算貼圖矩陣 Matrix4x4 inv_view_matrix = g_Control.GetCameraMatrix(); Matrix4x4 uv_offset_matrix; uv_offset_matrix.Identity(); uv_offset_matrix.Scale(0.5f, -0.5f, 0.5f); uv_offset_matrix[3].Set(0.5f, 0.5f, 0.5f, 1.0f); Matrix4x4 texture_matrix = inv_view_matrix * light_view_matrix * light_projection_matrix * uv_offset_matrix; Matrix4x4 indent_matrix = Matrix4x4::IdentityMatrix(); // 設定轉換矩陣 device->SetTransform(D3DTS_TEXTURE0, (D3DMATRIX *) &texture_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &indent_matrix); // 開啟自動產生貼圖座標功能 device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); device->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED); device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); device->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); device->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); // 畫出地表 g_Terrain_DX9.Render(0); device->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); } // 宣告所有的繪圖指令都下完了 device->EndScene(); // 把背景backbuffer的畫面呈現出來 device->Present( NULL, NULL, NULL, NULL ); }
// 使用DirectX 9來繪圖 void RenderFrameDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix = g_Control.GetObjectMatrix(); device->BeginScene(); // 消除畫面 device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, D3DCOLOR_RGBA(0, 0, 0, 255), 1.0f, 0); // 轉換矩陣 device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &g_projection_matrix); device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &view_matrix); // 畫出茶壼 { device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &world_matrix); g_Model_DX9.Render(); } // stencil pass { Matrix4x4 ident_matrix = Matrix4x4::IdentityMatrix(); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &ident_matrix); device->SetRenderState(D3DRS_STENCILREF, 1); device->SetRenderState(D3DRS_STENCILENABLE, TRUE); device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); device->SetRenderState(D3DRS_COLORWRITEENABLE, 0); device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); // 畫出面對鏡頭的面,同時遞增 Stencil Buffer。 device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR); device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); // 呼叫 Render 時傳入 0 代表不需要套用任何材質設定 g_SpotLightModel_DX9.Render(0); // 畫出背對鏡頭的面,同時遞減 Stencil Buffer。 device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_DECR); device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); // 呼叫 Render 時傳入 0 代表不需要套用任何材質設定 g_SpotLightModel_DX9.Render(0); // 還原設定 device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA); } // 畫出光柱照射到的區域 { device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL); device->SetRenderState(D3DRS_STENCILREF, 1); // 用 g_material_spotlightpass 來取代模型中的材質設定 CGutModel_DX9::SetMaterialOverwrite(&g_material_spotlightpass); g_SpotLightModel_DX9.Render(); // 還原,讓模型使用它原本的材質設定。 CGutModel_DX9::SetMaterialOverwrite(NULL); } // 用正常的方法畫出光柱 { device->SetRenderState(D3DRS_STENCILENABLE, FALSE); g_SpotLightModel_DX9.Render(); device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); } // 宣告所有的繪圖指令都下完了 device->EndScene(); // 把背景backbuffer的畫面呈現出來 device->Present( NULL, NULL, NULL, NULL ); }