LPDIRECT3DTEXTURE9 m_pShadowMapTexQuadNode; // shadow map objects
LPDIRECT3DSURFACE9 m_pShadowMapSurf;
LPDIRECT3DSURFACE9 m_pShadowMapZ;
HRESULT hr;
V_RETURN(pd3dDevice->CreateTexture(
QUADTREE_SM_SIZE,
QUADTREE_SM_SIZE,
1,
D3DUSAGE_RENDERTARGET,
SHADOW_MAP_FORMAT,
D3DPOOL_DEFAULT,
&m_pShadowMapTexQuadNode,
NULL
));
V_RETURN(m_pShadowMapTexQuadNode->GetSurfaceLevel(0, &m_pShadowMapSurf));
V_RETURN(pd3dDevice->CreateDepthStencilSurface(
QUADTREE_SM_SIZE,
QUADTREE_SM_SIZE,
D3DFMT_D24S8,
D3DMULTISAMPLE_NONE,
0,
TRUE,
&m_pShadowMapZ,
NULL
));
void CALLBACK NodeData::OnFrameRender_Shadowmap(IDirect3DDevice9* pd3dDevice,BOOL bSave)
{
HRESULT hr;
LPDIRECT3DSURFACE9 pOldBackBuffer, pOldZBuffer;
D3DXHANDLE hTechnique = g_pEffect->GetTechniqueByName("TShader");
g_pEffect->SetTechnique(hTechnique);
V(g_pEffect->Begin(NULL, 0));
// save old render target and set new render target with depth/stencil buffer
pd3dDevice->GetRenderTarget(0, &pOldBackBuffer);
pd3dDevice->GetDepthStencilSurface(&pOldZBuffer);
pd3dDevice->SetRenderTarget(0, m_pShadowMapSurf);
pd3dDevice->SetDepthStencilSurface(m_pShadowMapZ);
// clear render target
pd3dDevice->Clear(
0L,
NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
0xffffffff,
1.0f,
0L
);
V(g_pEffect->BeginPass(0));
// render depth values into shadow map
CreateShadowMap();
V(g_pEffect->EndPass());
CalculateShadowPixelNumber();
// restore old backbuffer/stencil/depth-buffer and viewport
pd3dDevice->SetRenderTarget(0, pOldBackBuffer);
pd3dDevice->SetDepthStencilSurface(pOldZBuffer);
pOldBackBuffer->Release();
pOldZBuffer->Release();
for (int i=0;i<4;i++)
{
if (children)
children->data.OnFrameRender_Shadowmap(pd3dDevice,bSave);
}
}
void NodeData::CalculateShadowPixelNumber()
{
#define WHITE D3DCOLOR_XRGB(255, 255, 255)
D3DLOCKED_RECT lrect;
D3DDISPLAYMODE display;
m_nShadowPixelNumber=0;
HRESULT hr=m_pShadowMapSurf->LockRect(&lrect,NULL,D3DLOCK_NO_DIRTY_UPDATE|D3DLOCK_READONLY );
//-2005530516
for (int y=0;y<QUADTREE_SM_SIZE;y++)
{
for (int x=0;x<QUADTREE_SM_SIZE;x++)
{
DWORD dwColor = ((DWORD*)lrect.pBits)[y*(lrect.Pitch/sizeof(DWORD))+x];//Y*Width+X
USHORT r=GetRValue(dwColor);
USHORT g=GetGValue(dwColor);
USHORT b=GetBValue(dwColor);
if (dwColor!=WHITE)
{
m_nShadowPixelNumber++;
}
//DXUTOutputDebugString(L"r=%d,g=%d,b=%d\n",r,g,b);
}
}
m_pShadowMapSurf->UnlockRect();
//DWORD* p=(DWORD*)(lrect.pBits);
//p[y*(lrect.Pitch/sizeof(DWORD))+x]=RGB(255,0,0);
}
How to get the color of one pixel of shadow map
How to get the color of one pixel of shadow map?
I try to lock the m_pShadowMapSurf by LockRect function, but it return error of -2005530516.
[Edited by - akira32 on January 9, 2008 12:39:09 AM]
1. Use the V_RETURN() or V() macro when calling LockRect. That will call DXUTTrace which in turn will call DXTrace, which will tell you the HRESULT error code that -2005530516 corresponds to. You should also use the debug runtime to get more error information.
2. Textures created with D3DUSAGE_RENDERTARGET must be assigned to D3DPOOL_DEFAULT, and textures in this pool are not lockable. You have to use IDirect3DDevice9::GetRenderTargetData to copy the data to a lockable surface.
3. Why are you checking the shadow-map pixel by pixel? It seems you're doing it for debugging purposes, in which case you should use PIX to look at the surface and debug individual pixels.
4. Please use the "source" tags when posting long sequences of code. It makes things easier for everyone. [smile]
2. Textures created with D3DUSAGE_RENDERTARGET must be assigned to D3DPOOL_DEFAULT, and textures in this pool are not lockable. You have to use IDirect3DDevice9::GetRenderTargetData to copy the data to a lockable surface.
3. Why are you checking the shadow-map pixel by pixel? It seems you're doing it for debugging purposes, in which case you should use PIX to look at the surface and debug individual pixels.
4. Please use the "source" tags when posting long sequences of code. It makes things easier for everyone. [smile]
Quote:Original post by MJP
3. Why are you checking the shadow-map pixel by pixel?
I want to implement the adaptive shadow maps. I must calculate the number of pixels in a shaodw map cell. I had used use GetRenderTargetData to copy the data to a lockable surface.(GetRenderTargetData return D3DERR_INVALIDCALL) But I have another problem how to get the color of pixel in surface(format is D3DFMT_R32F). I want to konw which pixel in shadow map has occluder.
void NodeData::CalculateShadowPixelNumber(){ #define WHITE D3DCOLOR_XRGB(255, 255, 255) IDirect3DSurface9* m_TmpSurface; g_pd3dDevice->CreateOffscreenPlainSurface(QUADTREE_SM_SIZE,QUADTREE_SM_SIZE,D3DFMT_R32F,D3DPOOL_DEFAULT,&m_TmpSurface,NULL); V(g_pd3dDevice->GetRenderTargetData(m_pShadowMapSurf,m_TmpSurface));//<===== D3DERR_INVALIDCALL D3DLOCKED_RECT lrect; m_nShadowPixelNumber=0; HRESULT hr; V(m_TmpSurface->LockRect(&lrect,NULL,D3DLOCK_NO_DIRTY_UPDATE|D3DLOCK_READONLY )); for (int y=0;y<QUADTREE_SM_SIZE;y++) { for (int x=0;x<QUADTREE_SM_SIZE;x++) { DWORD dwColor = ((DWORD*)lrect.pBits)[y*(lrect.Pitch/sizeof(DWORD))+x];//Y*Width+X USHORT r=GetRValue(dwColor); USHORT g=GetGValue(dwColor); USHORT b=GetBValue(dwColor); if (b!=255) { m_nShadowPixelNumber++; } DXUTOutputDebugString(L"r=%d,g=%d,b=%d\n",r,g,b); } } m_TmpSurface->UnlockRect(); SAFE_RELEASE(m_TmpSurface);}
[Edited by - akira32 on January 9, 2008 3:52:53 AM]
I had solveed the probelms of the CreateOffscreenPlainSurface and GetRenderTargetData.(Becuase the Pool of CreateOffscreenPlainSurface must be 3DPOOL_SYSTEMMEM).
But Now I have another problem how to get the color value of the pixel in the surface(m_TmpSurface) with the format "D3DFMT_R32F".
I must do this step for implementing the adaptive shaodw maps. Even though I know the using of D3DXSaveTextureToFile.
Becuase I wish I can never output a picture when I run my program and texture always in the memory.
So, I problem is that how to get the color of the pixel in surface with the format "D3DFMT_R32F".
There are the related code as below:
The CImage class is used to save the color of the pixel in shadow map for the comparison with the result of the function of "D3DXSaveTextureToFile".
But Now I have another problem how to get the color value of the pixel in the surface(m_TmpSurface) with the format "D3DFMT_R32F".
I must do this step for implementing the adaptive shaodw maps. Even though I know the using of D3DXSaveTextureToFile.
Becuase I wish I can never output a picture when I run my program and texture always in the memory.
So, I problem is that how to get the color of the pixel in surface with the format "D3DFMT_R32F".
There are the related code as below:
#define SHADOW_MAP_FORMAT D3DFMT_R32Fvoid NodeData::CalculateShadowPixelNumber(){ #define WHITE D3DCOLOR_XRGB(255, 255, 255) IDirect3DSurface9* m_TmpSurface; HRESULT hr; V(g_pd3dDevice->CreateOffscreenPlainSurface(QUADTREE_SM_SIZE,QUADTREE_SM_SIZE,SHADOW_MAP_FORMAT,D3DPOOL_SYSTEMMEM,&m_TmpSurface,NULL)); //Must be D3DPOOL_SYSTEMMEM for MSDN V(g_pd3dDevice->GetRenderTargetData(m_pShadowMapSurf,m_TmpSurface)); D3DLOCKED_RECT lrect; m_nShadowPixelNumber=0; m_nWhitePixelNumber=0; CImage MixImage; int nBPP=32;//http://zh.wikipedia.org/wiki/%E5%83%8F%E7%B4%A0 DWORD Flag_Alpha=1;//有aplha MixImage.Create(QUADTREE_SM_SIZE,QUADTREE_SM_SIZE,nBPP,Flag_Alpha); V(m_TmpSurface->LockRect(&lrect,NULL,D3DLOCK_NO_DIRTY_UPDATE|D3DLOCK_READONLY )); //-2005530516 D3DERR_INVALIDCALL /* D3DCOLOR t=D3DCOLOR_ARGB(255,1,2,3); USHORT r=GetRValue(t); USHORT g=GetGValue(t); USHORT b=GetBValue(t); */ for (int y=0;y<QUADTREE_SM_SIZE;y++) { for (int x=0;x<QUADTREE_SM_SIZE;x++) { DWORD dwColor = ((DWORD*)lrect.pBits)[y*(lrect.Pitch/sizeof(DWORD))+x];//Y*Width+X USHORT r=GetRValue(dwColor); USHORT g=GetGValue(dwColor); USHORT b=GetBValue(dwColor); if (r!=255) { m_nShadowPixelNumber++; } else { m_nWhitePixelNumber++; } BYTE* byte_mix=(BYTE*)MixImage.GetPixelAddress(x,y); int a=dwColor>>22; *(byte_mix+0)=255;//127 blue *(byte_mix+1)=255;//126 green *(byte_mix+2)=a;//125 red *(byte_mix+3)=255;//255 alpha //DXUTOutputDebugString(L"r=%d,g=%d,b=%d\n",r,g,b); } } m_TmpSurface->UnlockRect(); SAFE_RELEASE(m_TmpSurface); WCHAR wtmp[MAX_PATH]; StringCchPrintf(wtmp , MAX_PATH , TEXT("NormalSM_%d_%d.bmp") , m_nLevel,m_nCellPosition); hr=MixImage.Save(wtmp,Gdiplus::ImageFormatBMP);}
The CImage class is used to save the color of the pixel in shadow map for the comparison with the result of the function of "D3DXSaveTextureToFile".
void CALLBACK NodeData::OnFrameRender_Shadowmap(IDirect3DDevice9* pd3dDevice,BOOL bSave){ HRESULT hr; LPDIRECT3DSURFACE9 pOldBackBuffer, pOldZBuffer; D3DXHANDLE hTechnique = g_pEffect->GetTechniqueByName("TShader"); g_pEffect->SetTechnique(hTechnique); V(g_pEffect->Begin(NULL, 0)); // save old render target and set new render target with depth/stencil buffer pd3dDevice->GetRenderTarget(0, &pOldBackBuffer); pd3dDevice->GetDepthStencilSurface(&pOldZBuffer); pd3dDevice->SetRenderTarget(0, m_pShadowMapSurf); pd3dDevice->SetDepthStencilSurface(m_pShadowMapZ); // clear render target pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0L ); V(g_pEffect->BeginPass(0)); // render depth values into shadow map CreateShadowMap(); V(g_pEffect->EndPass()); // restore old backbuffer/stencil/depth-buffer and viewport pd3dDevice->SetRenderTarget(0, pOldBackBuffer); pd3dDevice->SetDepthStencilSurface(pOldZBuffer); pOldBackBuffer->Release(); pOldZBuffer->Release(); if (bSave) { WCHAR wtmp_filename[MAX_PATH]; WCHAR wtmp_total[MAX_PATH]; WCHAR wtmp[MAX_PATH]; QuadNode* current_node=m_parent_node; StringCchPrintf(wtmp_total,MAX_PATH,L"%d_",m_nCellPosition); while (current_node!=NULL) { StringCchPrintf(wtmp , MAX_PATH , TEXT("%d_") , current_node->data.m_nCellPosition); wcscat(wtmp_total,wtmp); current_node=current_node->data.m_parent_node; } StringCchPrintf(wtmp_filename , MAX_PATH , TEXT("NormalSM_L%d_%s.png") , m_nLevel,wtmp_total); D3DXSaveTextureToFile(wtmp_filename,D3DXIFF_PNG ,m_pShadowMapTexQuadNode,NULL); DXUTOutputDebugString(L"%s\n",wtmp_filename); CalculateShadowPixelNumber(); DXUTOutputDebugString(L"ShadowPixelNumber=%d,WhitePixelNumber=%d\n" ,m_nShadowPixelNumber, m_nWhitePixelNumber); } for (int i=0;i<4;i++) { if (children) children->data.OnFrameRender_Shadowmap(pd3dDevice,bSave); }}
You're treating the texture as if it were R8G8B8A8 format, but its not. Instead of a DWORD, it's a single FLOAT value. This value can be any valid 32-bit floating-point number, and interpreting it will depend on how your shadowmap-generating pixel shader outputs to the texture. In general the depth is usually normalized to the range 0.0-1.0f, in which case a value of 1.0f would correspond to "white". Keep in mind there is no RGB color in a R32F texture, since it only has one channel (the red channel).
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement