// 3D 물체등을 그린다. void RenderScene() { // 뷰 행렬을 만든다. D3DXMATRIXA16 matView; D3DXVECTOR3 vEyePt(gWorldCameraPosition.x, gWorldCameraPosition.y, gWorldCameraPosition.z); D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f); D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec); // 투영행렬을 만든다. D3DXMATRIXA16 matProjection; D3DXMatrixPerspectiveFovLH(&matProjection, FOV, ASPECT_RATIO, NEAR_PLANE, FAR_PLANE); // 프레임마다 0.4도씩 회전을 시킨다. gRotationY += 0.4f * PI / 180.0f; if (gRotationY > 2 * PI) { gRotationY -= 2 * PI; } // 월드행렬을 만든다. D3DXMATRIXA16 matWorld; D3DXMatrixRotationY(&matWorld, gRotationY); // 월드/뷰/투영행렬을 미리 곱한다. D3DXMATRIXA16 matWorldView; D3DXMATRIXA16 matWorldViewProjection; D3DXMatrixMultiply(&matWorldView, &matWorld, &matView); D3DXMatrixMultiply(&matWorldViewProjection, &matWorldView, &matProjection); // 쉐이더 전역변수들을 설정 gpEnvironmentMappingShader->SetMatrix("gWorldMatrix", &matWorld); gpEnvironmentMappingShader->SetMatrix("gWorldViewProjectionMatrix", &matWorldViewProjection); gpEnvironmentMappingShader->SetVector("gWorldLightPosition", &gWorldLightPosition); gpEnvironmentMappingShader->SetVector("gWorldCameraPosition", &gWorldCameraPosition); gpEnvironmentMappingShader->SetVector("gLightColor", &gLightColor); gpEnvironmentMappingShader->SetTexture("DiffuseMap_Tex", gpStoneDM); gpEnvironmentMappingShader->SetTexture("SpecularMap_Tex", gpStoneSM); gpEnvironmentMappingShader->SetTexture("NormalMap_Tex", gpStoneNM); gpEnvironmentMappingShader->SetTexture("EnvironmentMap_Tex", gpSnowENV); // 쉐이더를 시작한다. UINT numPasses = 0; gpEnvironmentMappingShader->Begin(&numPasses, NULL); { for (UINT i = 0; i < numPasses; ++i) { gpEnvironmentMappingShader->BeginPass(i); { // 구체를 그린다. gpTeapot->DrawSubset(0); } gpEnvironmentMappingShader->EndPass(); } } gpEnvironmentMappingShader->End(); }
// 3D 물체등을 그린다. void RenderScene() { // 뷰행렬 초기화. D3DXMATRIXA16 matView; // D3DXVECTOR3 vEyePt(0.0f, 0.0f, -200.0f); D3DXVECTOR3 vEyePt(gWorldCameraPosition.x, gWorldCameraPosition.y, gWorldCameraPosition.z); D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f); D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec); // 투영행렬 초기화. D3DXMATRIXA16 matProjection; D3DXMatrixPerspectiveFovLH(&matProjection, FOV, ASPECT_RATIO, NEAR_PLANE, FAR_PLANE); // 회전. gRotationY += ((0.4f * PI) / 180.0f); if (gRotationY > 2 * PI) gRotationY -= 2 * PI; // 월드행렬 초기화. D3DXMATRIXA16 matWorld; // D3DXMatrixIdentity(&matWorld); D3DXMatrixRotationY(&matWorld, gRotationY); // 쉐이더에 전달. gpTextureMappingShader->SetMatrix("gWorldMatrix", &matWorld); gpTextureMappingShader->SetMatrix("gViewMatrix", &matView); gpTextureMappingShader->SetMatrix("gProjectionMatrix", &matProjection); gpTextureMappingShader->SetVector("gWorldLightPosition", &gWorldLightPosition); gpTextureMappingShader->SetVector("gWorldCameraPosition", &gWorldCameraPosition); // gpTextureMappingShader->SetTexture("DiffuseMap_Tex", gpEarthDM); // 쉐이더 적용. UINT numPasses = 0; gpTextureMappingShader->Begin(&numPasses, NULL); for (UINT i = 0; i < numPasses; ++i) { gpTextureMappingShader->BeginPass(i); gpSphere->DrawSubset(0); gpTextureMappingShader->EndPass(); } gpTextureMappingShader->End(); }
void DXDirectionalLight::BlurShadowMap(LPDIRECT3DDEVICE9 device, LPD3DXEFFECT effect) { if( !shadowmap || !blur || !blurdeclforpointfordirectional || !needsblur ) return; float blurvertices[36] = { -0.5f, -0.5f, 0, 1, 0, 0, (float)shadowsize - 0.5f, -0.5f, 0, 1, 1, 0, -0.5f, (float)shadowsize - 0.5f, 0, 1, 0, 1, -0.5f, (float)shadowsize - 0.5f, 0, 1, 0, 1, (float)shadowsize - 0.5f, -0.5f, 0, 1, 1, 0, (float)shadowsize - 0.5f, (float)shadowsize - 0.5f, 0, 1, 1, 1 }; LPDIRECT3DSURFACE9 surface = NULL; D3DXVECTOR4 texelsize(1.0f / shadowsize, 0, 0, 0); UINT stride = 6 * sizeof(float); device->SetVertexDeclaration(blurdeclforpointfordirectional); // x blur->GetSurfaceLevel(0, &surface); effect->SetVector("texelSize", &texelsize); effect->CommitChanges(); device->SetRenderTarget(0, surface); device->Clear(0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0); device->SetTexture(0, shadowmap); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, blurvertices, stride); surface->Release(); std::swap(texelsize.x, texelsize.y); // y shadowmap->GetSurfaceLevel(0, &surface); effect->SetVector("texelSize", &texelsize); effect->CommitChanges(); device->SetRenderTarget(0, surface); device->Clear(0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0); device->SetTexture(0, blur); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, blurvertices, stride); surface->Release(); if( shadowtype == Static ) needsblur = false; }
void AutoExposure(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); D3DXHANDLE shader = g_pExposureEffect->GetTechniqueByName("AutoExposure"); g_pExposureEffect->SetTechnique(shader); Vector4 vMiddleGray(0.5f); Vector4 vMultiplierClamp(0.2f, 3.0f, 0.0f, 0.0f); D3DXHANDLE middlegray_var = g_pExposureEffect->GetParameterByName(NULL, "vMiddleGray"); D3DXHANDLE clamp_var = g_pExposureEffect->GetParameterByName(NULL, "vMultiplierClamp"); D3DXHANDLE image0_var = g_pExposureEffect->GetParameterByName(NULL, "Image"); D3DXHANDLE image1_var = g_pExposureEffect->GetParameterByName(NULL, "Image2"); g_pExposureEffect->SetVector(middlegray_var, (D3DXVECTOR4*)&vMiddleGray); g_pExposureEffect->SetVector(clamp_var, (D3DXVECTOR4*)&vMultiplierClamp); g_pExposureEffect->SetTexture(image0_var, g_pFrameBuffer[FULLSIZE]); g_pExposureEffect->SetTexture(image1_var, g_pFrameBuffer[LUMINANCE_TEMP]); g_pExposureEffect->Begin(NULL, 0); g_pExposureEffect->BeginPass(0); DrawFullScreenQuad(&g_ImageInfo); g_pExposureEffect->EndPass(); g_pExposureEffect->End(); }
static void WaterSimulation(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); device->SetRenderTarget(0, g_pSurfaces[TEX_HEIGHT2]); device->SetDepthStencilSurface(NULL); D3DXHANDLE shader = g_pWaterEffect->GetTechniqueByName("WaterSimulation"); D3DXHANDLE heightmap_current_var = g_pWaterEffect->GetParameterByName(NULL, "heightmap_current"); D3DXHANDLE heightmap_prev_var = g_pWaterEffect->GetParameterByName(NULL, "heightmap_prev"); D3DXHANDLE texturesize_var = g_pWaterEffect->GetParameterByName(NULL, "texture_size"); D3DXHANDLE damping_var = g_pWaterEffect->GetParameterByName(NULL, "fDamping"); Vector4 texturesize; texturesize[0] = 1.0f/(float)g_ImageInfo.m_iWidth; texturesize[1] = 1.0f/(float)g_ImageInfo.m_iHeight; texturesize[2] = (float)g_ImageInfo.m_iWidth; texturesize[3] = (float)g_ImageInfo.m_iHeight; g_pWaterEffect->SetTechnique(shader); g_pWaterEffect->SetTexture(heightmap_prev_var, g_pTextures[TEX_HEIGHT0]); g_pWaterEffect->SetTexture(heightmap_current_var, g_pTextures[TEX_HEIGHT1]); g_pWaterEffect->SetFloat(damping_var, 0.99f); g_pWaterEffect->SetVector(texturesize_var, (D3DXVECTOR4*)&texturesize); g_pWaterEffect->Begin(NULL,0); g_pWaterEffect->BeginPass(0); GutDrawFullScreenQuad_DX9(&g_ImageInfo); g_pWaterEffect->EndPass(); g_pWaterEffect->End(); }
void ConverToLogLuminance(LPDIRECT3DTEXTURE9 pSource, sImageInfo *pInfo) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); device->SetRenderTarget(0, g_pFrameSurface[DOWNSAMPLED_256x256]); device->SetDepthStencilSurface(NULL); D3DXHANDLE shader = g_pExposureEffect->GetTechniqueByName("LogLuminance"); g_pExposureEffect->SetTechnique(shader); D3DXHANDLE tablevar = g_pExposureEffect->GetParameterByName(NULL, "vLuminanceTable"); D3DXHANDLE imagevar = g_pExposureEffect->GetParameterByName(NULL, "Image"); Vector4 vTable(0.21f, 0.71f, 0.072f); g_pExposureEffect->SetVector(tablevar, (D3DXVECTOR4*)&vTable); g_pExposureEffect->SetTexture(imagevar, pSource); g_pExposureEffect->Begin(NULL, 0); g_pExposureEffect->BeginPass(0); DrawFullScreenQuad(pInfo); g_pExposureEffect->EndPass(); g_pExposureEffect->End(); }
//************************************************************************************************************* void LensFlare() { texelsize.x = 2.0f / (float)screenwidth; texelsize.y = 2.0f / (float)screenheight; hdreffect->SetTechnique("ghost"); hdreffect->SetVector("texelsize", &texelsize); device->SetRenderTarget(0, ghostsurfaces[0]); device->SetTexture(0, dstargets[0]); device->SetTexture(1, dstargets[1]); device->SetTexture(2, dstargets[2]); device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); tmpvert[6] = tmpvert[24] = tmpvert[30] = (float)screenwidth / 2.0f - 0.5f; tmpvert[13] = tmpvert[19] = tmpvert[31] = (float)screenheight / 2.0f - 0.5f; // 1 iteration only (not too spectatular...) hdreffect->Begin(NULL, 0); hdreffect->BeginPass(0); { device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, tmpvert, sizeof(D3DXVECTOR4) + sizeof(D3DXVECTOR2)); } hdreffect->EndPass(); hdreffect->End(); }
//************************************************************************************************************* void DownSample() { hdreffect->SetTechnique("downsample"); hdreffect->Begin(NULL, 0); hdreffect->BeginPass(0); for( int i = 1; i < 5; ++i ) { device->SetRenderTarget(0, dssurfaces[i]); device->SetTexture(0, dstargets[i - 1]); texelsize.x = (float)(2 << i) / (float)screenwidth; texelsize.y = (float)(2 << i) / (float)screenheight; tmpvert[6] = tmpvert[24] = tmpvert[30] = (float)screenwidth / ((float)(2 << i)) - 0.5f; tmpvert[13] = tmpvert[19] = tmpvert[31] = (float)screenheight / ((float)(2 << i)) - 0.5f; hdreffect->SetVector("texelsize", &texelsize); hdreffect->CommitChanges(); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, tmpvert, sizeof(D3DXVECTOR4) + sizeof(D3DXVECTOR2)); } hdreffect->EndPass(); hdreffect->End(); }
void DXPointLight::DrawShadowMap(LPDIRECT3DDEVICE9 device, LPD3DXEFFECT effect, void (*drawcallback)(LPD3DXEFFECT)) { if( !shadowmap || !needsredraw ) return; LPDIRECT3DSURFACE9 surface = NULL; D3DXMATRIX vp; effect->SetVector("lightPos", (D3DXVECTOR4*)&position); for( int j = 0; j < 6; ++j ) { GetViewProjMatrix(vp, j); effect->SetMatrix("matViewProj", &vp); shadowmap->GetCubeMapSurface((D3DCUBEMAP_FACES)j, 0, &surface); device->SetRenderTarget(0, surface); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0); drawcallback(effect); surface->Release(); } if( shadowtype == Static ) needsredraw = false; }
//************************************************************************************************************* void BlurTexture(LPDIRECT3DTEXTURE9 tex) { LPDIRECT3DSURFACE9 surface = NULL; LPDIRECT3DSURFACE9 blursurface = NULL; LPDIRECT3DTEXTURE9 blurtex = NULL; D3DXVECTOR4 texelsize(1.0f / SHADOWMAP_SIZE, 0, 0, 0); D3DSURFACE_DESC desc; tex->GetLevelDesc(0, &desc); if( desc.Format == D3DFMT_A8R8G8B8 ) blurtex = blurARGB8; // for convolution else blurtex = blurRGBA32F; // for others blurtex->GetSurfaceLevel(0, &blursurface); tex->GetSurfaceLevel(0, &surface); device->SetRenderTarget(0, blursurface); device->SetTexture(0, tex); device->SetVertexDeclaration(vertexdecl); boxblur5x5->SetVector("texelSize", &texelsize); boxblur5x5->Begin(NULL, 0); boxblur5x5->BeginPass(0); { device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, &vertices[0], 6 * sizeof(float)); std::swap(texelsize.x, texelsize.y); boxblur5x5->SetVector("texelSize", &texelsize); boxblur5x5->CommitChanges(); device->SetRenderTarget(0, surface); device->SetTexture(0, blurtex); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, &vertices[0], 6 * sizeof(float)); } boxblur5x5->EndPass(); boxblur5x5->End(); surface->Release(); blursurface->Release(); }
//--------------------------------------------------------------------------------------- // マテリアル設定(&コミット) //--------------------------------------------------------------------------------------- void SetMaterialShader(D3DMATERIAL9* pMaterial, LPDIRECT3DTEXTURE9 pTexture) { if (pMaterial) { g_pFX->SetVector(g_hDiffuse, (LPD3DXVECTOR4)&pMaterial->Diffuse); g_pFX->SetVector(g_hSpecular, (LPD3DXVECTOR4)&pMaterial->Specular); g_pFX->SetFloat(g_hPower, pMaterial->Power); g_pFX->SetVector(g_hAmbient, (LPD3DXVECTOR4)&pMaterial->Ambient); } if (pTexture) { g_pFX->SetTexture(g_hTexture, pTexture); g_pFX->SetBool(g_hTexEnable, TRUE); } else { g_pFX->SetBool(g_hTexEnable, FALSE); } g_pFX->CommitChanges(); }
//************************************************************************************************************* void DrawScene(LPD3DXEFFECT effect) { D3DXMATRIX world; D3DXMATRIX inv; D3DXVECTOR4 uv(3, 3, 0, 0); D3DXMatrixScaling(&world, 5, 0.1f, 5); D3DXMatrixInverse(&inv, NULL, &world); effect->SetMatrix("matWorld", &world); effect->SetMatrix("matWorldInv", &inv); effect->SetVector("uv", &uv); effect->Begin(0, 0); effect->BeginPass(0); { device->SetTexture(0, texture2); shadowreceiver->DrawSubset(0); if( !drawsilhouette ) { device->SetTexture(0, texture1); uv.x = uv.y = 1; effect->SetVector("uv", &uv); for( int i = 0; i < NUM_OBJECTS; ++i ) { D3DXMatrixInverse(&inv, NULL, &objects[i].world); effect->SetMatrix("matWorld", &objects[i].world); effect->SetMatrix("matWorldInv", &inv); effect->CommitChanges(); objects[i].object->DrawSubset(0); } } } effect->EndPass(); effect->End(); }
//************************************************************************************************************* void Star() { tmpvert[6] = tmpvert[24] = tmpvert[30] = (float)screenwidth / 4.0f - 0.5f; tmpvert[13] = tmpvert[19] = tmpvert[31] = (float)screenheight / 4.0f - 0.5f; texelsize.x = 4.0f / (float)screenwidth; texelsize.y = 4.0f / (float)screenheight; hdreffect->SetTechnique("star"); hdreffect->SetVector("texelsize", &texelsize); hdreffect->Begin(NULL, 0); hdreffect->BeginPass(0); for( int i = 0; i < 4; ++i ) { hdreffect->SetInt("stardir", i); for( int j = 0; j < 3; ++j ) { int ind = (j % 2); device->SetRenderTarget(0, starsurfaces[i][ind]); device->SetTexture(0, (j == 0 ? dstargets[1] : startargets[i][1 - ind])); hdreffect->SetInt("starpass", j); hdreffect->CommitChanges(); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, tmpvert, sizeof(D3DXVECTOR4) + sizeof(D3DXVECTOR2)); } } hdreffect->EndPass(); hdreffect->End(); // combine star textures hdreffect->SetTechnique("starcombine"); device->SetRenderTarget(0, blursurfaces[1]); device->SetTexture(0, startargets[0][0]); device->SetTexture(1, startargets[1][0]); device->SetTexture(2, startargets[2][0]); device->SetTexture(3, startargets[3][0]); hdreffect->Begin(NULL, 0); hdreffect->BeginPass(0); { device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, tmpvert, sizeof(D3DXVECTOR4) + sizeof(D3DXVECTOR2)); } hdreffect->EndPass(); hdreffect->End(); }
//************************************************************************************************************* void RenderScene(LPD3DXEFFECT effect, int what) { D3DXMATRIX inv; D3DXVECTOR4 uv(1, 1, 1, 1); D3DXVECTOR4 spec(1, 1, 1, 1); for( int i = 0; i < numobjects; ++i ) { SceneObject& obj = objects[i]; if( obj.behavior == what ) { D3DXMatrixInverse(&inv, 0, &obj.world); effect->SetMatrix("matWorld", &obj.world); effect->SetMatrix("matWorldInv", &inv); if( obj.type == FLOOR ) { uv.x = uv.y = 3; spec = D3DXVECTOR4(0.2f, 0.2f, 0.2f, 20.0f); effect->SetVector("uv", &uv); effect->SetVector("matSpecular", &spec); effect->CommitChanges(); device->SetTexture(0, texture2); box->DrawSubset(0); } else if( obj.type == CRATE ) { uv.x = uv.y = 1; spec = D3DXVECTOR4(0.2f, 0.2f, 0.2f, 20.0f); effect->SetVector("uv", &uv); effect->SetVector("matSpecular", &spec); effect->CommitChanges(); device->SetTexture(0, texture3); box->DrawSubset(0); } else if( obj.type == SKULL ) { uv.x = uv.y = 1; spec = D3DXVECTOR4(0.75f, 0.75f, 0.75f, 80.0f); effect->SetVector("uv", &uv); effect->SetVector("matSpecular", &spec); effect->CommitChanges(); device->SetTexture(0, texture1); skull->DrawSubset(0); } } } }
static void RenderParticle(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); int w, h; GutGetWindowSize(w, h); Matrix4x4 wvp_matrix = g_Control.GetObjectMatrix() * g_Control.GetViewMatrix() * g_proj_matrix; Vector4 ScreenSize( (float)w, (float)h, 0.0f, 0.0f); float fTanW = FastMath::Tan( FastMath::DegToRad(g_fFOV) ); device->SetRenderTarget(0, g_pMainFramebuffer); device->SetDepthStencilSurface(g_pMainDepthbuffer); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0x0, 1.0f, 0); D3DXHANDLE shader = g_pParticleRenderFX->GetTechniqueByName("RenderParticle"); D3DXHANDLE positiontex_var = g_pParticleRenderFX->GetParameterByName(NULL, "PositionTex"); D3DXHANDLE velocitytex_var = g_pParticleRenderFX->GetParameterByName(NULL, "VelocityTex"); D3DXHANDLE wvp_matrix_var = g_pParticleRenderFX->GetParameterByName(NULL, "wvp_matrix"); D3DXHANDLE tan_fov_var = g_pParticleRenderFX->GetParameterByName(NULL, "fTanW"); D3DXHANDLE screensize_var = g_pParticleRenderFX->GetParameterByName(NULL, "ScreenSize"); D3DXHANDLE diffusetex_var = g_pParticleRenderFX->GetParameterByName(NULL, "DiffuseTex"); g_pParticleRenderFX->SetTechnique(shader); g_pParticleRenderFX->SetTexture(positiontex_var, g_pTextures[TEX_POSITION1]); g_pParticleRenderFX->SetTexture(velocitytex_var, g_pTextures[TEX_VELOCITY1]); g_pParticleRenderFX->SetMatrix(wvp_matrix_var, (D3DXMATRIX*)&wvp_matrix); g_pParticleRenderFX->SetVector(screensize_var, (D3DXVECTOR4*)&ScreenSize); g_pParticleRenderFX->SetFloat(tan_fov_var, fTanW); g_pParticleRenderFX->SetTexture(diffusetex_var, g_pParticleTexture); int num_processed_particles = (g_num_particles / g_texture_width) * g_texture_width; if ( num_processed_particles ) { device->SetFVF(D3DFVF_TEX1); g_pParticleRenderFX->Begin(NULL,0); g_pParticleRenderFX->BeginPass(0); //device->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); device->DrawPrimitiveUP(D3DPT_POINTLIST, num_processed_particles, g_pParticleArray, sizeof(sParticle)); //device->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE); g_pParticleRenderFX->EndPass(); g_pParticleRenderFX->End(); } }
void AdaptiveLuminance(void) { static int count = 0; LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); if ( count ) { device->SetRenderTarget(0, g_pFrameSurface[LUMINANCE_TEMP]); D3DXHANDLE shader = g_pExposureEffect->GetTechniqueByName("AdaptiveLuminance"); g_pExposureEffect->SetTechnique(shader); Vector4 vSpeed(0.03f); D3DXHANDLE speed_var = g_pExposureEffect->GetParameterByName(NULL, "vAdaptiveSpeed"); D3DXHANDLE image0_var = g_pExposureEffect->GetParameterByName(NULL, "Image"); D3DXHANDLE image1_var = g_pExposureEffect->GetParameterByName(NULL, "Image2"); g_pExposureEffect->SetVector(speed_var, (D3DXVECTOR4*)&vSpeed); g_pExposureEffect->SetTexture(image0_var, g_pFrameBuffer[LUMINANCE_PREVIOUS]); g_pExposureEffect->SetTexture(image1_var, g_pFrameBuffer[LUMINANCE_CURRENT]); g_pExposureEffect->Begin(NULL, 0); g_pExposureEffect->BeginPass(0); DrawFullScreenQuad(&g_Image1x1); g_pExposureEffect->EndPass(); g_pExposureEffect->End(); } else { device->StretchRect(g_pFrameSurface[LUMINANCE_CURRENT], NULL, g_pFrameSurface[LUMINANCE_TEMP], NULL, D3DTEXF_POINT); } // copy //device->StretchRect(g_pFrameSurface[LUMINANCE_TEMP], NULL, g_pFrameSurface[LUMINANCE_PREVIOUS], NULL, D3DTEXF_POINT); SwapRenderTarget(LUMINANCE_TEMP, LUMINANCE_PREVIOUS); count++; }
//************************************************************************************************************* void Render(float alpha, float elapsedtime) { D3DXMATRIX vp, inv; D3DXVECTOR3 axis(0, 1, 0); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff6694ed, 1.0f, 0); device->SetTexture(0, tex); device->SetTexture(1, normalmap); D3DXMatrixMultiply(&vp, &view, &proj); D3DXMatrixInverse(&inv, NULL, &view); effect->SetVector("eyePos", (D3DXVECTOR4*)inv.m[3]); D3DXMatrixRotationAxis(&world, &axis, timeGetTime() / 1000.0f); D3DXMatrixInverse(&inv, NULL, &world); effect->SetMatrix("matWorld", &world); effect->SetMatrix("matWorldInv", &inv); effect->SetMatrix("matViewProj", &vp); if( SUCCEEDED(device->BeginScene()) ) { effect->Begin(NULL, 0); effect->BeginPass(0); { mesh->DrawSubset(0); } effect->EndPass(); effect->End(); device->EndScene(); } device->Present(NULL, NULL, NULL, NULL); }
void DXDirectionalLight::DrawShadowMap(LPDIRECT3DDEVICE9 device, LPD3DXEFFECT effect, void (*drawcallback)(LPD3DXEFFECT)) { if( !shadowmap || !needsredraw ) return; LPDIRECT3DSURFACE9 surface = NULL; D3DXMATRIX vp; GetViewProjMatrix(vp, D3DXVECTOR3(0, 0, 0)); effect->SetVector("lightPos", &direction); effect->SetMatrix("matViewProj", &vp); shadowmap->GetSurfaceLevel(0, &surface); device->SetRenderTarget(0, surface); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0); drawcallback(effect); surface->Release(); if( shadowtype == Static ) needsredraw = false; }
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 ); }
void RenderWithIrregularPCF( const D3DXMATRIX& viewproj, const D3DXVECTOR3& eye, const D3DXMATRIX& lightview, const D3DXMATRIX& lightproj, const D3DXVECTOR4& lightpos, const D3DXVECTOR4& clipplanes, const D3DXVECTOR4& texelsize) { LPDIRECT3DSURFACE9 oldsurface = NULL; LPDIRECT3DSURFACE9 shadowsurface = NULL; D3DXVECTOR4 noisesize(16.0f, 16.0f, 0, 1); // STEP 1: render shadow map shadowmap->GetSurfaceLevel(0, &shadowsurface); device->GetRenderTarget(0, &oldsurface); device->SetRenderTarget(0, shadowsurface); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0); //device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); shadowsurface->Release(); pcfirreg->SetTechnique("shadowmap"); pcfirreg->SetMatrix("lightView", &lightview); pcfirreg->SetMatrix("lightProj", &lightproj); pcfirreg->SetVector("clipPlanes", &clipplanes); pcfirreg->Begin(NULL, 0); pcfirreg->BeginPass(0); { RenderScene(pcfirreg, 1); // caster RenderScene(pcfirreg, 3); // caster & receiver } pcfirreg->EndPass(); pcfirreg->End(); // STEP 2: render scene //device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); device->SetRenderTarget(0, oldsurface); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff6694ed, 1.0f, 0); device->SetRenderState(D3DRS_SRGBWRITEENABLE, TRUE); oldsurface->Release(); device->SetTexture(1, shadowmap); device->SetTexture(2, noise); pcfirreg->SetTechnique("irregular_light"); //pcfirreg->SetTechnique("irregular_screen"); pcfirreg->SetMatrix("matViewProj", &viewproj); pcfirreg->SetMatrix("lightView", &lightview); pcfirreg->SetMatrix("lightProj", &lightproj); pcfirreg->SetVector("clipPlanes", &clipplanes); pcfirreg->SetVector("lightPos", &lightpos); pcfirreg->SetVector("eyePos", (D3DXVECTOR4*)&eye); pcfirreg->SetVector("texelSize", &texelsize); pcfirreg->SetVector("noiseSize", &noisesize); pcfirreg->Begin(NULL, 0); pcfirreg->BeginPass(0); { RenderScene(pcfirreg, 2); // receiver RenderScene(pcfirreg, 3); // caster & receiver } pcfirreg->EndPass(); pcfirreg->End(); device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE); }
//************************************************************************************************************* void Blur() { device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); // x hdreffect->SetTechnique("blurx"); hdreffect->Begin(NULL, 0); hdreffect->BeginPass(0); for( int i = 0; i < 5; ++i ) { device->SetRenderTarget(0, blursurfaces[i]); device->SetTexture(0, dstargets[i]); texelsize.x = (float)(2 << i) / (float)screenwidth; texelsize.y = (float)(2 << i) / (float)screenheight; tmpvert[6] = tmpvert[24] = tmpvert[30] = (float)screenwidth / ((float)(2 << i)) - 0.5f; tmpvert[13] = tmpvert[19] = tmpvert[31] = (float)screenheight / ((float)(2 << i)) - 0.5f; hdreffect->SetVector("texelsize", &texelsize); hdreffect->CommitChanges(); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, tmpvert, sizeof(D3DXVECTOR4) + sizeof(D3DXVECTOR2)); } hdreffect->EndPass(); hdreffect->End(); // y hdreffect->SetTechnique("blury"); hdreffect->Begin(NULL, 0); hdreffect->BeginPass(0); for( int i = 0; i < 5; ++i ) { device->SetRenderTarget(0, dssurfaces[i]); device->SetTexture(0, blurtargets[i]); texelsize.x = (float)(2 << i) / (float)screenwidth; texelsize.y = (float)(2 << i) / (float)screenheight; tmpvert[6] = tmpvert[24] = tmpvert[30] = (float)screenwidth / ((float)(2 << i)) - 0.5f; tmpvert[13] = tmpvert[19] = tmpvert[31] = (float)screenheight / ((float)(2 << i)) - 0.5f; hdreffect->SetVector("texelsize", &texelsize); hdreffect->CommitChanges(); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, tmpvert, sizeof(D3DXVECTOR4) + sizeof(D3DXVECTOR2)); } hdreffect->EndPass(); hdreffect->End(); // combine device->SetRenderTarget(0, blursurfaces[0]); device->SetTexture(0, dstargets[0]); device->SetTexture(1, dstargets[1]); device->SetTexture(2, dstargets[2]); device->SetTexture(3, dstargets[3]); device->SetTexture(4, dstargets[4]); hdreffect->SetTechnique("blurcombine"); tmpvert[6] = tmpvert[24] = tmpvert[30] = (float)screenwidth * 0.5f - 0.5f; tmpvert[13] = tmpvert[19] = tmpvert[31] = (float)screenheight * 0.5f - 0.5f; hdreffect->Begin(NULL, 0); hdreffect->BeginPass(0); { device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, tmpvert, sizeof(D3DXVECTOR4) + sizeof(D3DXVECTOR2)); } hdreffect->EndPass(); hdreffect->End(); }
//************************************************************************************************************* void Render(float alpha, float elapsedtime) { static float time = 0; D3DXMATRIX view, proj, vp; D3DXMATRIX world; D3DXMATRIX inv; D3DXVECTOR4 amblight(0.2f, 0.2f, 0.2f, 1); D3DXVECTOR4 intensity(0.8f, 0.8f, 0.8f, 1); D3DXVECTOR4 zero(0, 0, 0, 1); D3DXVECTOR3 lightpos(0, 0, -10); D3DXVECTOR3 eye(0, 0, -5.2f); D3DXVECTOR3 look(0, 0.5f, 0); D3DXVECTOR3 up(0, 1, 0); D3DXVECTOR3 p1, p2; D3DXVECTOR2 orient = cameraangle.smooth(alpha); D3DXVECTOR2 light = lightangle.smooth(alpha); time += elapsedtime; // setup light D3DXMatrixRotationYawPitchRoll(&view, light.x, light.y, 0); D3DXVec3TransformCoord(&lightpos, &lightpos, &view); // TODO: no need to calculate every frame for( int i = 0; i < NUM_OBJECTS; ++i ) { FindSilhouette(objects[i], (D3DXVECTOR3&)lightpos); ExtrudeSilhouette(objects[i], (D3DXVECTOR3&)lightpos); } // setup camera D3DXMatrixRotationYawPitchRoll(&view, orient.x, orient.y, 0); D3DXVec3TransformCoord(&eye, &eye, &view); D3DXMatrixLookAtLH(&view, &eye, &look, &up); D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI / 4, (float)screenwidth / (float)screenheight, 0.1f, 20); // put far plane to infinity proj._33 = 1; proj._43 = -0.1f; D3DXMatrixMultiply(&vp, &view, &proj); D3DXMatrixScaling(&world, 5, 0.1f, 5); // specular effect uniforms specular->SetMatrix("matViewProj", &vp); specular->SetVector("eyePos", (D3DXVECTOR4*)&eye); specular->SetVector("lightPos", (D3DXVECTOR4*)&lightpos); specular->SetVector("ambient", &zero); // it's a f**k-up specular->SetVector("lightColor", &intensity); // lazy to tonemap ambient->SetMatrix("matViewProj", &vp); ambient->SetVector("ambient", &amblight); if( SUCCEEDED(device->BeginScene()) ) { device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0xff6694ed, 1.0f, 0); // STEP 1: z pass ambient->SetTechnique("ambientlight"); ambient->SetMatrix("matViewProj", &vp); DrawScene(ambient); // STEP 2: draw shadow with depth fail method device->SetRenderState(D3DRS_COLORWRITEENABLE, 0); device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); device->SetRenderState(D3DRS_STENCILENABLE, TRUE); device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); device->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); device->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR); device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); extrude->SetTechnique("extrude"); extrude->SetMatrix("matViewProj", &vp); extrude->Begin(0, 0); extrude->BeginPass(0); { for( int i = 0; i < NUM_OBJECTS; ++i ) DrawShadowVolume(objects[i]); device->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR); device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); for( int i = 0; i < NUM_OBJECTS; ++i ) DrawShadowVolume(objects[i]); } extrude->EndPass(); extrude->End(); device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_ALPHA); // STEP 3: multipass lighting device->SetRenderState(D3DRS_ZENABLE, TRUE); device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); device->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATER); device->SetRenderState(D3DRS_STENCILREF, 1); DrawScene(specular); device->SetRenderState(D3DRS_STENCILENABLE, FALSE); device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); if( drawsilhouette ) { amblight = D3DXVECTOR4(1, 1, 0, 0.5f); // reuse whatever we can... extrude->SetVector("ambient", &amblight); extrude->Begin(0, 0); extrude->BeginPass(0); device->SetVertexDeclaration(shadowdecl); for( int i = 0; i < NUM_OBJECTS; ++i ) { const ShadowCaster& caster = objects[i]; D3DXVECTOR4* verts = (D3DXVECTOR4*)malloc(caster.silhouette.size() * 2 * sizeof(D3DXVECTOR4)); for( size_t j = 0; j < caster.silhouette.size(); ++j ) { const Edge& e = caster.silhouette[j]; verts[j * 2 + 0] = D3DXVECTOR4(e.v1, 1); verts[j * 2 + 1] = D3DXVECTOR4(e.v2, 1); } extrude->SetMatrix("matWorld", &caster.world); extrude->CommitChanges(); device->DrawPrimitiveUP(D3DPT_LINELIST, caster.silhouette.size(), verts, sizeof(D3DXVECTOR4)); free(verts); } extrude->EndPass(); extrude->End(); extrude->SetVector("ambient", &zero); } if( drawvolume ) { device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); amblight = D3DXVECTOR4(1, 1, 0, 0.5f); extrude->SetVector("ambient", &amblight); extrude->Begin(0, 0); extrude->BeginPass(0); for( int i = 0; i < NUM_OBJECTS; ++i ) DrawShadowVolume(objects[i]); extrude->EndPass(); extrude->End(); extrude->SetVector("ambient", &zero); device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); } // render text device->SetFVF(D3DFVF_XYZRHW|D3DFVF_TEX1); device->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); device->SetTexture(0, text); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, textvertices, 6 * sizeof(float)); device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); device->SetRenderState(D3DRS_ZENABLE, TRUE); device->SetTexture(0, 0); device->EndScene(); } device->Present(NULL, NULL, NULL, NULL); }
//************************************************************************************************************* void Render(float alpha, float elapsedtime) { LPDIRECT3DSURFACE9 oldtarget = NULL; D3DXMATRIX vp, inv, tmp1, tmp2; D3DXVECTOR3 axis(0, 1, 0); D3DXVECTOR3 eye(0, 0, -5); D3DXVECTOR3 look(0, 0, 0); D3DXVECTOR3 up(0, 1, 0); D3DXVECTOR2 cangle = cameraangle.smooth(alpha); D3DXVECTOR2 oangle = objectangle.smooth(alpha); float expo = exposure.smooth(alpha); D3DXMatrixRotationYawPitchRoll(&world, cangle.x, cangle.y, 0); D3DXVec3TransformCoord(&eye, &eye, &world); D3DXMatrixLookAtLH(&view, &eye, &look, &up); D3DXMatrixMultiply(&vp, &view, &proj); D3DXMatrixInverse(&inv, NULL, &view); memcpy(&eye, inv.m[3], 3 * sizeof(float)); if( mesh == mesh1 ) { // skullocc D3DXMatrixScaling(&world, 0.4f, 0.4f, 0.4f); world._42 = -1.5f; } else if( mesh == mesh2 ) { // knot D3DXMatrixScaling(&world, 0.8f, 0.8f, 0.8f); } else { // teapot D3DXMatrixScaling(&world, 1.5f, 1.5f, 1.5f); } D3DXMatrixRotationYawPitchRoll(&tmp1, oangle.x, oangle.y, 0); D3DXMatrixMultiply(&world, &world, &tmp1); D3DXMatrixInverse(&inv, NULL, &world); fresnel->SetVector("eyePos", (D3DXVECTOR4*)&eye); fresnel->SetMatrix("matWorld", &world); fresnel->SetMatrix("matWorldInv", &inv); fresnel->SetMatrix("matViewProj", &vp); D3DXMatrixScaling(&world, 20, 20, 20); skyeffect->SetMatrix("matWorld", &world); D3DXMatrixIdentity(&world); skyeffect->SetMatrix("matWorldSky", &world); skyeffect->SetMatrix("matViewProj", &vp); memcpy(tmpvert, quadvertices, 36 * sizeof(float)); if( SUCCEEDED(device->BeginScene()) ) { device->SetRenderState(D3DRS_SRGBWRITEENABLE, false); device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); // STEP 1: render sky device->GetRenderTarget(0, &oldtarget); if( firstframe ) { device->SetRenderTarget(0, aftersurfaces[0]); device->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0); device->SetRenderTarget(0, aftersurfaces[1]); device->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0); device->SetRenderTarget(0, avglumsurfaces[4]); device->Clear(0, NULL, D3DCLEAR_TARGET, 0x11111111, 1.0f, 0); device->SetRenderTarget(0, avglumsurfaces[5]); device->Clear(0, NULL, D3DCLEAR_TARGET, 0x11111111, 1.0f, 0); firstframe = false; } device->SetRenderTarget(0, scenesurface); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff6694ed, 1.0f, 0); device->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetTexture(0, skytexture); skyeffect->Begin(NULL, 0); skyeffect->BeginPass(0); { skymesh->DrawSubset(0); } skyeffect->EndPass(); skyeffect->End(); device->SetRenderState(D3DRS_ZENABLE, TRUE); // STEP 2: render object device->SetTexture(0, texture); device->SetTexture(1, fresneltexture); device->SetTexture(2, skytexture); device->SetTexture(3, roughspecular); fresnel->Begin(NULL, 0); fresnel->BeginPass(0); { mesh->DrawSubset(0); } fresnel->EndPass(); fresnel->End(); device->SetVertexDeclaration(vertexdecl); // STEP 3: measure average luminance MeasureLuminance(); // STEP 4: adapt luminance to eye AdaptLuminance(elapsedtime); // STEP 5: bright pass BrightPass(); // STEP 6: downsample bright pass texture DownSample(); // STEP 7: blur downsampled textures Blur(); // STEP 8: ghost LensFlare(); // STEP 9: star Star(); // STEP 10: final combine hdreffect->SetTechnique("final"); hdreffect->SetFloat("targetluminance", targetluminance); device->SetRenderTarget(0, oldtarget); device->SetTexture(0, scenetarget); // scene device->SetTexture(1, blurtargets[0]); // blur device->SetTexture(2, blurtargets[1]); // star device->SetTexture(3, ghosttargets[0]); // ghost device->SetTexture(4, afterimages[1 - afterimagetex]); device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); device->SetRenderState(D3DRS_SRGBWRITEENABLE, true); oldtarget->Release(); hdreffect->Begin(NULL, 0); hdreffect->BeginPass(0); { device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, quadvertices, sizeof(D3DXVECTOR4) + sizeof(D3DXVECTOR2)); } hdreffect->EndPass(); hdreffect->End(); if( drawhelp ) { // render text device->SetFVF(D3DFVF_XYZRHW|D3DFVF_TEX1); device->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); device->SetTexture(0, text); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, textvertices, 6 * sizeof(float)); device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); device->SetRenderState(D3DRS_ZENABLE, TRUE); } // clean up device->SetTexture(1, NULL); device->SetTexture(2, NULL); device->SetTexture(3, NULL); device->SetTexture(4, NULL); device->SetTexture(5, NULL); device->EndScene(); } device->Present(NULL, NULL, NULL, NULL); }
void RenderScene(const D3DXMATRIX& viewproj, const D3DXVECTOR3& eye, const D3DXVECTOR4& lightpos, bool refl) { D3DXMATRIX world, inv; // sky device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, 1); D3DXMatrixScaling(&world, 20, 20, 20); skyeffect->SetMatrix("matWorld", &world); D3DXMatrixIdentity(&world); skyeffect->SetMatrix("matWorldSky", &world); skyeffect->SetMatrix("matViewProj", &viewproj); skyeffect->SetVector("eyePos", (D3DXVECTOR4*)&eye); skyeffect->Begin(0, 0); skyeffect->BeginPass(0); { device->SetTexture(0, skytex); skymesh->DrawSubset(0); } skyeffect->EndPass(); skyeffect->End(); device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); if( !refl ) { // sand D3DXMatrixTranslation(&world, 0, -2, 0); ambient->SetMatrix("matViewProj", &viewproj); ambient->SetMatrix("matWorld", &world); ambient->Begin(0, 0); ambient->BeginPass(0); { device->SetTexture(0, sand); sandplane->DrawSubset(0, DXObject::Opaque); } ambient->EndPass(); ambient->End(); } else device->SetRenderState(D3DRS_CLIPPLANEENABLE, D3DCLIPPLANE0); // palm D3DXMatrixScaling(&world, 6, 6, 6); D3DXMatrixInverse(&inv, 0, &world); world._42 = -2; specular->SetMatrix("matViewProj", &viewproj); specular->SetMatrix("matWorld", &world); specular->SetMatrix("matWorldInv", &inv); specular->SetVector("eyePos", (D3DXVECTOR4*)&eye); specular->SetVector("lightPos", &lightpos); specular->SetVector("lightColor", &lightcolor); specular->Begin(0, 0); specular->BeginPass(0); { device->SetTexture(0, bark); palm->DrawSubset(0, DXObject::Opaque); device->SetTexture(0, leaves); palm->DrawSubset(1, DXObject::Opaque); } specular->EndPass(); specular->End(); device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, 0); if( refl ) device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); }
void RenderLightShafts(const D3DXMATRIX& view, const D3DXMATRIX& proj, const D3DXVECTOR3& eye, const D3DXVECTOR4& lightpos) { D3DXMATRIX world; D3DXVECTOR3 viewdir(view._13, view._23, view._33); D3DXVECTOR3 lightdir; D3DXVECTOR4 lightss; D3DXVECTOR4 texelsize(1.0f / screenwidth, 1.0f / screenheight, 0, 1); D3DXVec3Normalize(&lightdir, (D3DXVECTOR3*)&lightpos); float exposure = min(max(D3DXVec3Dot(&viewdir, &lightdir), 0), 1); lightss.x = eye.x + lightpos.x; lightss.y = eye.y + lightpos.y; lightss.z = eye.z + lightpos.z; lightss.w = 1; D3DXVec4Transform(&lightss, &lightss, &view); D3DXVec4Transform(&lightss, &lightss, &proj); lightss.x = (1.0f + lightss.x / lightss.w) * 0.5f; lightss.y = (1.0f - lightss.y / lightss.w) * 0.5f; device->SetRenderTarget(0, occludersurf); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x68686868, 1.0f, 0); D3DXMatrixScaling(&world, 6, 6, 6); world._42 = -2; device->SetTransform(D3DTS_WORLD, &world); device->SetTransform(D3DTS_VIEW, &view); device->SetTransform(D3DTS_PROJECTION, &proj); palm->DrawSubset(0, DXObject::Opaque); palm->DrawSubset(1, DXObject::Opaque); device->SetVertexDeclaration(quaddecl); device->SetRenderState(D3DRS_ZENABLE, FALSE); // first blur godray->SetTechnique("godray"); godray->SetVector("lightPos", (D3DXVECTOR4*)&lightss); godray->SetFloat("exposure", exposure); device->SetRenderTarget(0, blursurf); godray->Begin(0, 0); godray->BeginPass(0); { device->SetTexture(0, occluders); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, quadvertices, 6 * sizeof(float)); } godray->EndPass(); godray->End(); // second blur godray->SetTechnique("blur"); godray->SetVector("texelSize", &texelsize); godray->SetVector("lightPos", (D3DXVECTOR4*)&lightss); device->SetRenderTarget(0, occludersurf); godray->Begin(0, 0); godray->BeginPass(0); { device->SetTexture(0, blurtex); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, quadvertices, 6 * sizeof(float)); } godray->EndPass(); godray->End(); device->SetRenderState(D3DRS_ZENABLE, TRUE); }
void Render(float alpha, float elapsedtime) { static float time = 0; LPDIRECT3DSURFACE9 backbuffer = 0; D3DXMATRIX view, proj, viewproj; D3DXMATRIX world, inv; D3DXVECTOR4 texelsize; D3DXVECTOR4 lightpos(-600, 350, 1000, 1); D3DXVECTOR4 refllight; D3DXVECTOR3 eye(0, 0, -5.0f); D3DXVECTOR3 look(0, 1.2f, 0); D3DXVECTOR3 refleye, refllook; D3DXVECTOR3 up(0, 1, 0); D3DXVECTOR2 orient = cameraangle.smooth(alpha); D3DXMatrixRotationYawPitchRoll(&view, orient.x, orient.y, 0); D3DXVec3TransformCoord(&eye, &eye, &view); eye.y += 1.2f; D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI / 2, (float)screenwidth / (float)screenheight, 0.1f, 30); time += elapsedtime; if( SUCCEEDED(device->BeginScene()) ) { device->GetRenderTarget(0, &backbuffer); // STEP 1: render reflection texture device->SetRenderTarget(0, reflectsurf); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff6694ed, 1.0f, 0); D3DXPLANE plane(0, 1, 0, 1); refleye = eye - 2 * D3DXPlaneDotCoord(&plane, &eye) * (D3DXVECTOR3&)plane; refllook = look - 2 * D3DXPlaneDotCoord(&plane, &look) * (D3DXVECTOR3&)plane; refllight = lightpos - 2 * D3DXPlaneDot(&plane, &lightpos) * (D3DXVECTOR4&)plane; refllight.w = 1; D3DXMatrixLookAtLH(&view, &refleye, &refllook, &up); D3DXMatrixMultiply(&viewproj, &view, &proj); D3DXMatrixInverse(&inv, 0, &viewproj); D3DXMatrixTranspose(&inv, &inv); D3DXPlaneTransform(&plane, &plane, &inv); device->SetClipPlane(0, &plane.a); RenderScene(viewproj, refleye, refllight, true); // STEP 2: render scene (later used for refraction) D3DXMatrixLookAtLH(&view, &eye, &look, &up); D3DXMatrixMultiply(&viewproj, &view, &proj); device->SetRenderTarget(0, refractsurf); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff6694ed, 1.0f, 0); RenderScene(viewproj, eye, lightpos, false); // render water surface into alpha channel for masking device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA); D3DXMatrixTranslation(&world, 0, -1, 0); device->SetTransform(D3DTS_WORLD, &world); device->SetTransform(D3DTS_VIEW, &view); device->SetTransform(D3DTS_PROJECTION, &proj); waterplane->DrawSubset(0, DXObject::Opaque); device->SetRenderState(D3DRS_COLORWRITEENABLE, 0x0f); // STEP 3: light shafts quadvertices[6] = quadvertices[24] = quadvertices[30] = (float)screenwidth - 0.5f; quadvertices[13] = quadvertices[19] = quadvertices[31] = (float)screenheight - 0.5f; RenderLightShafts(view, proj, eye, lightpos); // STEP 4: gamma correct device->SetRenderTarget(0, sceneldrsurf); device->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetVertexDeclaration(quaddecl); bloom->SetTechnique("gammacorrect"); bloom->Begin(0, 0); bloom->BeginPass(0); { device->SetTexture(0, refraction); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, quadvertices, 6 * sizeof(float)); } bloom->EndPass(); bloom->End(); device->SetRenderState(D3DRS_ZENABLE, TRUE); // STEP 5: water surface device->SetRenderState(D3DRS_SRGBWRITEENABLE, TRUE); D3DXMatrixTranslation(&world, 0, -1, 0); D3DXMatrixIdentity(&inv); water->SetMatrix("matViewProj", &viewproj); water->SetMatrix("matWorld", &world); water->SetMatrix("matWorldInv", &inv); water->SetVector("eyePos", (D3DXVECTOR4*)&eye); water->SetVector("lightPos", &lightpos); water->SetVector("lightColor", &lightcolor); water->SetFloat("time", time); water->Begin(0, 0); water->BeginPass(0); { device->SetTexture(0, refraction); device->SetTexture(1, reflection); device->SetTexture(2, waves); waterplane->DrawSubset(0, DXObject::Opaque); } water->EndPass(); water->End(); device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE); // STEP 6: downsample & blur quadvertices[6] = quadvertices[24] = quadvertices[30] = (float)screenwidth * 0.5f - 0.5f; quadvertices[13] = quadvertices[19] = quadvertices[31] = (float)screenheight * 0.5f - 0.5f; device->SetRenderTarget(0, bloomsurf1); device->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetVertexDeclaration(quaddecl); texelsize.x = 1.0f / screenwidth; texelsize.y = 1.0f / screenheight; bloom->SetTechnique("downsample"); bloom->SetVector("texelSize", &texelsize); bloom->Begin(0, 0); bloom->BeginPass(0); { device->SetTexture(0, sceneldr); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, quadvertices, 6 * sizeof(float)); } bloom->EndPass(); bloom->End(); device->SetRenderTarget(0, bloomsurf2); texelsize.x = 2.0f / screenwidth; texelsize.y = 2.0f / screenheight; bloom->SetTechnique("blur"); bloom->SetVector("texelSize", &texelsize); bloom->Begin(0, 0); bloom->BeginPass(0); { device->SetTexture(0, bloomtex1); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, quadvertices, 6 * sizeof(float)); } bloom->EndPass(); bloom->End(); // STEP 7: add light shafts quadvertices[6] = quadvertices[24] = quadvertices[30] = (float)screenwidth - 0.5f; quadvertices[13] = quadvertices[19] = quadvertices[31] = (float)screenheight - 0.5f; device->SetRenderTarget(0, backbuffer); godray->SetTechnique("final"); godray->Begin(0, 0); godray->BeginPass(0); { device->SetTexture(0, sceneldr); device->SetTexture(1, occluders); device->SetTexture(2, bloomtex2); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, quadvertices, 6 * sizeof(float)); } godray->EndPass(); godray->End(); backbuffer->Release(); device->SetRenderState(D3DRS_ZENABLE, TRUE); device->EndScene(); } device->Present(NULL, NULL, NULL, NULL); }
HRESULT CGlowEffect::Render(float fGlowThreshold, float fGlowAmount, bool bUseAlpha) { //#ifdef _DEBUG // bUseAlpha = true; //#endif HRESULT hr=S_OK; LPDIRECT3DDEVICE9 pd3dDevice = CGlobals::GetRenderDevice(); // get current render target m_pBackBuffer = CGlobals::GetDirectXEngine().GetRenderTarget(); if(FAILED(pd3dDevice->GetDepthStencilSurface(&m_pZBuffer))) return E_FAIL; if(!m_pBackBuffer || !m_pZBuffer) return E_FAIL; // Copy scene to lower resolution render target texture if( FAILED(hr = pd3dDevice->StretchRect( m_pBackBuffer, NULL, m_pRTHalfSizeSurface, NULL, D3DTEXF_LINEAR )) ) { OUTPUT_LOG("StretchRect() failed!\r\n"); return hr; } EffectManager* pEffectManager = CGlobals::GetEffectManager(); pEffectManager->BeginEffect(TECH_FULL_SCREEN_GLOW); CEffectFile* pEffectFile = pEffectManager->GetCurrentEffectFile(); if(pEffectFile != 0 && pEffectFile->begin(true, 0)) { // full screen glow effect is completed in four steps. assert(pEffectFile->totalPasses() == 4); mesh_vertex_plain quadVertices[4] = { {Vector3(-1,-1,0), Vector2(0,1)}, { Vector3(1, -1, 0), Vector2(1, 1) }, { Vector3(-1, 1, 0), Vector2(0, 0) }, { Vector3(1, 1, 0), Vector2(1, 0) }, }; // offset the texture coordinate by half texel in order to match texel to pixel. // This takes me hours to figure out. :-( float fhalfTexelWidth = 0.5f/m_glowtextureWidth; float fhalfTexelHeight = 0.5f/m_glowtextureHeight; for (int i=0;i<4;++i) { quadVertices[i].uv.x += fhalfTexelWidth; quadVertices[i].uv.y += fhalfTexelHeight; } // shader constants /* #ifdef TEST_GLOW static int i=0; ++i; if(i>30){ fGlowAmount = 1.0f; fGlowThreshold = 0.f; if(i>60) i=0; } else { fGlowAmount = 0.f; fGlowThreshold = 1.0f; } #endif*/ /* pEffectFile->setParameter(CEffectFile::k_ConstVector0, (const float*)&Vector4(1/m_glowtextureWidth, 1/m_glowtextureHeight, 0.0f, 0.0f)); LinearColor glowness = pEffectManager->GetGlowness(); glowness.a = fGlowThreshold; glowness.r *= fGlowAmount; glowness.g *= fGlowAmount; glowness.b *= fGlowAmount; pEffectFile->setParameter(CEffectFile::k_ConstVector1, (const float*)&glowness); */ bUseAlpha = true; if(bUseAlpha) { ////////////////////////////////////////////////////////////////////////// // make the glow source. Multiply texture alpha * RGB to get the glow sources pd3dDevice->SetRenderTarget( 0, m_pRTGlowSourceSurface); pd3dDevice->SetDepthStencilSurface( NULL ); if(pEffectFile->BeginPass(0)) { pEffectFile->setTexture(0, m_pRTHalfSizeTexture); LPD3DXEFFECT fx = pEffectFile->GetDXEffect(); fx->SetFloat(fx->GetParameterByName(NULL,"glowThreshold"),fGlowThreshold); pEffectFile->CommitChanges(); HRESULT hr = RenderDevice::DrawPrimitiveUP( pd3dDevice, RenderDevice::DRAW_PERF_TRIANGLES_MESH, D3DPT_TRIANGLESTRIP,2,quadVertices,sizeof(mesh_vertex_plain)); pEffectFile->EndPass(); } } ////////////////////////////////////////////////////////////////////////// // Blur glow sources in the horizontal axis pd3dDevice->SetRenderTarget( 0, m_pRTBlurHorizSurface ); pd3dDevice->SetDepthStencilSurface( NULL ); // no need to clear alpha channel? // pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, 0x00, 1.0f, 0 ); if(pEffectFile->BeginPass(1)) { SetBlurEffectParameters(1.0f / m_glowtextureWidth,0,fGlowAmount,pEffectFile); pEffectFile->setTexture(0, m_pRTGlowSourceTexture); pEffectFile->CommitChanges(); HRESULT hr = RenderDevice::DrawPrimitiveUP( pd3dDevice, RenderDevice::DRAW_PERF_TRIANGLES_MESH, D3DPT_TRIANGLESTRIP,2,quadVertices,sizeof(mesh_vertex_plain)); pEffectFile->EndPass(); } // set texture 0 to NULL so same texture is never simultaneously a source and render target pEffectFile->setTexture( 0, (LPDIRECT3DTEXTURE9)NULL ); ////////////////////////////////////////////////////////////////////////// // Blur the horizontal blur in the vertical direction pd3dDevice->SetRenderTarget( 0, m_pRTBlurVertSurface ); pd3dDevice->SetDepthStencilSurface( NULL ); // no need to clear alpha channel? // pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, 0x00, 1.0f, 0 ); //fGlowAmount = 2; if(pEffectFile->BeginPass(1)) { //pEffectFile->setTexture( 1, m_pRTBlurHorizTexture ); SetBlurEffectParameters(0,1.0f / m_glowtextureHeight,fGlowAmount,pEffectFile); pEffectFile->setTexture(0, m_pRTBlurHorizTexture ); //editor here!!! pEffectFile->CommitChanges(); HRESULT hr = RenderDevice::DrawPrimitiveUP( pd3dDevice, RenderDevice::DRAW_PERF_TRIANGLES_MESH, D3DPT_TRIANGLESTRIP,2,quadVertices,sizeof(mesh_vertex_plain)); pEffectFile->EndPass(); } // Set all textures to NULL to prevent RTT being bound as source and destination at the same time, pEffectFile->setTexture( 0,(LPDIRECT3DTEXTURE9)NULL ); ////////////////////////////////////////////////////////////////////////// // Add the final blur image to the back buffer pd3dDevice->SetRenderTarget( 0, m_pBackBuffer); pd3dDevice->SetDepthStencilSurface( NULL ); // no need to clear alpha channel? // pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, 0x00, 1.0f, 0 ); for (int i=0;i<4;++i) { quadVertices[i].uv.x -= fhalfTexelWidth * 0.5f; quadVertices[i].uv.y -= fhalfTexelHeight * 0.5f; } if(pEffectFile->BeginPass(3)) { pEffectFile->setTexture(0, m_pRTHalfSizeTexture ); pEffectFile->setTexture(1,m_pRTBlurVertTexture); Vector4 glowParam = pEffectManager->GetGlowness(); LPD3DXEFFECT fx = pEffectFile->GetDXEffect(); fx->SetVector(fx->GetParameterByName(NULL,"glowParams"), (const DeviceVector4*)&glowParam); pEffectFile->CommitChanges(); HRESULT hr = RenderDevice::DrawPrimitiveUP( pd3dDevice, RenderDevice::DRAW_PERF_TRIANGLES_MESH, D3DPT_TRIANGLESTRIP,2,quadVertices,sizeof(mesh_vertex_plain)); pEffectFile->EndPass(); pEffectFile->setTexture( 0, (LPDIRECT3DTEXTURE9)NULL ); pEffectFile->setTexture(1,(LPDIRECT3DTEXTURE9)NULL); } // restore depth stencil buffer pd3dDevice->SetDepthStencilSurface( m_pZBuffer ); pEffectFile->end(); } else { CGlobals::GetScene()->EnableFullScreenGlow(false); //Glow effect will not be load when graphics setting set to middle //so we just disable this warnning //OUTPUT_LOG("can not set full screen glow effect error \r\n"); } SAFE_RELEASE(m_pZBuffer); return hr; }
//************************************************************************************************************* void Render(float alpha, float elapsedtime) { D3DXMATRIX world, view, proj; D3DXMATRIX skyworld, viewproj; D3DXVECTOR3 eye(0, 0, -5); D3DXVECTOR3 look(0, 0, 0); D3DXVECTOR3 up(0, 1, 0); D3DXVECTOR2 orient = cameraangle.smooth(alpha); D3DXMatrixRotationYawPitchRoll(&view, orient.x, orient.y, 0); D3DXVec3TransformCoord(&eye, &eye, &view); D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI / 4, (float)screenwidth / (float)screenheight, 0.1f, 50); D3DXMatrixLookAtLH(&view, &eye, &look, &up); D3DXMatrixMultiply(&viewproj, &view, &proj); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff6694ed, 1.0f, 0); device->SetTransform(D3DTS_VIEW, &view); device->SetTransform(D3DTS_PROJECTION, &proj); for( int i = 0; i < NUM_DWARFS; ++i ) dwarfs[i].Update(elapsedtime, &dwarfmatrices[i]); effect->SetMatrix("matViewProj", &viewproj); if( SUCCEEDED(device->BeginScene()) ) { // render sky device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); D3DXMatrixScaling(&skyworld, 20, 20, 20); skyeffect->SetMatrix("matWorld", &skyworld); D3DXMatrixIdentity(&skyworld); skyeffect->SetMatrix("matWorldSky", &skyworld); skyeffect->SetMatrix("matViewProj", &viewproj); skyeffect->SetVector("eyePos", (D3DXVECTOR4*)&eye); skyeffect->Begin(0, 0); skyeffect->BeginPass(0); { device->SetTexture(0, skytex); skymesh->DrawSubset(0); } skyeffect->EndPass(); skyeffect->End(); device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); // render ground D3DXMatrixScaling(&world, 5, 0.1f, 5); world._42 = -0.05f; device->SetTransform(D3DTS_WORLD, &world); device->SetTexture(0, texture2); mesh->DrawSubset(0); // dwarfs for( int i = 0; i < NUM_DWARFS; ++i ) dwarfs[i].Draw(); // fire D3DXMatrixTranslation(&world, 0, 0.25f, 0); device->SetTransform(D3DTS_WORLD, &world); system1.Draw(world, view); // render text device->SetFVF(D3DFVF_XYZRHW|D3DFVF_TEX1); device->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); device->SetTexture(0, text); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, textvertices, 6 * sizeof(float)); device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); device->SetRenderState(D3DRS_ZENABLE, TRUE); device->EndScene(); } device->Present(NULL, NULL, NULL, NULL); }
//************************************************************************************************************* void Render(float alpha, float elapsedtime) { static float time = 0; D3DXMATRIX inv; D3DXVECTOR3 axis(0, 1, 0); D3DXVECTOR4 texelsize(1.0f / (float)screenwidth, 1.0f / (float)screenheight, 0, 1); LPDIRECT3DSURFACE9 oldtarget = NULL; time += elapsedtime; D3DXMatrixRotationAxis(&inv, &axis, time); D3DXMatrixScaling(&world, 0.3f, 0.3f, 0.3f); //D3DXMatrixScaling(&world, 0.6f, 0.6f, 0.6f); D3DXMatrixMultiply(&world, &world, &inv); D3DXMatrixInverse(&inv, NULL, &world); device->SetTexture(0, texture); device->SetTexture(1, intensity); effect->SetMatrix("matWorld", &world); effect->SetMatrix("matWorldInv", &inv); effect->SetMatrix("matView", &view); effect->SetMatrix("matProj", &proj); if( useedgedetect ) { device->GetRenderTarget(0, &oldtarget); device->SetRenderTarget(0, colorsurface); device->SetRenderTarget(1, normalsurface); } device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0xff6694ed, 1.0f, 0); if( SUCCEEDED(device->BeginScene()) ) { // draw scene + normals/depth effect->SetTechnique("celshading"); effect->Begin(NULL, 0); effect->BeginPass(0); { mesh->DrawSubset(0); } effect->EndPass(); effect->End(); if( useedgedetect ) { // edge detection device->SetVertexDeclaration(vertexdecl); device->SetRenderTarget(0, edgesurface); device->SetRenderTarget(1, NULL); device->SetTexture(0, normaltarget); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff6694ed, 1.0f, 0); effect->SetTechnique("edgedetect"); effect->SetVector("texelSize", &texelsize); effect->Begin(NULL, 0); effect->BeginPass(0); { device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, vertices, sizeof(D3DXVECTOR4) + sizeof(D3DXVECTOR2)); } effect->EndPass(); effect->End(); // put together device->SetRenderTarget(0, oldtarget); device->SetTexture(0, colortarget); device->SetTexture(2, edgetarget); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff6694ed, 1.0f, 0); oldtarget->Release(); effect->SetTechnique("final"); effect->Begin(NULL, 0); effect->BeginPass(0); { device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, vertices, sizeof(D3DXVECTOR4) + sizeof(D3DXVECTOR2)); } effect->EndPass(); effect->End(); } else { D3DXMATRIX offproj; // use the stencil buffer device->SetRenderState(D3DRS_COLORWRITEENABLE, 0); device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); device->SetRenderState(D3DRS_STENCILENABLE, TRUE); device->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); device->SetRenderState(D3DRS_STENCILREF, 1); device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE); device->SetTransform(D3DTS_WORLD, &world); device->SetTransform(D3DTS_VIEW, &view); float thickness = 3.5f; // render object 4 times with offseted frustum for( float i = -thickness; i < thickness + 1; i += 2 * thickness ) { for( float j = -thickness; j < thickness + 1; j += 2 * thickness ) { D3DXMatrixTranslation(&offproj, i / (float)screenwidth, j / (float)screenheight, 0); D3DXMatrixMultiply(&offproj, &proj, &offproj); device->SetTransform(D3DTS_PROJECTION, &offproj); mesh->DrawSubset(0); } } // erase area in the center device->SetRenderState(D3DRS_STENCILREF, 0); device->SetTransform(D3DTS_PROJECTION, &proj); mesh->DrawSubset(0); // now render outlines device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_ALPHA); device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_NOTEQUAL); device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); device->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); device->SetFVF(D3DFVF_XYZRHW|D3DFVF_TEX1); device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_CONSTANT); device->SetTextureStageState(0, D3DTSS_CONSTANT, 0); { device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, vertices, sizeof(D3DXVECTOR4) + sizeof(D3DXVECTOR2)); } device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); device->SetRenderState(D3DRS_ZENABLE, TRUE); device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); device->SetRenderState(D3DRS_STENCILENABLE, FALSE); } device->SetTexture(2, NULL); // render text device->SetFVF(D3DFVF_XYZRHW|D3DFVF_TEX1); device->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); device->SetTexture(0, text); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, textvertices, 6 * sizeof(float)); device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); device->SetRenderState(D3DRS_ZENABLE, TRUE); device->SetTexture(0, NULL); device->EndScene(); } device->Present(NULL, NULL, NULL, NULL); }
HRESULT InitScene() { HRESULT hr; LPD3DXBUFFER errors = NULL; SetWindowText(hwnd, TITLE); if( FAILED(hr = D3DXLoadMeshFromXA("../media/meshes/sphere.X", D3DXMESH_MANAGED, device, NULL, NULL, NULL, NULL, &mesh)) ) { MYERROR("Could not load sphere"); return hr; } // generate tangent frame LPD3DXMESH newmesh = NULL; D3DVERTEXELEMENT9 decl[] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, { 0, 20, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, { 0, 32, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0 }, { 0, 44, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 }, D3DDECL_END() }; if( FAILED(hr = mesh->CloneMesh(D3DXMESH_MANAGED, decl, device, &newmesh)) ) { MYERROR("Could not clone mesh"); return hr; } mesh->Release(); mesh = NULL; hr = D3DXComputeTangentFrameEx(newmesh, D3DDECLUSAGE_TEXCOORD, 0, D3DDECLUSAGE_TANGENT, 0, D3DDECLUSAGE_BINORMAL, 0, D3DDECLUSAGE_NORMAL, 0, 0, NULL, 0.01f, 0.25f, 0.01f, &mesh, NULL); newmesh->Release(); if( FAILED(hr) ) { MYERROR("Could not compute tangent frame"); return hr; } if( FAILED(hr = CreateChecker(device, 10, 10, 0xff7557a8, 0xffd8d8d8, &tex)) ) { MYERROR("Could not create texture"); return hr; } if( FAILED(hr = D3DXCreateTextureFromFileA(device, "../media/textures/brick_nh.dds", &normalmap)) ) { MYERROR("Could not load normalmap"); return hr; } hr = D3DXCreateEffectFromFileA(device, "../media/shaders/normal.fx", NULL, NULL, D3DXSHADER_DEBUG, NULL, &effect, &errors); if( FAILED(hr) ) { if( errors ) { char* str = (char*)errors->GetBufferPointer(); std::cout << str << "\n\n"; errors->Release(); } MYERROR("Could not create effect"); return hr; } D3DXVECTOR4 uv(3, 1, 0, 1); effect->SetVector("normuv", &uv); D3DXVECTOR3 eye(0, 0, -1.5f); D3DXVECTOR3 look(0, 0, 0); D3DXVECTOR3 up(0, 1, 0); D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI / 3, (float)screenwidth / (float)screenheight, 0.1f, 10); D3DXMatrixLookAtLH(&view, &eye, &look, &up); D3DXMatrixIdentity(&world); return S_OK; }