void InitStateDX9(void) { // 取得Direct3D 9裝置 LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); // 關閉打光 device->SetRenderState(D3DRS_LIGHTING, FALSE); // 使用trilinear device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); // device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE); device->GetRenderTarget(0, &g_pMainFrameBuffer); device->GetDepthStencilSurface(&g_pMainDepthBuffer); int width, height; GutGetWindowSize(width, height); g_iFrameBufferWidth = width * 2; g_iFrameBufferHeight = height * 2; device->CreateTexture(g_iFrameBufferWidth, g_iFrameBufferHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pTexture, NULL); device->CreateDepthStencilSurface(g_iFrameBufferWidth, g_iFrameBufferHeight, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &g_pDepthStencil, NULL); g_pTexture->GetSurfaceLevel(0, &g_pFrameBuffer); }
void Graphics::setRenderTarget(RenderTarget* target, int num) { //if (backBuffer != nullptr) backBuffer->Release(); if (num == 0) { if (backBuffer == nullptr) { device->GetRenderTarget(0, &backBuffer); device->GetDepthStencilSurface(&depthBuffer); } affirm(device->SetDepthStencilSurface(target->depthSurface)); } affirm(device->SetRenderTarget(num, target->colorSurface)); }
void Graphics::setRenderTarget(RenderTarget* target, int num, int additionalTargets) { // if (backBuffer != nullptr) backBuffer->Release(); System::makeCurrent(target->contextId); if (num == 0) { if (backBuffer == nullptr) { device->GetRenderTarget(0, &backBuffer); device->GetDepthStencilSurface(&depthBuffer); } affirm(device->SetDepthStencilSurface(target->depthSurface)); } affirm(device->SetRenderTarget(num, target->colorSurface)); }
void Graphics4::setRenderTargets(RenderTarget** targets, int count) { // if (backBuffer != nullptr) backBuffer->Release(); System::makeCurrent(targets[0]->contextId); if (backBuffer == nullptr) { device->GetRenderTarget(0, &backBuffer); device->GetDepthStencilSurface(&depthBuffer); } Microsoft::affirm(device->SetDepthStencilSurface(targets[0]->depthSurface)); for (int i = 0; i < count; ++i) { Microsoft::affirm(device->SetRenderTarget(i, targets[i]->colorSurface)); } }
static bool CopyRenderTargetToBackground() { bool ret = false; LPDIRECT3DDEVICE9 device = (LPDIRECT3DDEVICE9)GetUseDirect3DDevice9(); if (device == NULL) return nullptr; HRESULT hr; IDirect3DSurface9* tempRender = nullptr; IDirect3DSurface9* tempDepth = nullptr; hr = device->GetRenderTarget(0, &tempRender); if (FAILED(hr)) { goto Exit; } hr = device->GetDepthStencilSurface(&tempDepth); if (FAILED(hr)) { goto Exit; } device->SetRenderTarget(0, g_dx9_backgroundSurface); device->SetDepthStencilSurface(nullptr); D3DSURFACE_DESC desc; tempRender->GetDesc(&desc); const bool isSame = (desc.Width == g_backgroundWidth && desc.Height == g_backgroundHeight); device->StretchRect( tempRender, nullptr, g_dx9_backgroundSurface, nullptr, (isSame ? D3DTEXF_POINT : D3DTEXF_LINEAR) ); device->SetRenderTarget(0, tempRender); device->SetDepthStencilSurface(tempDepth); ret = true; Exit:; ES_SAFE_RELEASE(tempRender); ES_SAFE_RELEASE(tempDepth); return ret; }
//---------------------------------------------------------------------------------- // //---------------------------------------------------------------------------------- static bool CopyRenderTargetToBackground() { bool ret = false; HRESULT hr; IDirect3DSurface9* tempRender = nullptr; IDirect3DSurface9* tempDepth = nullptr; hr = g_d3d_device->GetRenderTarget(0, &tempRender); if (FAILED(hr)) { goto Exit; } hr = g_d3d_device->GetDepthStencilSurface(&tempDepth); if (FAILED(hr)) { goto Exit; } g_d3d_device->SetRenderTarget(0, g_backgroundSurface); g_d3d_device->SetDepthStencilSurface(nullptr); D3DSURFACE_DESC desc; tempRender->GetDesc(&desc); g_d3d_device->StretchRect( tempRender, nullptr, g_backgroundSurface, nullptr, D3DTEXF_POINT ); g_d3d_device->SetRenderTarget(0, tempRender); g_d3d_device->SetDepthStencilSurface(tempDepth); ret = true; Exit:; ES_SAFE_RELEASE(tempRender); ES_SAFE_RELEASE(tempDepth); return ret; }
bool ReInitResourceDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); int w,h; GutGetWindowSize(w, h); float fAspect = (float)h/(float)w; g_proj_matrix = GutMatrixPerspectiveRH_DirectX(g_fFOV, fAspect, g_fCameraNearZ, g_fCameraFarZ); g_ImageInfo.m_iWidth = g_texture_width; g_ImageInfo.m_iHeight = g_texture_height; g_ImageInfo.m_bProcedure = true; //D3DFORMAT fmt = D3DFMT_A16B16G16R16F; D3DFORMAT fmt = D3DFMT_A32B32G32R32F; for ( int i=0; i<TEX_TEXTURES; i++ ) { device->CreateTexture( g_texture_width, g_texture_height, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &g_pTextures[i], NULL); if ( NULL==g_pTextures[i] ) return false; g_pTextures[i]->GetSurfaceLevel(0, &g_pSurfaces[i]); if ( NULL==g_pSurfaces[i] ) return false; } device->GetRenderTarget(0, &g_pMainFramebuffer); device->GetDepthStencilSurface(&g_pMainDepthbuffer); device->SetRenderTarget(0, g_pSurfaces[0]); device->SetRenderTarget(1, g_pSurfaces[1]); device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 0), 1.0f, 0); device->SetRenderTarget(0, g_pMainFramebuffer); device->SetRenderTarget(1, NULL); return true; }
// 使用DirectX 9來繪圖 void RenderFrameDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); Vector4 vPlane(0.0f, 0.0f, 1.0f, -g_mirror_z); // 開始下繪圖指令 device->BeginScene(); { 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(0, 0, 200, 255), 1.0f, 0); RenderModelDX9(true, &vPlane); 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); RenderModelDX9(false, NULL); Matrix4x4 identMat; identMat.Identity(); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &identMat); sModelMaterial_DX9 material; material.m_pTextures[0] = g_pTexture; material.Submit(); device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); device->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); device->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_NONE); Matrix4x4 uv_offset_matrix; uv_offset_matrix.Scale_Replace(0.5f, -0.5f, 1.0f); uv_offset_matrix[3].Set(0.5f, 0.5f, 0.5f, 1.0f); Matrix4x4 inv_view_matrix = g_Control.GetViewMatrix(); inv_view_matrix.FastInvert(); Matrix4x4 texture_matrix = inv_view_matrix * g_mirror_view_matrix * g_projection_matrix * uv_offset_matrix; device->SetTransform(D3DTS_TEXTURE0, (D3DMATRIX *) &texture_matrix); device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); // D3DTTFF_PROJECTED告知direct3d裝置texcoord需要除以w device->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED); float v[12]; for ( int i=0; i<4; i++ ) { g_Quad[i].m_Position.StoreXYZ(&v[i*3]); } // 畫出矩形 device->SetFVF(D3DFVF_XYZ); //device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_Quad, sizeof(Vertex_V)); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, 12); } // 宣告所有的繪圖指令都下完了 device->EndScene(); // 把背景backbuffer的畫面呈現出來 device->Present( NULL, NULL, NULL, NULL ); }
INT CrenderTarget::CreateRenderSurface() { HRESULT hr=-1; DWORD dMip = 1; LPDIRECT3DSURFACE9 pSfC = NULL; LPDIRECT3DSURFACE9 pSfD = NULL; D3DSURFACE_DESC dscC; D3DSURFACE_DESC dscD; D3DCAPS9 m_Caps; m_pDev->GetRenderTarget(0,&pSfC); m_pDev->GetDepthStencilSurface(&pSfD); pSfC->GetDesc(&dscC); pSfD->GetDesc(&dscD); m_pDev->GetDeviceCaps(&m_Caps); pSfC->Release(); pSfD->Release(); if(m_iW<0) m_iW = dscC.Width; if(m_iH<0) m_iH = dscC.Height; m_dC = dscC.Format; m_dD = dscD.Format; if(LCX_TARGET_HDR16 == m_nType) m_dC = D3DFMT_A16B16G16R16F; if(LCX_TARGET_HDR32 == m_nType) m_dC = D3DFMT_A32B32G32R32F; hr = D3DXCreateRenderToSurface(m_pDev , m_iW , m_iH , (D3DFORMAT)m_dC , TRUE , (D3DFORMAT)m_dD , &m_pRts); if(FAILED(hr)) return -1; hr = D3DXCreateTexture(m_pDev , m_iW , m_iH , dMip , D3DUSAGE_RENDERTARGET , (D3DFORMAT)m_dC , D3DPOOL_DEFAULT , &m_pTxP); if(FAILED(hr)) return -1; hr = m_pTxP->GetSurfaceLevel(0, &m_pSfc); if(FAILED(hr)) return -1; // Clear 0x0 m_pDev->ColorFill(m_pSfc, NULL, 0x0); return hr; }
HRESULT HookIDirect3DDevice9::GetDepthStencilSurface(LPVOID _this, IDirect3DSurface9** ppZStencilSurface) { LOG_API(); return pD3Dev->GetDepthStencilSurface(ppZStencilSurface); }
// `使用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 ); }
bool ReInitResourceDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); GutGetWindowSize(g_iWidth, g_iHeight); g_proj_matrix = GutMatrixOrthoRH_DirectX(g_iWidth, g_iHeight, 0.0f, 100.0f); int w = g_iWidth; int h = g_iHeight; g_ImageInfo.m_iWidth = g_iWidth; g_ImageInfo.m_iHeight = g_iHeight; g_ImageInfo.m_bProcedure = true; //D3DFORMAT fmt = D3DFMT_G16R16; D3DFORMAT fmt = D3DFMT_A8R8G8B8; device->SetRenderState(D3DRS_LIGHTING, FALSE); device->CreateTexture( w, h, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &g_pTextures[TEX_HEIGHT0], NULL); if ( NULL==g_pTextures[TEX_HEIGHT0] ) return false; g_pTextures[TEX_HEIGHT0]->GetSurfaceLevel(0, &g_pSurfaces[TEX_HEIGHT0]); if ( NULL==g_pSurfaces[TEX_HEIGHT0] ) return false; device->CreateTexture( w, h, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &g_pTextures[TEX_HEIGHT1], NULL); if ( NULL==g_pTextures[TEX_HEIGHT1] ) return false; if ( NULL==g_pTextures[TEX_HEIGHT1] ) return false; g_pTextures[TEX_HEIGHT1]->GetSurfaceLevel(0, &g_pSurfaces[TEX_HEIGHT1]); device->CreateTexture( w, h, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &g_pTextures[TEX_HEIGHT2], NULL); if ( NULL==g_pTextures[TEX_HEIGHT2] ) return false; g_pTextures[TEX_HEIGHT2]->GetSurfaceLevel(0, &g_pSurfaces[TEX_HEIGHT2]); if ( NULL==g_pSurfaces[TEX_HEIGHT2] ) return false; device->CreateTexture( w, h, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pTextures[TEX_NORMAL], NULL); if ( NULL==g_pTextures[TEX_NORMAL] ) return false; g_pTextures[TEX_NORMAL]->GetSurfaceLevel(0, &g_pSurfaces[TEX_NORMAL]); if ( NULL==g_pSurfaces[TEX_NORMAL] ) return false; device->GetRenderTarget(0, &g_pMainFramebuffer); device->GetDepthStencilSurface(&g_pMainDepthbuffer); device->SetRenderTarget(0, g_pSurfaces[0]); device->SetRenderTarget(1, g_pSurfaces[1]); device->SetRenderTarget(2, g_pSurfaces[2]); device->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 1.0f, 0); device->SetRenderTarget(0, g_pMainFramebuffer); device->SetRenderTarget(1, NULL); device->SetRenderTarget(2, NULL); device->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE); device->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL); device->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL); return true; }
bool ReInitResourceDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); device->SetRenderState(D3DRS_LIGHTING, FALSE); int w, h; GutGetWindowSize(w, h); g_ImageInfo.m_iWidth = w; g_ImageInfo.m_iHeight = h; float aspect = (float)h/(float)w; g_proj_matrix = GutMatrixPerspectiveRH_DirectX(g_fFovW, aspect, g_fNearZ, g_fFarZ); device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *)&g_proj_matrix); int width = w; int height = h; D3DFORMAT fmt = D3DFMT_A16B16G16R16F; device->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &g_pFrameBuffer[FULLSIZE], NULL); device->CreateTexture(256, 256, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &g_pFrameBuffer[DOWNSAMPLED_256x256], NULL); device->CreateTexture(64, 64, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &g_pFrameBuffer[DOWNSAMPLED_64x64], NULL); device->CreateTexture(16, 16, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &g_pFrameBuffer[DOWNSAMPLED_16x16], NULL); device->CreateTexture(4, 4, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &g_pFrameBuffer[DOWNSAMPLED_4x4], NULL); device->CreateTexture(1, 1, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &g_pFrameBuffer[LUMINANCE_PREVIOUS], NULL); device->CreateTexture(1, 1, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &g_pFrameBuffer[LUMINANCE_CURRENT], NULL); device->CreateTexture(1, 1, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &g_pFrameBuffer[LUMINANCE_TEMP], NULL); for ( int i=0; i<NUM_FRAMEBUFFERS; i++ ) { if ( g_pFrameBuffer[i]==NULL ) return false; g_pFrameBuffer[i]->GetSurfaceLevel(0, &g_pFrameSurface[i]); } for ( int i=0; i<4; i++ ) { device->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); device->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); device->SetSamplerState(i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); device->SetSamplerState(i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); } device->GetRenderTarget(0, &g_pMainSurface); g_pMainSurface->Release(); device->GetDepthStencilSurface(&g_pDepthStencilSurface); g_pDepthStencilSurface->Release(); return true; }
// 使用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 ); }
static LPDIRECT3DTEXTURE9 BlurTexture(LPDIRECT3DTEXTURE9 pSource) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); Matrix4x4 identiyMatrix = Matrix4x4::IdentityMatrix(); device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &identiyMatrix); device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &identiyMatrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &identiyMatrix); LPDIRECT3DSURFACE9 pFrameBufferBackup, pDepthBufferBackup; device->GetRenderTarget(0, &pFrameBufferBackup); pFrameBufferBackup->Release(); device->GetDepthStencilSurface(&pDepthBufferBackup); pDepthBufferBackup->Release(); device->SetRenderState(D3DRS_CULLMODE , D3DCULL_NONE); float weight_table[7] = {1.0f, 3.0f, 4.0f, 5.0f, 4.0f, 3.0f, 1.0f}; float uv_offset_table[7] = {-3.0f, -2.0f, -1.0f, 0.0f, 1.0f, 2.0f, 3.0f}; float sum = 0.0f; for ( int i=0; i<7; i++ ) { sum += weight_table[i]; } for ( int i=0; i<7; i++ ) { weight_table[i] /= sum; } Vector4 vOneTexel_X(1.0f/(float)g_framebuffer_w, 0.0f, 0.0f, 0.0f); Vector4 vOneTexel_Y(0.0f, 1.0f/(float)g_framebuffer_h, 0.0f, 0.0f); Vertex_VT temp_quad[4]; LPDIRECT3DSURFACE9 pSurface; g_pBlurTextures[0]->GetSurfaceLevel(0, &pSurface); device->SetRenderTarget(0, pSurface); device->SetDepthStencilSurface(NULL); device->SetRenderState(D3DRS_ZENABLE, FALSE); device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 0), 1.0f, 0); device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); device->SetTexture(0, pSource); device->SetFVF(D3DFVF_XYZW|D3DFVF_TEX1); // 設定顏色來源為 texture factor * texture device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); // X方向blur for ( int i=0; i<7; i++ ) { Vector4 vOffset = uv_offset_table[i] * vOneTexel_X; for ( int p=0; p<4; p++ ) { temp_quad[p].m_Position = g_Quad[p].m_Position; temp_quad[p].m_Texcoord = g_Quad[p].m_Texcoord + vOffset; } int weight = (int) (weight_table[i] * 255); device->SetRenderState(D3DRS_TEXTUREFACTOR, D3DCOLOR_RGBA(weight, weight, weight, weight)); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, temp_quad, sizeof(Vertex_VT)); } pSurface->Release(); g_pBlurTextures[1]->GetSurfaceLevel(0, &pSurface); device->SetRenderTarget(0, pSurface); device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 0), 1.0f, 0); device->SetTexture(0, g_pBlurTextures[0]); // Y方向blur for ( int i=0; i<7; i++ ) { Vector4 vOffset = uv_offset_table[i] * vOneTexel_Y; for ( int p=0; p<4; p++ ) { temp_quad[p].m_Position = g_Quad[p].m_Position; temp_quad[p].m_Texcoord = g_Quad[p].m_Texcoord + vOffset; } int weight = (int) (weight_table[i] * 255); device->SetRenderState(D3DRS_TEXTUREFACTOR, D3DCOLOR_RGBA(weight, weight, weight, weight)); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, temp_quad, sizeof(Vertex_VT)); } pSurface->Release(); // 還原設定 device->SetRenderState(D3DRS_TEXTUREFACTOR, D3DCOLOR_RGBA(255, 255, 255, 255)); device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); device->SetRenderState(D3DRS_ZENABLE, TRUE); device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); device->SetRenderTarget(0, pFrameBufferBackup); device->SetDepthStencilSurface(pDepthBufferBackup); return g_pBlurTextures[1]; }
// 初期化 bool D3D::Init( HWND hWnd, BOOL iswindow ) { // DirectX初期化 s_lpD3D = Direct3DCreate9( D3D_SDK_VERSION ); if( s_lpD3D == NULL ) { return false; } // パラメータ設定 s_D3DPP.BackBufferWidth = WINDOW_WIDTH; // バックバッファ幅 s_D3DPP.BackBufferHeight = WINDOW_HEIGHT; // バックバッファ高さ s_D3DPP.BackBufferFormat = D3DFMT_A8R8G8B8; // バックバッファフォーマット s_D3DPP.BackBufferCount = 1; // バックバッファ数 s_D3DPP.MultiSampleType = D3DMULTISAMPLE_NONE; // マルチサンプリングタイプ s_D3DPP.MultiSampleQuality = 0; // 品質レベル s_D3DPP.SwapEffect = D3DSWAPEFFECT_FLIP; // スワップエフェクト s_D3DPP.hDeviceWindow = hWnd; // ウィンドウハンドル s_D3DPP.Windowed = iswindow; // ウィンドウモード s_D3DPP.EnableAutoDepthStencil = TRUE; // サーフェスフォーマット s_D3DPP.AutoDepthStencilFormat = D3DFMT_D24S8; // ステンシルバッファフォーマット s_D3DPP.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; // 画面フリップ時の効果オプション s_D3DPP.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; // フルスクリーン時のリフレッシュレート s_D3DPP.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; // フリップのタイミング設定 // デバイス作成 // ハードウェア HAL HRESULT hr = s_lpD3D->CreateDevice( D3DADAPTER_DEFAULT, // アダプタ D3DDEVTYPE_HAL, // デバイスタイプ hWnd, // ウィンドウハンドル D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED,// デバイス生成オプション &s_D3DPP, // 設定したパラメータ &s_lpD3DDevice ); // 格納するデバイス // 失敗すれば ソフトウェア HAL if( FAILED( hr ) ) { hr = s_lpD3D->CreateDevice( D3DADAPTER_DEFAULT, // アダプタ D3DDEVTYPE_HAL, // デバイスタイプ hWnd, // ウィンドウハンドル D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED,// デバイス生成オプション &s_D3DPP, // 設定したパラメータ &s_lpD3DDevice ); // 格納するデバイス // それでも失敗すれば ソフトウェア REF if( FAILED( hr ) ) { hr = s_lpD3D->CreateDevice( D3DADAPTER_DEFAULT, // アダプタ D3DDEVTYPE_REF, // デバイスタイプ hWnd, // ウィンドウハンドル D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED,// デバイス生成オプション &s_D3DPP, // 設定したパラメータ &s_lpD3DDevice ); // 格納するデバイス // ここで失敗すればもう無理 if( ErrorMessage( hr, "デバイス作成失敗") ) { return false; } } } // レンダーターゲット格納 s_lpD3DDevice->GetRenderTarget( 0, &s_lpBackBuffer ); s_lpD3DDevice->GetDepthStencilSurface( &s_lpZBuffer ); // レンダーステート設定 s_lpD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); s_lpD3DDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); s_lpD3DDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE ); s_lpD3DDevice->SetRenderState( D3DRS_LIGHTING, TRUE ); s_lpD3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE ); s_lpD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); s_lpD3DDevice->SetRenderState( D3DRS_ALPHAREF, TRUE ); s_lpD3DDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL ); // アルファ値の掛け算指定 s_lpD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); s_lpD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); s_lpD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE ); return true; }
// 描画 void CDOFText::Draw() { LPDIRECT3DDEVICE9 lpDevice = D3D::GetDevice(); // シーン描画開始 D3D::Begin(); // カメラ、投影設定 m_Camera.SetCameraPos( &D3DXVECTOR3( 0, 0, -10 ) ); lpDevice->SetTransform( D3DTS_VIEW, m_Camera.GetMatrix() ); lpDevice->SetTransform( D3DTS_PROJECTION, m_Proj.GetMatrix() ); // バックバッファ保存 lpDevice->GetRenderTarget( 0, &m_lpBackBuffer ); lpDevice->GetDepthStencilSurface( &m_lpZBuffer ); CXfile::SetDrawShader( false ); // パス1 // テクスチャに描画 // レンダーターゲット変更 lpDevice->SetRenderTarget( 0, m_SceneTex.GetSurface() ); lpDevice->SetDepthStencilSurface( m_SceneTex.GetZbuffer() ); lpDevice->Clear( 0,NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0, 0xff, 0xff ), 1.0f, 0); lpDevice->SetRenderState( D3DRS_FOGENABLE, TRUE ); lpDevice->SetRenderState( D3DRS_FOGCOLOR, D3DCOLOR_XRGB( 0, 0x00, 0x80 ) ); lpDevice->SetRenderState( D3DRS_FOGTABLEMODE, D3DFOG_LINEAR ); lpDevice->SetRenderState( D3DRS_FOGSTART, GetAddress( 0.f ) ); lpDevice->SetRenderState( D3DRS_FOGEND, GetAddress( 100.f ) ); // 描画 CMatrix mRot, mTrans; mRot.SetRotY( timeGetTime() / 2 % 360 ); lpDevice->SetRenderState( D3DRS_LIGHTING, TRUE ); // テストメッシュ for( int i = 0; i < 5; i++ ) { mTrans.SetTrans( -2 + i * 2, 0, -3 + i * 3 ); lpDevice->SetTransform( D3DTS_WORLD, &(mRot * mTrans) ); m_Mesh.Draw( lpDevice ); } lpDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); lpDevice->SetTransform( D3DTS_WORLD, &CMatrix() ); m_Sphere.Draw( lpDevice ); // パス2 // 縮小させる // レンダーターゲット変更 // ぼかし用(ビューポートも変える) D3DVIEWPORT9 Vp = { 0, 0, WINDOW_WIDTH / 4, WINDOW_HEIGHT / 4, 0.f, 1.f }; lpDevice->SetViewport( &Vp ); lpDevice->SetRenderTarget( 0, m_MiniSizeTex.GetSurface() ); lpDevice->SetDepthStencilSurface( m_MiniSizeTex.GetZbuffer() ); lpDevice->Clear( 0,NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0xff, 0xff, 0 ), 1.0f, 0); lpDevice->SetTransform( D3DTS_VIEW, &CMatrix() ); lpDevice->SetTransform( D3DTS_PROJECTION, &CMatrix() ); // テクスチャに描画したものを流す m_BlurShader.SetTexture( "g_Texture", m_SceneTex.GetTexture() ); // 解像度を渡す D3DXVECTOR2 TexPos( 0.5f / Vp.Width, 0.5f / Vp.Height ); m_BlurShader.SetValue( "g_Offset", &TexPos, sizeof(D3DXVECTOR2) ); // シェーダー描画開始 m_BlurShader.Begin(); m_BlurShader.BeginPass( 0 ); m_Scene.SetVertex( 2 ); m_Scene.Draw( lpDevice ); m_BlurShader.EndPass(); m_BlurShader.End(); // パス3 // ぼかし入れる // レンダーターゲット変更 lpDevice->SetRenderTarget( 0, m_BlurTex.GetSurface() ); lpDevice->SetDepthStencilSurface( m_BlurTex.GetZbuffer() ); lpDevice->SetViewport( &Vp ); lpDevice->Clear( 0,NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0xff, 0xff, 0 ), 1.0f, 0); // 縮小画像をシェーダーに流す m_BlurShader.SetTexture( "g_Texture", m_MiniSizeTex.GetTexture() ); // シェーダー描画開始 m_BlurShader.Begin(); m_BlurShader.BeginPass( 1 ); lpDevice->SetFVF( CBoard::FVF_VERTEX ); m_Scene.SetVertex( 2 ); m_Scene.Draw( lpDevice ); m_BlurShader.EndPass(); m_BlurShader.End(); // パス4 // 深度計算を行う // レンダーターゲット変更 // (ビューポートももとに戻す) Vp.Width = WINDOW_WIDTH; Vp.Height = WINDOW_HEIGHT; lpDevice->SetViewport( &Vp ); lpDevice->SetRenderTarget( 0, m_DepthTex.GetSurface() ); lpDevice->SetDepthStencilSurface( m_DepthTex.GetZbuffer() ); lpDevice->Clear( 0,NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0, 0xff, 0xff ), 1.0f, 0); // シェーダーに値を渡す lpDevice->SetTransform( D3DTS_VIEW, m_Camera.GetMatrix() ); lpDevice->SetTransform( D3DTS_PROJECTION, m_Proj.GetMatrix() ); m_DepthShader.SetValue( "g_Proj", m_Proj.GetMatrix(), sizeof(D3DXMATRIX) ); m_DepthShader.SetValue( "g_View", m_Camera.GetMatrix(), sizeof(D3DXMATRIX) ); // シェーダー描画開始 m_DepthShader.Begin(); m_DepthShader.BeginPass( 0 ); CXfile::SetDrawShader( true ); //CXfile::SetShaderDevice( &m_DepthShader, "g_mWVP" ); for( int i = 0; i < 5; i++ ) { mTrans.SetTrans( -2 + i * 2, 0, -3 + i * 3 ); lpDevice->SetTransform( D3DTS_WORLD, &(mRot * mTrans) ); m_Mesh.Draw( lpDevice ); } //m_DepthShader.SetValue( "g_World", &CMatrix(), sizeof(D3DXMATRIX) ); lpDevice->SetTransform( D3DTS_WORLD, &CMatrix() ); m_Sphere.Draw( lpDevice ); m_DepthShader.EndPass(); m_DepthShader.End(); // パス5 // 被写界深度適用 // バックバッファに描画 // バックバッファにレンダーターゲットを戻す lpDevice->SetRenderTarget( 0, m_lpBackBuffer ); lpDevice->SetDepthStencilSurface( m_lpZBuffer ); Vp.Width = WINDOW_WIDTH; Vp.Height= WINDOW_HEIGHT; lpDevice->SetViewport( &Vp ); lpDevice->Clear( 0,NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0xff, 0, 0xff ), 1.0f, 0); // シェーダーに値を渡す m_DOFShader.SetTexture( "g_SceneTex", m_SceneTex.GetTexture() ); // シーン m_DOFShader.SetTexture( "g_BlurTex", m_BlurTex.GetTexture() ); // ぼかし m_DOFShader.SetTexture( "g_DepthTex", m_DepthTex.GetTexture() ); // 深度 lpDevice->SetTransform( D3DTS_VIEW, &CMatrix() ); lpDevice->SetTransform( D3DTS_PROJECTION, &CMatrix() ); lpDevice->SetTransform( D3DTS_WORLD, &CMatrix() ); // 板ポリゴンに描画 m_DOFShader.Begin(); m_DOFShader.BeginPass( 0 ); m_Scene.SetVertex( 2 ); m_Scene.Draw( lpDevice ); m_DOFShader.EndPass(); m_DOFShader.End(); /*Vp.Y = 300.f; Vp.Height = 600.f; lpDevice->SetViewport( &Vp );*/ DrawSceneByPolygon(lpDevice); SAFE_RELEASE( m_lpBackBuffer ); SAFE_RELEASE( m_lpZBuffer ); // シーン終了 D3D::End(); }