PDA

View Full Version : HDR Scene render problem


Phlex
02-27-2009, 01:48 PM
I've been working with the HDRLighting sample in the 2008 August DirectX SDK and am trying to rewrite it without any DXUT code so that I can understand it better. I've spent a good few hours working through it and converting the code, but I've hit my first major snag which I can't get out of.
Working with the first pass scene render here, I'm doing exactly as the HDRLighting app has, the problem is when I should be getting this:

http://img17.imageshack.us/img17/2595/screenshotd.png


I'm getting this:

http://img502.imageshack.us/img502/5606/screenshot0.png

This is the code from the HDR Lighting app:

void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
// If the settings dialog is being shown, then
// render it instead of rendering the app's scene
if( g_SettingsDlg.IsActive() )
{
g_SettingsDlg.OnRender( fElapsedTime );
return;
}

HRESULT hr;

PDIRECT3DSURFACE9 pSurfLDR; // Low dynamic range surface for final output
PDIRECT3DSURFACE9 pSurfDS; // Low dynamic range depth stencil surface
PDIRECT3DSURFACE9 pSurfHDR; // High dynamic range surface to store
// intermediate floating point color values

// Store the old render target
V( g_pd3dDevice->GetRenderTarget( 0, &pSurfLDR ) );
V( g_pd3dDevice->GetDepthStencilSurface( &pSurfDS ) );

// Setup HDR render target
V( g_pTexScene->GetSurfaceLevel( 0, &pSurfHDR ) );
if( g_bUseMultiSampleFloat16 )
{
V( g_pd3dDevice->SetRenderTarget( 0, g_pFloatMSRT ) );
V( g_pd3dDevice->SetDepthStencilSurface( g_pFloatMSDS ) );
}
else
{
V( g_pd3dDevice->SetRenderTarget( 0, pSurfHDR ) );
}

// Clear the viewport
V( g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA( 0, 0, 0, 0 ), 1.0f, 0L ) );

// Render the scene
if( SUCCEEDED( pd3dDevice->BeginScene() ) )
{
// Render the HDR Scene
{
CDXUTPerfEventGenerator g( DXUT_PERFEVENTCOLOR, L"Scene" );
RenderScene();

if(g_bScreenHasBeenTaken != TRUE)
{
if(FAILED(ScreenGrabSurface(pSurfHDR)))
MessageBox(NULL, L"ScreenGrabSurface failed", NULL, MB_OK | MB_ICONERROR);

else g_bScreenHasBeenTaken = TRUE;
}
}
}

V( pd3dDevice->EndScene() );
}

// Release surfaces
SAFE_RELEASE( pSurfHDR );
SAFE_RELEASE( pSurfLDR );
SAFE_RELEASE( pSurfDS );
}

// and the code for render scene
//-----------------------------------------------------------------------------
// Name: RenderScene()
// Desc: Render the world objects and lights
//-----------------------------------------------------------------------------
HRESULT RenderScene()
{
HRESULT hr = S_OK;

UINT uiPassCount, uiPass;
D3DXMATRIXA16 mWorld;
D3DXMATRIXA16 mTrans;
D3DXMATRIXA16 mRotate;
D3DXMATRIXA16 mObjectToView;

g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );

D3DXMATRIX mView = *g_Camera.GetViewMatrix();

g_pEffect->SetTechnique( "RenderScene" );
g_pEffect->SetMatrix( "g_mObjectToView", &mView );

hr = g_pEffect->Begin( &uiPassCount, 0 );
if( FAILED( hr ) )
return hr;

for( uiPass = 0; uiPass < uiPassCount; uiPass++ )
{
g_pEffect->BeginPass( uiPass );

// Turn off emissive lighting
D3DXVECTOR4 vNull( 0.0f, 0.0f, 0.0f, 0.0f );
g_pEffect->SetVector( "g_vEmissive", &vNull );

// Enable texture
g_pEffect->SetBool( "g_bEnableTexture", true );
g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );


// Render walls and columns
g_pEffect->SetFloat( "g_fPhongExponent", 5.0f );
g_pEffect->SetFloat( "g_fPhongCoefficient", 1.0f );
g_pEffect->SetFloat( "g_fDiffuseCoefficient", 0.5f );
g_pd3dDevice->SetTexture( 0, g_pTexWall );
g_pEffect->CommitChanges();
g_pWorldMesh->DrawSubset( 0 );

