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 ); }
void RenderFrameDX10(void) { Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix = g_Control.GetObjectMatrix(); Vector4 vClearColor(0.0f, 0.0f, 0.0f, 0.0f); UINT stride = sizeof(Vertex_VT); UINT offset = 0; ID3D10RenderTargetView *pRenderTargetView = GutGetDX10RenderTargetView(); ID3D10DepthStencilView *pDepthStencilView = GutGetDX10DepthStencilView(); g_pDevice->OMSetRenderTargets(1, &g_pRTView[FULLSIZE], pDepthStencilView); g_pDevice->ClearRenderTargetView(g_pRTView[FULLSIZE], &vClearColor[0]); g_pDevice->ClearDepthStencilView(pDepthStencilView, D3D10_CLEAR_DEPTH|D3D10_CLEAR_STENCIL, 1.0f, 0); SetViewport(FULLSIZE); CGutModel_DX10::SetViewMatrix(view_matrix); CGutModel_DX10::SetWorldMatrix(world_matrix); CGutModel_DX10::SetProjectionMatrix(g_proj_matrix); CGutModel_DX10::UpdateMatrix(); g_Model_DX10.Render(); ConvertToLuminance(); Average(); AdaptiveLuminance(); AutoExposure(); if ( g_iMode & 0x01 ) { g_pDevice->OMSetRenderTargets(1, &pRenderTargetView, pDepthStencilView); SetViewport(FULLSIZE); float x = -1.0f; float y = -1.0f; float w = 0.2f; float h = 0.2f; DrawImage(g_pSRView[LUMINANCE_CURRENT], x, y, w, h); x+=w; DrawImage(g_pSRView[LUMINANCE_PREVIOUS], x, y, w, h); x+=w; } // 等待硬體掃結束, 然後才更新畫面 IDXGISwapChain *pSwapChain = GutGetDX10SwapChain(); pSwapChain->Present(1, 0); }
void *renderThread(void *arg) { int x,y; thread_info *tinfo = (thread_info *)arg; /* Calculate which part to render based on thread id */ int limits[]={(tinfo->thread_num*sectionsize),(tinfo->thread_num*sectionsize)+sectionsize}; /* Autoexposure */ double exposure = AutoExposure(myScene); double projectionDistance = 0.0f; if ((myScene->persp.type == CONIC) && myScene->persp.FOV > 0.0f && myScene->persp.FOV < 189.0f) { projectionDistance = 0.5f * myScene->width / tanf((double)(PIOVER180) * 0.5f * myScene->persp.FOV); } for (y = limits[0]; y < limits[1]; ++y) { for (x = 0; x < myScene->width; ++x) { colour output = {0.0f, 0.0f, 0.0f}; double fragmentx, fragmenty; /* Antialiasing */ for (fragmentx = x; fragmentx < x + 1.0f; fragmentx += 0.5f) { for (fragmenty = y; fragmenty < y + 1.0f; fragmenty += 0.5f) { double sampleRatio=0.25f; colour temp = {0.0f, 0.0f, 0.0f}; double totalWeight = 0.0f; if (myScene->persp.type == ORTHOGONAL || projectionDistance == 0.0f) { ray viewRay = { {fragmentx, fragmenty, -10000.0f},{ 0.0f, 0.0f, 1.0f}}; int i; for (i = 0; i < myScene->complexity; ++i) { colour result = raytrace(&viewRay, myScene); totalWeight += 1.0f; temp = colourAdd(&temp,&result); } temp = colourCoefMul((1.0f/totalWeight), &temp); } else { vector dir = {(fragmentx - 0.5f * myScene->width) / projectionDistance, (fragmenty - 0.5f * myScene->height) / projectionDistance, 1.0f }; double norm = vectorDot(&dir,&dir); if (norm == 0.0f) break; dir = vectorScale(invsqrtf(norm),&dir); vector start = {0.5f * myScene->width, 0.5f * myScene->height, 0.0f}; vector tmp = vectorScale(myScene->persp.clearPoint,&dir); vector observed = vectorAdd(&start,&tmp); int i; for (i = 0; i < myScene->complexity; ++i) { ray viewRay = { {start.x, start.y, start.z}, {dir.x, dir.y, dir.z} }; if (myScene->persp.dispersion != 0.0f) { vector disturbance; disturbance.x = (myScene->persp.dispersion / RAND_MAX) * (1.0f * rand()); disturbance.y = (myScene->persp.dispersion / RAND_MAX) * (1.0f * rand()); disturbance.z = 0.0f; viewRay.start = vectorAdd(&viewRay.start, &disturbance); viewRay.dir = vectorSub(&observed, &viewRay.start); norm = vectorDot(&viewRay.dir,&viewRay.dir); if (norm == 0.0f) break; viewRay.dir = vectorScale(invsqrtf(norm),&viewRay.dir); } colour result = raytrace(&viewRay, myScene); totalWeight += 1.0f; temp = colourAdd(&temp,&result); } temp = colourCoefMul((1.0f/totalWeight), &temp); } temp.blue = (1.0f - expf(temp.blue * exposure)); temp.red = (1.0f - expf(temp.red * exposure)); temp.green = (1.0f - expf(temp.green * exposure)); colour adjusted = colourCoefMul(sampleRatio, &temp); output = colourAdd(&output, &adjusted); } } /* gamma correction */ double invgamma = 0.45f; //Fixed value from sRGB standard output.blue = powf(output.blue, invgamma); output.red = powf(output.red, invgamma); output.green = powf(output.green, invgamma); img[(x+y*myScene->width)*3+2] = (unsigned char)min(output.red*255.0f, 255.0f); img[(x+y*myScene->width)*3+1] = (unsigned char)min(output.green*255.0f, 255.0f); img[(x+y*myScene->width)*3+0] = (unsigned char)min(output.blue*255.0f,255.0f); } } pthread_exit((void *) arg); }