void RenderFrameDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); device->BeginScene(); Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix = g_Control.GetObjectMatrix(); // normal pass if ( g_bPosteffect ) { device->SetRenderTarget(0, g_pFrameSurface[FULLSIZE]); device->SetDepthStencilSurface(NULL); } else { device->SetRenderTarget(0, g_pMainSurface); device->SetDepthStencilSurface(NULL); } device->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 1.0f, 0); device->SetVertexShader(NULL); device->SetPixelShader(NULL); device->SetRenderState(D3DRS_LIGHTING, FALSE); device->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&g_proj_matrix); device->SetTransform(D3DTS_VIEW, (D3DMATRIX*)&view_matrix); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *)&world_matrix); g_Model_DX9.Render(); if ( g_bPosteffect ) { ConverToLogLuminance(g_pFrameBuffer[FULLSIZE], &g_ImageInfo); // ExpLuminance(g_pFrameSurface[FULLSIZE], g_pFrameBuffer[DOWNSAMPLED_256x256], &g_Image256x256); AverageLuminance(g_pFrameBuffer[DOWNSAMPLED_256x256]); ExpLuminance(); AdaptiveLuminance(); device->SetRenderTarget(0, g_pMainSurface); device->SetDepthStencilSurface(NULL); //device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0x0, 1.0f, 0); AutoExposure(); if ( g_iMode & 0x01 ) { DrawImage(g_pFrameBuffer[LUMINANCE_TEMP], &g_Image1x1, -1.0f, -1.0f, 0.1f, 0.1f); DrawImage(g_pFrameBuffer[LUMINANCE_CURRENT], &g_Image1x1, -0.9f, -1.0f, 0.1f, 0.1f); } } device->EndScene(); device->Present( NULL, NULL, NULL, NULL ); }
/** Gradient Domain HDR tone mapping operator @param Y Image luminance values @param alpha Parameter alpha of the paper (suggested value is 0.1) @param beta Parameter beta of the paper (suggested value is between 0.8 and 0.9) @return returns the tone mapped luminance */ static FIBITMAP* tmoFattal02(FIBITMAP *Y, float alpha, float beta) { const unsigned MIN_PYRAMID_SIZE = 32; // minimun size (width or height) of the coarsest level of the pyramid FIBITMAP *H = NULL; FIBITMAP **pyramid = NULL; FIBITMAP **gradients = NULL; FIBITMAP *phy = NULL; FIBITMAP *divG = NULL; FIBITMAP *U = NULL; float *avgGrad = NULL; int k; int nlevels = 0; try { // get the normalized luminance FIBITMAP *H = LogLuminance(Y); if(!H) throw(1); // get the number of levels for the pyramid const unsigned width = FreeImage_GetWidth(H); const unsigned height = FreeImage_GetHeight(H); unsigned minsize = MIN(width, height); while(minsize >= MIN_PYRAMID_SIZE) { nlevels++; minsize /= 2; } // create the Gaussian pyramid pyramid = (FIBITMAP**)malloc(nlevels * sizeof(FIBITMAP*)); if(!pyramid) throw(1); memset(pyramid, 0, nlevels * sizeof(FIBITMAP*)); if(!GaussianPyramid(H, pyramid, nlevels)) throw(1); // calculate gradient magnitude and its average value on each pyramid level gradients = (FIBITMAP**)malloc(nlevels * sizeof(FIBITMAP*)); if(!gradients) throw(1); memset(gradients, 0, nlevels * sizeof(FIBITMAP*)); avgGrad = (float*)malloc(nlevels * sizeof(float)); if(!avgGrad) throw(1); if(!GradientPyramid(pyramid, nlevels, gradients, avgGrad)) throw(1); // free the Gaussian pyramid for(k = 0; k < nlevels; k++) { if(pyramid[k]) FreeImage_Unload(pyramid[k]); } free(pyramid); pyramid = NULL; // compute the gradient attenuation function PHI(x, y) phy = PhiMatrix(gradients, avgGrad, nlevels, alpha, beta); if(!phy) throw(1); // free the gradient pyramid for(k = 0; k < nlevels; k++) { if(gradients[k]) FreeImage_Unload(gradients[k]); } free(gradients); gradients = NULL; free(avgGrad); avgGrad = NULL; // compute gradients in x and y directions, attenuate them with the attenuation matrix, // then compute the divergence div G from the attenuated gradient. divG = Divergence(H, phy); if(!divG) throw(1); // H & phy no longer needed FreeImage_Unload(H); H = NULL; FreeImage_Unload(phy); phy = NULL; // solve the PDE (Poisson equation) using a multigrid solver and 3 cycles FIBITMAP *U = FreeImage_MultigridPoissonSolver(divG, 3); if(!U) throw(1); FreeImage_Unload(divG); // perform exponentiation and recover the log compressed image ExpLuminance(U); return U; } catch(int) { if(H) FreeImage_Unload(H); if(pyramid) { for(int i = 0; i < nlevels; i++) { if(pyramid[i]) FreeImage_Unload(pyramid[i]); } free(pyramid); } if(gradients) { for(int i = 0; i < nlevels; i++) { if(gradients[i]) FreeImage_Unload(gradients[i]); } free(gradients); } if(avgGrad) free(avgGrad); if(phy) FreeImage_Unload(phy); if(divG) FreeImage_Unload(divG); if(U) FreeImage_Unload(U); return NULL; } }