// Render floor
g_pEffect->SetFloat( "g_fPhongExponent", 50.0f );
g_pEffect->SetFloat( "g_fPhongCoefficient", 3.0f );
g_pEffect->SetFloat( "g_fDiffuseCoefficient", 1.0f );
g_pd3dDevice->SetTexture( 0, g_pTexFloor );
g_pEffect->CommitChanges();
g_pWorldMesh->DrawSubset( 1 );

// Render ceiling
g_pEffect->SetFloat( "g_fPhongExponent", 5.0f );
g_pEffect->SetFloat( "g_fPhongCoefficient", 0.3f );
g_pEffect->SetFloat( "g_fDiffuseCoefficient", 0.3f );
g_pd3dDevice->SetTexture( 0, g_pTexCeiling );
g_pEffect->CommitChanges();
g_pWorldMesh->DrawSubset( 2 );

// Render paintings
g_pEffect->SetFloat( "g_fPhongExponent", 5.0f );
g_pEffect->SetFloat( "g_fPhongCoefficient", 0.3f );
g_pEffect->SetFloat( "g_fDiffuseCoefficient", 1.0f );
g_pd3dDevice->SetTexture( 0, g_pTexPainting );
g_pEffect->CommitChanges();
g_pWorldMesh->DrawSubset( 3 );

// Draw the light spheres.
g_pEffect->SetFloat( "g_fPhongExponent", 5.0f );
g_pEffect->SetFloat( "g_fPhongCoefficient", 1.0f );
g_pEffect->SetFloat( "g_fDiffuseCoefficient", 1.0f );
g_pEffect->SetBool( "g_bEnableTexture", false );

for( int iLight = 0; iLight < NUM_LIGHTS; iLight++ )
{
// Just position the point light -- no need to orient it
D3DXMATRIXA16 mScale;
D3DXMatrixScaling( &mScale, 0.05f, 0.05f, 0.05f );

mView = *g_Camera.GetViewMatrix();
D3DXMatrixTranslation( &mWorld, g_avLightPosition[iLight].x, g_avLightPosition[iLight].y,
g_avLightPosition[iLight].z );
mWorld = mScale * mWorld;
mObjectToView = mWorld * mView;
g_pEffect->SetMatrix( "g_mObjectToView", &mObjectToView );

// A light which illuminates objects at 80 lum/sr should be drawn
// at 3183 lumens/meter^2/steradian, which equates to a multiplier
// of 39.78 per lumen.
D3DXVECTOR4 vEmissive = EMISSIVE_COEFFICIENT * g_avLightIntensity[iLight];
g_pEffect->SetVector( "g_vEmissive", &vEmissive );

g_pEffect->CommitChanges();
g_pmeshSphere->DrawSubset( 0 );
}
g_pEffect->EndPass();
}

g_pEffect->End();

return S_OK;
}


And here's what I've done to get my black screen:



//--------------------------------------------------------------------------------------
// Name: Render
// Desc: Render frame
//--------------------------------------------------------------------------------------
HRESULT Render()
{
HRESULT hr;


PDIRECT3DSURFACE9 pSurfLDR; // Low dynamic range surface for final output
PDIRECT3DSURFACE9 pSurfDS; // Low dynamic range depth stencil surface
PDIRECT3DSURFACE9 pSurfHDR; // High dynamic range surface to store
// intermediate floating point color values

// Store the old render target
hr = g_pd3dDevice->GetRenderTarget(0, &pSurfLDR);
if(FAILED(hr)) return hr;
hr = g_pd3dDevice->GetDepthStencilSurface(&pSurfDS);
if(FAILED(hr)) return hr;

// Setup HDR render target
g_pTexScene->GetSurfaceLevel(0, &pSurfHDR);
if(g_bUseMultiSampleFloat16)
{
hr = g_pd3dDevice->SetRenderTarget(0, g_pFloatMSRT);
if(FAILED(hr)) return hr;
hr = g_pd3dDevice->SetDepthStencilSurface(g_pFloatMSDS);
if(FAILED(hr)) return hr;
}
else
{
hr = g_pd3dDevice->SetRenderTarget(0, pSurfHDR);
if(FAILED(hr)) return hr;
}

// Clear the viewport
hr = g_pd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0, 0, 0, 0), 1.0f, 0L);
if(FAILED(hr)) return hr;

// Render the scene
if(SUCCEEDED(g_pd3dDevice->BeginScene()))
{
// Render the HDR Scene
{
if(FAILED(RenderScene()))
return hr;

if(g_bScreenHasBeenTaken != TRUE)
{
if(FAILED(ScreenGrabSurface(pSurfHDR)))
MessageBox(NULL, "ScreenGrabSurface failed", NULL, MB_OK | MB_ICONERROR);

else g_bScreenHasBeenTaken = TRUE;
}
}

// If using floating point multi sampling, stretchrect to the rendertarget
if( g_bUseMultiSampleFloat16 )
{
hr = g_pd3dDevice->StretchRect(g_pFloatMSRT, NULL, pSurfHDR, NULL, D3DTEXF_NONE);
if(FAILED(hr)) return hr;
hr = g_pd3dDevice->SetRenderTarget(0, pSurfHDR);
if(FAILED(hr)) return hr;
hr = g_pd3dDevice->SetDepthStencilSurface(pSurfDS);
if(FAILED(hr)) return hr;
}

g_pd3dDevice->EndScene();
}

// Release surfaces
SAFE_RELEASE(pSurfHDR);
SAFE_RELEASE(pSurfLDR);
SAFE_RELEASE(pSurfDS);

return hr;
}



//-----------------------------------------------------------------------------
// Name: RenderScene()
// Desc: Render the world objects and lights
//-----------------------------------------------------------------------------
HRESULT RenderScene()
{
HRESULT hr = S_OK;

UINT uiPassCount, uiPass;
D3DXMATRIXA16 mObjectToView;

g_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
g_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);

g_pEffect->SetTechnique("RenderScene");
g_pEffect->SetMatrix("g_mObjectToView", &g_mView);

hr = g_pEffect->Begin(&uiPassCount, 0);
if(FAILED(hr))
return hr;

for(uiPass = 0; uiPass < uiPassCount; uiPass++)
{
g_pEffect->BeginPass(uiPass);

// Turn off emissive lighting
D3DXVECTOR4 vNull(0.0f, 0.0f, 0.0f, 0.0f);
g_pEffect->SetVector("g_vEmissive", &vNull);

// Enable texture
g_pEffect->SetBool("g_bEnableTexture", true);
g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);


// Render walls and columns
g_pEffect->SetFloat("g_fPhongExponent", 5.0f);
g_pEffect->SetFloat("g_fPhongCoefficient", 1.0f);
g_pEffect->SetFloat("g_fDiffuseCoefficient", 0.5f);
g_pd3dDevice->SetTexture(0, g_pTexWall);
g_pEffect->CommitChanges();
g_pWorldMesh->DrawSubset(0);

// Render floor
g_pEffect->SetFloat("g_fPhongExponent", 50.0f);
g_pEffect->SetFloat("g_fPhongCoefficient", 3.0f);
g_pEffect->SetFloat("g_fDiffuseCoefficient", 1.0f);
g_pd3dDevice->SetTexture(0, g_pTexFloor);
g_pEffect->CommitChanges();
g_pWorldMesh->DrawSubset(1);

// Render ceiling
g_pEffect->SetFloat("g_fPhongExponent", 5.0f);
g_pEffect->SetFloat("g_fPhongCoefficient", 0.3f);
g_pEffect->SetFloat("g_fDiffuseCoefficient", 0.3f);
g_pd3dDevice->SetTexture(0, g_pTexCeiling);
g_pEffect->CommitChanges();
g_pWorldMesh->DrawSubset(2);

// Render paintings
g_pEffect->SetFloat("g_fPhongExponent", 5.0f);
g_pEffect->SetFloat("g_fPhongCoefficient", 0.3f);
g_pEffect->SetFloat("g_fDiffuseCoefficient", 1.0f);
g_pd3dDevice->SetTexture(0, g_pTexPainting);
g_pEffect->CommitChanges();
g_pWorldMesh->DrawSubset(3);

// Draw the light spheres.
g_pEffect->SetFloat("g_fPhongExponent", 5.0f);
g_pEffect->SetFloat("g_fPhongCoefficient", 1.0f);
g_pEffect->SetFloat("g_fDiffuseCoefficient", 1.0f);
g_pEffect->SetBool("g_bEnableTexture", false);

for(int iLight = 0; iLight < NUM_LIGHTS; iLight++)
{
// Just position the point light -- no need to orient it
D3DXMATRIXA16 mScale;
D3DXMatrixScaling( &mScale, 0.05f, 0.05f, 0.05f );

D3DXMatrixTranslation(&g_mWorld,
g_avLightPosition[iLight].x,
g_avLightPosition[iLight].y,
g_avLightPosition[iLight].z );

g_mWorld = mScale * g_mWorld;
mObjectToView = g_mWorld * g_mView;
g_pEffect->SetMatrix("g_mObjectToView", &mObjectToView);

// A light which illuminates objects at 80 lum/sr should be drawn
// at 3183 lumens/meter^2/steradian, which equates to a multiplier
// of 39.78 per lumen.
D3DXVECTOR4 vEmissive = EMISSIVE_COEFFICIENT * g_avLightIntensity[iLight];
g_pEffect->SetVector("g_vEmissive", &vEmissive);

g_pEffect->CommitChanges();
g_pmeshSphere->DrawSubset(0);
}
g_pEffect->EndPass();
}

g_pEffect->End();

return S_OK;
}


The odd thing is that I capture exactly the same surface which is declared as such in both source snippets:

g_pTexScene-&gt;GetSurfaceLevel( 0, &pSurfHDR )

Both of the above images are this exact same surface, although mine does not work, if anyone can help, I would be greatly appreciative.

Goz
02-27-2009, 01:54 PM
Have you tried running through PIX? PIX is WELL worth learning before you attempt to do things like this ... Being able to debug the DirectX pipeline is amazing.

Phlex
02-27-2009, 01:55 PM
I've heard of it, but haven't really learned anything about it.

Goz
02-27-2009, 02:07 PM
Where, exactly, do you call Render() from ... you haven't added that code?

If you place a breakpoint at the start of the Render() function does it ever get hit? If so .. do you step through each line of code?

My guess is that you aren't actually rendering anything. However it is hard to tell without seeing things like your window and D3D initialisation code.

Phlex
02-27-2009, 02:28 PM
I call Render here

while(uMsg.message != WM_QUIT)
{
if( PeekMessage(&uMsg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&uMsg);
DispatchMessage(&uMsg);
}
else
{
g_dCurTime = timeGetTime();
g_fElpasedTime = (float)((g_dCurTime - g_dLastTime) * 0.001);
g_dLastTime = g_dCurTime;

if(FAILED(Render()))
MessageBox(NULL, "Could not render", "Error", MB_OK | MB_ICONERROR);
}
}
and here's my initiazation code.


//--------------------------------------------------------------------------------------
// Name: Initialise
// Desc: Initialise the HDRLightingPipeling application
//--------------------------------------------------------------------------------------
HRESULT Initialise()
{
HRESULT hr;

g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);

D3DDISPLAYMODE DisplayMode;
hr = g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &DisplayMode);

if(FAILED(hr))
{
MessageBox(NULL, "Could not get Apdater Display Mode", "Error", MB_OK | MB_ICONERROR);
return hr;
}

D3DPRESENT_PARAMETERS PresentParameters;
ZeroMemory(&PresentParameters, sizeof(PresentParameters));

PresentParameters.BackBufferHeight = SCREEN_HEIGHT;
PresentParameters.BackBufferWidth = SCREEN_WIDTH;
PresentParameters.BackBufferCount = 1;
PresentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
PresentParameters.MultiSampleQuality = NULL;
PresentParameters.Windowed = TRUE;
PresentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
PresentParameters.BackBufferFormat = DisplayMode.Format;
PresentParameters.EnableAutoDepthStencil = TRUE;
PresentParameters.AutoDepthStencilFormat = D3DFMT_D16;
PresentParameters.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
PresentParameters.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

/********************************** DEVICE CAPS **********************************/
// Get the device caps and check return values
D3DCAPS9 Caps;
hr = g_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &Caps);

if(FAILED(hr))
{
MessageBox(NULL, "Could not get Device Caps", "Error", MB_OK | MB_ICONERROR);
return hr;
}

// Create Direct3D Device and check return value
hr = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, g_hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&PresentParameters,
&g_pd3dDevice);

if(FAILED(hr))
{
MessageBox(NULL, "Could not create D3DDevice", "Error", MB_OK | MB_ICONERROR);
return hr;
}

// Check if system supports alpha blending
hr = g_pD3D->CheckDeviceFormat(Caps.AdapterOrdinal,
Caps.DeviceType,
DisplayMode.Format,
D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
D3DRTYPE_TEXTURE,
PresentParameters.BackBufferFormat);
if(FAILED(hr))
{
MessageBox(NULL, "System doesn't suppot alpha blending", "Error", MB_OK | MB_ICONERROR);
return hr;
}

// check if system supports D3DFMT_A16B16G16R16F render targets
hr = g_pD3D->CheckDeviceFormat(Caps.AdapterOrdinal,
Caps.DeviceType,
DisplayMode.Format,
D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
D3DRTYPE_TEXTURE,
D3DFMT_A16B16G16R16F);

if(FAILED(hr))
{
MessageBox(NULL, "System doesn't suppot\n D3DFMT_A16B16G16R16F render targets", NULL, MB_OK | MB_ICONERROR);
return hr;
}

// check support for D3DFMT_R32F or D3DFMT_R16F render targets
hr = g_pD3D->CheckDeviceFormat(Caps.AdapterOrdinal,
Caps.DeviceType,
DisplayMode.Format,
D3DUSAGE_RENDERTARGET,
D3DRTYPE_TEXTURE,
D3DFMT_R32F);

if(FAILED(hr))
{
hr = g_pD3D->CheckDeviceFormat(Caps.AdapterOrdinal,
Caps.DeviceType,
DisplayMode.Format,
D3DUSAGE_RENDERTARGET,
D3DRTYPE_TEXTURE,
D3DFMT_R16F);

if(FAILED(hr))
{
MessageBox(NULL, "System does not support R32F OR R16F\nformat render targets", NULL, MB_OK | MB_ICONERROR);
return hr;
}
}

// Check if post-pixel processing is supported
hr = g_pD3D->CheckDeviceFormat(Caps.AdapterOrdinal,
Caps.DeviceType,
DisplayMode.Format,
D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
D3DRTYPE_SURFACE,
PresentParameters.BackBufferFormat);

if(FAILED(hr))
{
MessageBox(NULL, "Syste doesn't support\npost-pixel processing", NULL, MB_OK | MB_ICONERROR);
return hr;
}

// we have already ensured that one of D3DFMT_R16F or D3DFMT_R32F is available.
if(FAILED(g_pD3D->CheckDeviceFormat(Caps.AdapterOrdinal,
Caps.DeviceType,
DisplayMode.Format,
D3DUSAGE_RENDERTARGET,
D3DRTYPE_TEXTURE,
D3DFMT_R16F)))
g_LuminanceFormat = D3DFMT_R32F;
else
g_LuminanceFormat = D3DFMT_R16F;

// Determine whether we can support multisampling on a A16B16G16R16F render target
g_bUseMultiSampleFloat16 = false;
g_MaxMultiSampleType = D3DMULTISAMPLE_NONE;

// Determine whether we can support multisampling on a A16B16G16R16F render target
g_bUseMultiSampleFloat16 = false;
g_MaxMultiSampleType = D3DMULTISAMPLE_NONE;
for( D3DMULTISAMPLE_TYPE imst = D3DMULTISAMPLE_2_SAMPLES; imst <= D3DMULTISAMPLE_16_SAMPLES;
imst = (D3DMULTISAMPLE_TYPE)(imst + 1))
{
DWORD msQuality = 0;
if(SUCCEEDED(g_pD3D->CheckDeviceMultiSampleType(Caps.AdapterOrdinal,
Caps.DeviceType,
D3DFMT_A16B16G16R16F,
PresentParameters.Windowed ,
imst, &msQuality)))
{
g_bUseMultiSampleFloat16 = true;
g_MaxMultiSampleType = imst;
if(msQuality > 0)
g_dwMultiSampleQuality = msQuality - 1;
else
g_dwMultiSampleQuality = msQuality;
}
}

g_bSupportsD16 = false;
if(SUCCEEDED(g_pD3D->CheckDeviceFormat(Caps.AdapterOrdinal,
Caps.DeviceType,
DisplayMode.Format,
D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE,
D3DFMT_D16)))
{
if(SUCCEEDED(g_pD3D->CheckDepthStencilMatch(Caps.AdapterOrdinal,
Caps.DeviceType,
DisplayMode.Format,
D3DFMT_A16B16G16R16F,
D3DFMT_D16)))
{
g_bSupportsD16 = true;
}
}

g_bSupportsD32 = false;
if(SUCCEEDED(g_pD3D->CheckDeviceFormat(Caps.AdapterOrdinal,
Caps.DeviceType,
DisplayMode.Format,
D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE,
D3DFMT_D32)))
{
if(SUCCEEDED(g_pD3D->CheckDepthStencilMatch(Caps.AdapterOrdinal,
Caps.DeviceType,
DisplayMode.Format,
D3DFMT_A16B16G16R16F,
D3DFMT_D32)))
{
g_bSupportsD32 = true;
}
}

g_bSupportsD24X8 = false;
if(SUCCEEDED(g_pD3D->CheckDeviceFormat(Caps.AdapterOrdinal,
Caps.DeviceType,
DisplayMode.Format,
D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE, D3DFMT_D24X8 ) ) )
{
if(SUCCEEDED(g_pD3D->CheckDepthStencilMatch(Caps.AdapterOrdinal,
Caps.DeviceType,
DisplayMode.Format,
D3DFMT_A16B16G16R16F,
D3DFMT_D24X8)))
{
g_bSupportsD24X8 = true;
}
}

// Crop the scene texture so width and height are evenly divisible by 8.
// This cropped version of the scene will be used for post processing effects,
// and keeping everything evenly divisible allows precise control over
// sampling points within the shaders.
g_dwCropWidth = PresentParameters.BackBufferWidth - PresentParameters.BackBufferWidth % 8;
g_dwCropHeight = PresentParameters.BackBufferHeight - PresentParameters.BackBufferHeight % 8;

// Create the HDR scene texture
hr = g_pd3dDevice->CreateTexture(PresentParameters.BackBufferWidth,
PresentParameters.BackBufferHeight,
1, D3DUSAGE_RENDERTARGET,
D3DFMT_A16B16G16R16F,
D3DPOOL_DEFAULT,
&g_pTexScene, NULL );
if(FAILED(hr)) return hr;

// Scaled version of the HDR scene texture
hr = g_pd3dDevice->CreateTexture(g_dwCropWidth / 4, g_dwCropHeight / 4,
1, D3DUSAGE_RENDERTARGET,
D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT,
&g_pTexSceneScaled, NULL);
if(FAILED(hr)) return hr;

// Create the bright-pass filter texture.
// Texture has a black border of single texel thickness to fake border
// addressing using clamp addressing
hr = g_pd3dDevice->CreateTexture(g_dwCropWidth / 4 + 2, g_dwCropHeight / 4 + 2,
1, D3DUSAGE_RENDERTARGET,
D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
&g_pTexBrightPass, NULL);
if(FAILED(hr)) return hr;

// Create a texture to be used as the source for the star effect
// Texture has a black border of single texel thickness to fake border
// addressing using clamp addressing
hr = g_pd3dDevice->CreateTexture(g_dwCropWidth / 4 + 2, g_dwCropHeight / 4 + 2,
1, D3DUSAGE_RENDERTARGET,
D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
&g_pTexStarSource, NULL);
if(FAILED(hr)) return hr;

// Create a texture to be used as the source for the bloom effect
// Texture has a black border of single texel thickness to fake border
// addressing using clamp addressing
hr = g_pd3dDevice->CreateTexture(g_dwCropWidth / 8 + 2, g_dwCropHeight / 8 + 2,
1, D3DUSAGE_RENDERTARGET,
D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
&g_pTexBloomSource, NULL );
if(FAILED(hr)) return hr;


// Create a 2 textures to hold the luminance that the user is currently adapted
// to. This allows for a simple simulation of light adaptation.
hr = g_pd3dDevice->CreateTexture(1, 1, 1, D3DUSAGE_RENDERTARGET,
g_LuminanceFormat, D3DPOOL_DEFAULT,
&g_pTexAdaptedLuminanceCur, NULL);
if(FAILED(hr)) return hr;
hr = g_pd3dDevice->CreateTexture(1, 1, 1, D3DUSAGE_RENDERTARGET,
g_LuminanceFormat, D3DPOOL_DEFAULT,
&g_pTexAdaptedLuminanceLast, NULL);
if(FAILED(hr)) return hr;

// For each scale stage, create a texture to hold the intermediate results
// of the luminance calculation
for(int i = 0; i < NUM_TONEMAP_TEXTURES; i++)
{
int iSampleLen = 1 << (2 * i);

hr = g_pd3dDevice->CreateTexture(iSampleLen, iSampleLen, 1, D3DUSAGE_RENDERTARGET,
g_LuminanceFormat, D3DPOOL_DEFAULT,
&g_apTexToneMap[i], NULL);
if(FAILED(hr)) return hr;
}

// Create the temporary blooming effect textures
// Texture has a black border of single texel thickness to fake border
// addressing using clamp addressing
for(int i = 1; i < NUM_BLOOM_TEXTURES; i++)
{
hr = g_pd3dDevice->CreateTexture(g_dwCropWidth / 8 + 2, g_dwCropHeight / 8 + 2,
1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT, &g_apTexBloom[i], NULL );
if(FAILED(hr)) return hr;
}

// Create the final blooming effect texture
hr = g_pd3dDevice->CreateTexture( g_dwCropWidth / 8, g_dwCropHeight / 8,
1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT, &g_apTexBloom[0], NULL );
if(FAILED(hr)) return hr;


// Create the star effect textures
for(int i = 0; i < NUM_STAR_TEXTURES; i++)
{
hr = g_pd3dDevice->CreateTexture(g_dwCropWidth / 4, g_dwCropHeight / 4,
1, D3DUSAGE_RENDERTARGET,
D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT,
&g_apTexStar[i], NULL);

if(FAILED(hr)) return hr;
}

// Create a texture to paint the walls
hr = D3DXCreateTextureFromFile(g_pd3dDevice, "Media/Textures/env2.bmp", &g_pTexWall);
if(FAILED(hr)) return hr;

// Create a texture to paint the floor
hr = D3DXCreateTextureFromFile(g_pd3dDevice, "Media/Textures/ground2.bmp", &g_pTexFloor);
if(FAILED(hr)) return hr;

// Create a texture to paint the ceiling
hr = D3DXCreateTextureFromFile( g_pd3dDevice, "Media/Textures/seafloor.bmp", &g_pTexCeiling );
if(FAILED(hr)) return hr;

// Create a texture for the paintings
hr = D3DXCreateTextureFromFile( g_pd3dDevice, "Media/Textures/env3.bmp", &g_pTexPainting );
if(FAILED(hr)) return hr;

// Textures with borders must be cleared since scissor rect testing will
// be used to avoid rendering on top of the border
ClearTexture(g_pTexAdaptedLuminanceCur);
ClearTexture(g_pTexAdaptedLuminanceLast);
ClearTexture(g_pTexBloomSource);
ClearTexture(g_pTexBrightPass);
ClearTexture(g_pTexStarSource);

for(int i = 0; i < NUM_BLOOM_TEXTURES; i++)
{
ClearTexture(g_apTexBloom[i]);
}

// Build the world object
hr = BuildWorldMesh();
if(FAILED(hr)) return hr;

// Create sphere mesh to represent the light
hr = LoadMesh(g_pd3dDevice, "Media/Models/sphere0.x", &g_pmeshSphere);
if(FAILED(hr)) return hr;

// Load effects
LPD3DXBUFFER pBuffer;

// Load blinn phong shader
if(FAILED(D3DXCreateEffectFromFile(g_pd3dDevice, "Media/Effects/HDRLightingPipeline.fx",
NULL, NULL, 0, NULL, &g_pEffect, &pBuffer)))
{
// if effect could not compile, output shader debug info
LPVOID pCompileErrors = pBuffer->GetBufferPointer();
MessageBox(NULL, (const char*)pCompileErrors, "Compile Error", MB_OK | MB_ICONEXCLAMATION);
PostQuitMessage(0);
}

// Create world a screen vertex declarations
hr = g_pd3dDevice->CreateVertexDeclaration(g_aWorldVertex,&g_pWorldVertex);
if(FAILED(hr)) return hr;

hr = g_pd3dDevice->CreateVertexDeclaration(g_aScreenVertex,&g_pScreenVertex);
if(FAILED(hr)) return hr;

// Set perspective matrix and clear g_mWorld to '1'
D3DXMatrixPerspectiveFovLH(&g_mProj, D3DXToRadian(45.0f), SCREEN_WIDTH / SCREEN_HEIGHT, 0.1f, 500.0f);
D3DXMatrixIdentity(&g_mWorld);

// Set effect file variables
g_pEffect->SetMatrix("g_mProjection", &g_mProj);
g_pEffect->SetFloat("g_fBloomScale", 1.0f);
g_pEffect->SetFloat("g_fStarScale", 0.5f);

// Set light positions in world space
g_avLightPosition[0] = D3DXVECTOR4(4.0f, 2.0f, 18.0f, 1.0f);
g_avLightPosition[1] = D3DXVECTOR4(11.0f, 2.0f, 18.0f, 1.0f);

return S_OK;
}

Goz
02-27-2009, 02:31 PM
And if you place a break point and step through the code?

Edit: Where do you render your render texture to the D3D back buffer? I can't see that ... maybe im just being blind ... have been on the vodka and oranges for a couple of hours ... friday night and all that.

Phlex
02-27-2009, 02:37 PM
I inserted several break points through out render and render scene, and they were all executed (a yellow arrow came up where it was, which I assume means it was reached).

I don't render to the back buffer, this is correct, I am only rendering to pSurfHDR currently, this is because there are several more steps involved before I will actually render to the back buffer, so I just catch pSurfHDR whenever I press space bar, you aren't going blind, still room for a few more drinks I think :p

Goz
02-28-2009, 07:21 AM
Can you post up your screen grab code?

Phlex
02-28-2009, 11:47 AM
The screen grab code is not the problem, I knwo it isn't because I use it in the HDRLighting sample and various other programs, but if you still want it, here it is;



// Grab a single selleted surface
HRESULT ScreenGrabSurface(LPDIRECT3DSURFACE9 pSurface)
{
HRESULT hr;
sprintf_s(g_cBuffer, 17, "Screenshot%d.bmp", g_iScreenShot++);
hr = D3DXSaveSurfaceToFile(g_cBuffer, D3DXIFF_BMP, pSurface, NULL, NULL);

return hr;
}


Look in HRESULT Render() for how it's called.

Goz
02-28-2009, 03:02 PM
what happens if you place the screen grab IMMEDIATELY after the present?

Phlex
02-28-2009, 03:28 PM
..... sigh

There is no present, IM NOT LOOKING FOR THE BACK BUFFER, so long as screen grab is called between SAFE_RELEASE(pSurfHDR) and RenderScene I will get exactly the same image, I'm not even going to bother to test that :p

Reedbeta
02-28-2009, 06:50 PM
I'm not convinced of this. If you never call Present(), I'm uncertain the command buffer (that contains all your draw calls and state changes) is ever actually sent to the GPU and started. If it is, I'm uncertain that D3DXSaveSurfaceToFile actually waits for the GPU to finish rendering before grabbing the surface. It doesn't say anything one way or the other in the docs. It could be that it's smart enough to do this automatically - but unless you know for a fact (because you've done it before) that this all works without any Present() call, I'd advise hooking up a standard graphics loop to be sure everything actually runs.

Phlex
02-28-2009, 07:06 PM
I know for a fact it makes no difference, I have already tried it and it made no difference.

Goz
03-01-2009, 11:04 AM
I know for a fact it makes no difference, I have already tried it and it made no difference.

LOL! Do you work for nVidida or ATI? Thats a VERY sweeping statement. Seriously. At the very least post up the screen grab code. From experience if the calls are correct then the render is ccorrect. The render is NOT correct which, instantly, implies you are doing something wrong. I STRONGLY recommend you play with PIX with a few of the D3D example and learn how it works before you come on here and tell people that they are wrong.

As an anecdote. The first time i was exposed to pix was when working on an X-Box (ie not an x-box 360) game. I had to work out the tool as i went along but found it to be the most amazingly powerful piece of tech i've come across for games development (Was much better than the PS2's Performance Analyser at debugging graphics issues, for one). It was amazing how many problems i fixed after spending 10 minutes looking through a PIX grab on the X-Box.

Recently PIX grabs have become as advanced (or even mroe so) on the PC and you are wasting YOUR time if you won't spend some time learning how it works. One of the best things i ever learnt doing any sort of computer programming was that debugging is by FAR the most important skill you will ever learn.

Please listen to those who have "been there and done that" rather than just outright dismissing them because you know you are right. You will never learn (or earn) anything with that attitude.

Goz
03-01-2009, 11:07 AM
In fact to further Reedbeta's comment i seem to recall that the driver runtimes will not bother to present anything unless it reaches the ACTUAL back buffer. Unless you do the render to back buffer it is quite probable that the driver will say "hes done nothing" and not bother to render. It wil just keep queueing the commands into the command buffer. It will take you 30 minutes (At most) to implement a very simple exposure filter and render your results to the back buffer ... do it and see what happens.

Phlex
03-01-2009, 08:40 PM
If you read what I said, I said that I know for a fact it doesn't work because I have already tried it.

I've rendered to the back buffer and released the surface, but still getting a black screen and now a memory leak.